Skip to main content
Version: 1.8.0

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_RESPONSE audit event (one per request through the data plane), and any other event types fired downstream by policy, PII, guardrail, MCP, or admin paths — trace_id lives on the access log line surrounding the event, so a single grep on the trace ID reconnects every layer
  • The X-Trace-ID response 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.

HeaderDistributionWhen emittedWhat it means
X-Trace-IDBothAlwaysThe 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 / MISSBoth for exact cache; Enterprise for semantic matchingCache configuredWhether 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: trueBothresponse_format: json_schema with strict: true against Anthropic or AWS BedrockThe provider cannot enforce strict JSON Schema; validate on the client if strictness is load-bearing.
X-Gateway-Failover-Blocked: capability_mismatchBoth503 failover_capability_mismatchThe primary failed and no fallback supports the requested capability.
X-Budget-Remaining-Pct, X-Budget-Remaining-TokensEnterpriseA workspace has a budget capRemaining percentage and estimated token buying power.
X-Budget-Warning: trueBothA policy returned WARN_AGENTA policy warning, despite the historical header name; it is not a budget signal.
X-Context-Window-Warning, X-Context-Window-UtilizationBothApproaching the context windowEstimated input tokens crossed the configured warning threshold.
X-Gateway-Pii-UnresolvedEnterpriseResponse detokenization left placeholdersCount of unresolved request placeholders in the reply.
Retry-After, X-RateLimit-Retry-After-SecondsBothA rate limiter returns 429Backoff time in the standard and seconds-only forms.
X-RateLimit-Tokens-Limit, X-RateLimit-Tokens-Remaining, X-RateLimit-ResetBothToken-budget branch returns 429Active 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:

  1. Your application's structured logs
  2. Your tracing backend (Jaeger, Tempo, Honeycomb)
  3. DVARA's tamper-evident audit trail
  4. 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​