← back to docs

ingest api

OTLP/HTTP endpoints, headers, payload expectations, sample curl.

endpoint

POST https://otlp.metric-ai.nativekloud.com/v1/{traces,metrics,logs}

Three sub-paths, one per OTLP signal type. The Worker validates the bearer token, hashes it (SHA-256), looks up org_id in KV, and pushes the raw payload onto a Cloudflare Queue. The queue consumer decodes and writes to D1 + WAE.

headers

HeaderValue
AuthorizationBearer <your-ingest-token>
Content-Typeapplication/json

payload

OTLP/JSON, exactly as defined by the OpenTelemetry spec. Claude Code emits this when you set OTEL_EXPORTER_OTLP_PROTOCOL=http/json.

We currently support OTLP/JSON only. OTLP/protobuf is acknowledged on the wire but not yet decoded — it’s the next item on the phase-3 roadmap. If you’re sending from Claude Code, the managed-settings template already pins the JSON protocol for you.

sample request

curl -X POST https://otlp.metric-ai.nativekloud.com/v1/traces \
  -H "Authorization: Bearer $METRIC_AI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceSpans": [{
      "resource": {
        "attributes": [
          {"key": "service.name", "value": {"stringValue": "claude-code"}},
          {"key": "session.id", "value": {"stringValue": "demo-session"}}
        ]
      },
      "scopeSpans": [{
        "scope": {"name": "claude_code"},
        "spans": [{
          "traceId": "5b8aa5a2d2c872e8321cf37308d69df2",
          "spanId": "051581bf3cb55c13",
          "name": "claude_code.interaction",
          "kind": 1,
          "startTimeUnixNano": "1709158800000000000",
          "endTimeUnixNano": "1709158801000000000"
        }]
      }]
    }]
  }'

responses

CodeMeaning
204 No Contentaccepted, queued for processing
401 Unauthorizedmissing or invalid bearer token
413 Payload Too Largerequest body over the per-request limit
429 Too Many Requestsper-token rate limit tripped

per-signal notes

  • Traces — we extract the thin span row (trace_id, span_id, parent_span_id, name, duration, plus key attributes: prompt.id, user, repo, model, tool, cost). The full attribute bag is dropped.
  • Metrics — pre-aggregated to 1-minute buckets keyed by (org, user, repo, model, tool, status). Histograms collapse to count + sum.
  • Logs — body is dropped. We extract event name, severity, and the structured attributes we care about (tool decisions, api errors, prompt id).