DVARA headers — request and response reference
DVARA is an AI governance platform, so every /v1/* request is already audited with a server-generated trace ID. The headers below let you authenticate, correlate the audit trail with your own request identifiers, and read the signals DVARA emits back on the response.
Request headers
Authorization: Bearer gw_…
Required on every data-plane request. Create the API key from API Keys in DVARA Flightdeck. Flightdeck applies the signed-in user's role and active workspace. The key starts with gw_, and the full secret is shown exactly once; only a SHA-256 hash is persisted. See Data plane authentication for rotation and revoke flows.
Every /v1 request must carry a valid key. A missing header returns
401 api_key_required; a key absent from the store returns
401 invalid_api_key. Revoked and expired keys return their corresponding
401 codes. The former require-api-key switch was removed in 1.8.0.
X-Trace-ID
Pass X-Trace-ID for distributed tracing correlation. DVARA resolves the trace ID in this order: (1) client-supplied X-Trace-ID / X-Trace-Id header, (2) the OTel trace ID from the current span when OpenTelemetry tracing is active, (3) a random UUID. The chosen value lands on the audit event, the SLF4J MDC, and is echoed back as the X-Trace-ID response header.
A supplied trace ID must contain at most 128 letters, digits, or ._:-. DVARA replaces an invalid value with a new trace ID rather than reflecting it into logs.
# Python (OpenAI SDK)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
extra_headers={"X-Trace-ID": "my-trace-123"},
)
// TypeScript (OpenAI SDK)
const response = await client.chat.completions.create(
{
model: "gpt-4o",
messages: [{ role: "user", content: "Hello" }],
},
{ headers: { "X-Trace-ID": "my-trace-123" } },
);
// Java (LangChain4j)
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("http://localhost:8080/v1")
.apiKey("your-dvara-api-key")
.modelName("gpt-4o")
.customHeaders(Map.of("X-Trace-ID", "my-trace-123"))
.build();
The same trace ID will appear on:
- The
GATEWAY_RESPONSEaudit event (one per request through the data plane), and any other event types fired downstream by policy, PII, guardrail, MCP, or admin paths —trace_idlives on the access log line surrounding the event, so a single grep on the trace ID reconnects every layer - The
X-Trace-IDresponse header DVARA sends back to you - The OTLP span emitted for the request (when tracing is enabled)
X-Session-Id
Pass X-Session-Id for agent session tracking. DVARA groups requests sharing a session ID into a single agentic session, which activates loop detection, approval gates, and session-level audit grouping.
A supplied session ID uses the same 128-character and [A-Za-z0-9._:-] contract. DVARA ignores an invalid session ID, so the request is not joined to that session.
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Continue our conversation"}],
extra_headers={"X-Session-Id": "agent-session-456"},
)
const response = await client.chat.completions.create(
{
model: "gpt-4o",
messages: [{ role: "user", content: "Continue" }],
},
{ headers: { "X-Session-Id": "agent-session-456" } },
);
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("http://localhost:8080/v1")
.apiKey("your-dvara-api-key")
.modelName("gpt-4o")
.customHeaders(Map.of("X-Session-Id", "agent-session-456"))
.build();
Sessions appear in the DVARA Flightdeck under Agents → Sessions, where you can see loop-detection status, kill a runaway session, or drill into every request the session produced.
Response headers
DVARA stamps response headers to signal in-band conditions that don't justify a non-2xx but a well-behaved client should react to. None of these break the OpenAI wire format; they layer on top.
| Header | Distribution | When emitted | What it means |
|---|---|---|---|
X-Trace-ID | Both | Always | The trace ID DVARA resolved for the request — echo it in your application logs to grep across the audit, tracing, and provider-log layers. |
X-Cache: HIT / MISS | Both for exact cache; Enterprise for semantic matching | Cache configured | Whether the response came from a cache rather than the provider. A HIT avoids the upstream call. Semantic similarity matching is Enterprise-only. |
X-Gateway-Strict-Downgraded: true | Both | response_format: json_schema with strict: true against Anthropic or AWS Bedrock | The provider cannot enforce strict JSON Schema; validate on the client if strictness is load-bearing. |
X-Gateway-Failover-Blocked: capability_mismatch | Both | 503 failover_capability_mismatch | The primary failed and no fallback supports the requested capability. |
X-Budget-Remaining-Pct, X-Budget-Remaining-Tokens | Enterprise | A workspace has a budget cap | Remaining percentage and estimated token buying power. |
X-Budget-Warning: true | Both | A policy returned WARN_AGENT | A policy warning, despite the historical header name; it is not a budget signal. |
X-Context-Window-Warning, X-Context-Window-Utilization | Both | Approaching the context window | Estimated input tokens crossed the configured warning threshold. |
X-Gateway-Pii-Unresolved | Enterprise | Response detokenization left placeholders | Count of unresolved request placeholders in the reply. |
Retry-After, X-RateLimit-Retry-After-Seconds | Both | A rate limiter returns 429 | Backoff time in the standard and seconds-only forms. |
X-RateLimit-Tokens-Limit, X-RateLimit-Tokens-Remaining, X-RateLimit-Reset | Both | Token-budget branch returns 429 | Active token limit, remainder, and reset time. |
From 1.8.2 DVARA no longer sends X-License-Warning. Licence expiry never changes a response, so it is reported in DVARA Flightdeck, in LICENSE_* audit events, and on GET /actuator/license instead. See Get and apply a license.
The HTTP error envelope ({"error": {"type": "...", "code": "...", "message": "...", ...}}) is documented separately in Error handling.
Why this matters for governance
Trace IDs and session IDs are the join key between:
- Your application's structured logs
- Your tracing backend (Jaeger, Tempo, Honeycomb)
- DVARA's tamper-evident audit trail
- The upstream provider's request logs (via propagation)
Without them, when a policy fires a denial at 3 a.m. you know what was blocked but not which customer request triggered it. With them, one grep on the trace ID reconnects every layer of the stack.
Next steps
- Back to language-agnostic integration overview.
- Looking for examples by language? See Python, JavaScript / TypeScript, or Java.
- Debugging a specific response code? See Troubleshooting.