Noveum.ai
Noveum Docs

Send Traces with the REST API

Ingest one trace or a batch directly from any language without installing noveum-trace.

Use REST ingestion when the application cannot use the Python package, including TypeScript services and custom telemetry pipelines. The REST API accepts the same trace and span structure used by the platform.

Use noveum-trace for supported Python applications. It manages context, parent relationships, batching, retries, and shutdown delivery for you.

Authentication

Send the organization API key as a bearer token:

export NOVEUM_API_KEY="your-api-key"

Send one trace

curl --request POST "https://api.noveum.ai/api/v1/traces/single" \
  --header "Authorization: Bearer $NOVEUM_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "trace_id": "5f9440c41d8a4e2c8a0cfd07c67df1d2",
    "name": "support-agent.request",
    "start_time": "2026-08-18T12:00:00.000Z",
    "end_time": "2026-08-18T12:00:00.850Z",
    "duration_ms": 850,
    "status": "ok",
    "span_count": 1,
    "error_count": 0,
    "project": "support-agent",
    "environment": "production",
    "service_version": "support-agent-v3",
    "sdk": {
      "name": "custom-typescript",
      "version": "1.0.0"
    },
    "metadata": {
      "user_id": "user-123",
      "session_id": "session-456",
      "request_id": "request-789"
    },
    "spans": [
      {
        "span_id": "c5c40b21540c4f78",
        "trace_id": "5f9440c41d8a4e2c8a0cfd07c67df1d2",
        "name": "llm.chat_completion",
        "start_time": "2026-08-18T12:00:00.050Z",
        "end_time": "2026-08-18T12:00:00.800Z",
        "duration_ms": 750,
        "status": "ok",
        "attributes": {
          "function.type": "llm_call",
          "llm.model": "gpt-4o-mini",
          "llm.provider": "openai",
          "llm.system_prompt": "Answer support questions from the supplied policy.",
          "llm.prompt": "Can I return this order?",
          "llm.completion": "Orders can be returned within 30 days.",
          "llm.usage.input_tokens": 82,
          "llm.usage.output_tokens": 11,
          "llm.usage.total_tokens": 93
        }
      }
    ]
  }'

Remove secrets and unnecessary personal data before ingestion, including from llm.system_prompt, llm.prompt, llm.completion, user_id, and session_id. When correlation is required, use approved pseudonymous identifiers instead of direct identifiers.

The API validates the complete payload before queueing it. A successful 200 response means the trace was accepted for asynchronous processing; it may take a short time to appear in Project Traces.

Required trace fields

FieldRequirement
nameStable name for the end-to-end request or execution.
start_time, end_timeISO 8601 timestamps or another accepted timestamp representation.
duration_msNon-negative end-to-end duration.
statusok, error, or timeout.
span_countNumber of spans in the spans array.
projectProject name used to group the trace.
environmentEnvironment name; defaults to production when omitted.
sdkProducer name and version, even for a custom integration.
spansOrdered operation records belonging to the trace.

trace_id is optional on the trace envelope but required on each span. Generate it in the application and use the same value everywhere so parent relationships and retries remain stable.

Required span fields

Each span requires:

  • span_id and the enclosing trace_id
  • optional parent_span_id for nested work
  • operation name
  • start_time, end_time, and non-negative duration_ms
  • status of ok, error, or timeout
  • the application payload in attributes

For LLM, retrieval, and tool operations, follow the evaluation capture contract. The API stores arbitrary JSON attributes, but consistent names make filtering and ETL mapping reliable.

Send a batch

Send up to 1,000 traces to the batch endpoint:

curl --request POST "https://api.noveum.ai/api/v1/traces" \
  --header "Authorization: Bearer $NOVEUM_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "traces": [
      {
        "trace_id": "5f9440c41d8a4e2c8a0cfd07c67df1d2",
        "name": "support-agent.request",
        "start_time": "2026-08-18T12:00:00.000Z",
        "end_time": "2026-08-18T12:00:00.850Z",
        "duration_ms": 850,
        "status": "ok",
        "span_count": 0,
        "error_count": 0,
        "project": "support-agent",
        "environment": "production",
        "service_version": "support-agent-v3",
        "sdk": {
          "name": "custom-typescript",
          "version": "1.0.0"
        },
        "spans": []
      }
    ]
  }'

Use bounded batches, retry rate-limited or server-error responses with backoff, and keep trace IDs stable across retries. Traces are immutable after ingestion. A successful response only acknowledges queueing; it does not report worker-side duplicates or storage failures. Verify delivery with GET /api/v1/traces/{trace_id} before treating the submission as complete.

Verify ingestion

  1. Retrieve the trace by ID or open the configured project and environment in Project Traces.
  2. Filter by service_version and the time window from the payload.
  3. Open the trace and verify span ordering, status, duration, and attributes.
  4. Send a controlled error trace and confirm its status and error details are searchable.
  5. Continue to ETL setup only after representative payloads are complete.