Docs/Budget Ai/Observability And Cost

Observability & Cost

Every request that reaches Budget AI with a known key is recorded as a trace in the key's project, including requests that were refused. Gateway traces go through the same ingestion path as SDK and OpenTelemetry traces, so they appear in Tracing, Sessions, Users, dashboards and cost reporting with no extra setup.

What a gateway trace contains

PartValue
Trace idThe gateway request id, returned to the caller in the x-ants-request-id response header
Trace nameThe model group the request resolved to. When the requested model matched no group, gateway.chat.completions.
Tagsgateway, plus any tags the caller sent
GenerationOne generation named chat.completions (also for embeddings), with model, parameters, input, output, token usage, cost, start time, time to first token and end time
LevelDEFAULT when served, WARNING for policy refusals and client disconnects, ERROR for provider and gateway failures
User and sessionFrom the caller context headers, see below

The generation's model is the model the provider reported, falling back to the deployment's provider model. Input is the request's messages (with tools when sent); output is the assistant message, rebuilt from the stream for streamed calls. Both are empty for refusals, errors and usage-only keys.

Recording happens after the response has been sent, on a separate thread in the gateway, so it never slows down or fails a request. One request produces one trace; a client retry is a second trace.

What is not traced

Requests with a missing or unknown key, a malformed or oversized body, or that arrive while the gateway cannot confirm its configuration, have no project to attribute them to and are counted only in gateway metrics. Refusals for blocked, expired or network-confined keys are traced at most once per minute per key and reason.

Finding gateway traffic

  • In Tracing, the Source filter offers Gateway and SDK & OTel.
  • The gateway tag works with the Tags filter.
  • Opening a gateway trace shows a Gateway panel with key, model group, deployment, provider model, provider, request id and cost, plus the list of attempts and the fallback kind when routing did more than one thing. A usage estimated badge marks traces whose token counts were estimated.
  • Custom dashboards can filter and break down by Source, Gateway key and Gateway model group.

Caller context headers

Callers can attribute a request to an end user, a session, tags and their own metadata by sending these optional headers on any request route, including embeddings:

HeaderFormatBecomes
langfuse-user-idStringThe trace's user, shown on the Users page
langfuse-session-idStringThe trace's session, shown on the Sessions page
langfuse-tagsComma-separated listAdded to the trace's tags after gateway
langfuse-metadataJSON object of string, number or boolean valuesMerged into the trace's metadata
traceparentW3C trace contextRecorded as gateway.traceparent metadata only

If langfuse-user-id is absent, the OpenAI user field from the request body is used as the user.

bash
curl https://<your-gateway-host>/v1/chat/completions \ -H "Authorization: Bearer $ANTS_GATEWAY_KEY" \ -H "langfuse-user-id: user-1234" \ -H "langfuse-session-id: support-chat-42" \ -H "langfuse-tags: support,tier-gold" \ -H 'langfuse-metadata: {"region":"eu","plan":"enterprise"}' \ -H "Content-Type: application/json" \ -d '{"model":"prod-chat","messages":[{"role":"user","content":"Hello"}]}'

With the OpenAI Python SDK, pass the headers with extra_headers:

python
response = client.chat.completions.create( model="prod-chat", messages=[{"role": "user", "content": "Hello"}], extra_headers={ "langfuse-user-id": "user-1234", "langfuse-session-id": "support-chat-42", }, )

Limits:

RuleLimitWhen exceeded
User id, session id, traceparent length256 charactersThat value is dropped
Tags16 tags of up to 64 charactersExtra or oversized tags are dropped
MetadataA JSON object; 32 keys; values up to 1024 charactersInvalid JSON drops the header; extra keys and long values are dropped
Reserved metadata keysAny key starting with gateway.Dropped, so callers cannot overwrite gateway fields
All caller headers together8 KBAll caller context is dropped

A bad header never fails the request. When anything is dropped, the trace carries gateway.caller_context_rejected naming the rules that tripped. traceparent does not attach the gateway trace to the caller's own trace; it is recorded for reference. Caller context is kept for usage-only keys, because it is attribution rather than model content.

Gateway metadata

Every gateway trace and generation carries these metadata keys (all values are strings):

KeyValue
gateway.sourcegateway
gateway.request_idThe request id
gateway.route/v1/chat/completions or /v1/embeddings
gateway.provideropenai-compatible, azure-openai, anthropic, bedrock or vertex-ai; none when refused before a deployment was chosen
gateway.streamtrue or false
gateway.key_id, gateway.key_aliasThe key
gateway.model_groupThe model group requested, or resolved when model was omitted
gateway.model_group_idWhen the group exists
gateway.deployment_id, gateway.provider_modelThe deployment that served, or last failed
gateway.provider_statusThe provider's HTTP status, when it answered
gateway.refusalThe refusal code, for refused requests
gateway.attemptsThe attempts list, identical to the x-ants-attempts header
gateway.fallback_kindgeneral, context or content, when a fallback group served
gateway.cachehit for a response cache hit
gateway.logging_modeusage_only for usage-only keys
gateway.usage_estimatedtrue when the provider reported no usage and tokens were estimated
gateway.traceparentThe caller's traceparent
gateway.caller_context_rejectedCaller context rules that dropped a value
gateway.source_addressThe caller's address, on ip_not_allowed refusals only
gateway.versionThe gateway build, when set

How cost is calculated

  • Cost is calculated from the provider's reported token usage and your project's model prices, with the same pricing engine as every other trace. The trace's cost and the key's spend use the same figure.
  • Non-streaming responses return the request's cost in the x-ants-cost header (USD) with x-ants-cost-estimated: false.
  • Streaming responses send headers before usage is known, so x-ants-cost carries the estimate made at admission and x-ants-cost-estimated: true. The trace and budgets use the real cost once the stream ends.
  • When a provider reports no usage, the gateway estimates it (about one token per four bytes) and marks the trace gateway.usage_estimated.
  • Embeddings are priced on input tokens.
  • Cache hits cost nothing.
  • Refusals carry zero usage and are never priced.
  • A stream that breaks part-way is still priced for what the provider produced.
ℹ

A provider model with no price produces traces with no cost, and cannot be used under a hard budget. Add prices for every provider model behind your model groups.

Budget AI analytics

The Budget AI pages read the same trace data, for the time range you select:

PageWhat it shows
OverviewSetup status; requests, spend, tokens, error rate, latency p50 with time to first token, refusals, fallbacks and cache hits; traffic and spend over time by model group; refusals by reason; current budgets; Busiest keys; Model health for every deployment; a table of model groups with traffic, latency and deployment health
KeysKey counts (active, blocked, expired, expiring soon, usage only), Traffic by key, Spend by key, and per key: requests, spend against budget, mode, last used and expiry
Models & RoutingTraffic by model and Spend by provider model across all groups
Model group detailsTraffic and latency per model, configured weight against actual share and attempts, keys with access, and errors and refusals grouped by message
Budgets & LimitsSpend over time, Budget pressure, budgets with enforced and recorded spend, threshold crossings, and the org unit hierarchy with projections
Organization Settings → Budget AIRequests, cost, error rate and spend against budget for every project, over the last 24 hours

Overview, key, model and budget figures can lag live traffic by the few seconds it takes traces to be processed. Enforcement does not: limits and budgets are checked against real-time counters.

For wider cost analysis across gateway and non-gateway traffic, use FinOps.

© 2026 ANTS Platform, Inc.Docs v1.0 · Last updated June 2026