Skip to main content
Every request flows through the gateway, so observability is automatic — no collector to run, no spans to export. Each LLM call becomes one rich record in your project’s data store.

What’s captured per call

Every call records ~150 fields. The ones you’ll use most:

Models & routing

Requested model, routed model, provider, tier, priority score, routing signals, fallback chain, and whether BYOK was used.

Tokens & cost

Input/output tokens, reasoning and cache tokens, cost, provider cost, baseline cost, and savings.

Latency

Total latency, provider latency, queue time, first-token latency, and inter-token p50/p95 for streamed responses.

Content & outcome

Input messages, output messages, tool definitions, finish reasons, refusal detection, and an output format signature.

The attribution ladder

Slice the same data at any grain:
Call → Session (run) → Workflow (project) → End-user → Organization
LevelKeyed byWhat it answers
Callstep_idOne provider invocation — every field above.
Sessionrun_idThe calls that belong to one agent execution.
Workflowworkflow_idA deployed project over all time.
End-userend_user_idOne of your customers, across sessions and workflows.
Organizationorg_idThe whole account — billing, totals, anomalies.

How attribution is stamped

  • Workflow — from the API key; every key belongs to exactly one workflow, so you pass nothing.
  • Runx-orbitrage-run-id if set, else a W3C traceparent, else a sticky 30-second per-key window groups bursts into one session automatically.
  • End-userx-orbitrage-end-user-id, set via the SDK (below).

Per-end-user attribution

Running a B2B app for many end-users? Tag calls with a user id so the dashboard can build per-user cost and flow graphs inside one workflow.
# At startup — one user for the whole process:
orbitrage.init(api_key, user_id=current_user.id)

# Or per request in a long-running server (the next client picks it up):
orbitrage.set_user(current_user.id)
This sets the x-orbitrage-end-user-id header on the next OpenAI client you construct and every subsequent call.
Don’t send x-orbitrage-user-id yourself. That header is the gateway’s authoritative account identity (derived from your API key), protected by a signature — sending your own value causes a 403. Use x-orbitrage-end-user-id for per-customer attribution.

Custom attribution headers

Beyond the SDK defaults, the gateway reads optional headers you can set to enrich analytics — pass them as request headers (or via your client’s default_headers).
HeaderPurpose
x-orbitrage-end-user-idYour customer’s user id (per-user graphs).
x-orbitrage-run-idGroup calls into one session/run.
x-orbitrage-workflow-idOverride the key’s workflow (advanced).
x-orbitrage-session-idA session identifier within a run.
x-orbitrage-customer-id / x-orbitrage-tenant-idMulti-tenant identifiers.
x-orbitrage-parent-request-idParent span, to build call graphs.
x-orbitrage-step-indexPosition of this call in a sequence.
See the API reference for the full list.

Where to see it

  • Telemetry / Traces — the live span stream and org-wide drilldown.
  • Routing — every router decision with the score and signals.
  • Workflows — a per-project flow graph that reconstructs each run.
  • Overview — org-wide cost, savings, and incident KPIs.
See the Dashboard tour for what each page shows.

Closing the loop with outcomes

Optionally report what your user did with a response (kept, regenerated, edited, abandoned, thumbs up/down) by calling the outcome endpoint with the call’s step id. These opt-in signals power the frustration and churn analytics in the Intelligence layer.