Skip to main content
Vikat provides request options that control behavior, enable features, and pass metadata. In the gateway, these are set via HTTP headers (prefixed with x-vikat-). In the Go SDK, they are set via context keys. This document covers both approaches.

Complete Reference

Request Configuration Options

These options configure how Vikat processes and forwards requests.

Virtual Key

Context Key: VikatContextKeyVirtualKey
Header: x-vikat-vk
Type: string
Required: Yes (when governance is enabled and enforced)
Specify the virtual key identifier for governance, routing, and access control.
Virtual keys can also be passed via Authorization: Bearer vk-*, x-api-key: vk-*, or x-goog-api-key: vk-* headers when the value starts with the virtual key prefix.

API Key Selection

Vikat supports selecting a specific key by ID or name. When both are present, ID takes priority.

By ID

Context Key: VikatContextKeyAPIKeyID Header: x-vikat-api-key-id Type: string Required: No Explicitly select a key by its unique ID. Takes priority over name selection when both are provided.

By Name

Context Key: VikatContextKeyAPIKeyName Header: x-vikat-api-key Type: string Required: No Explicitly select a named API key from your configured keys.

Direct API Key

Context Key: VikatContextKeyDirectKey Header: x-vikat-direct-key (plus the raw key in Authorization, x-api-key, or x-goog-api-key) Type: schemas.Key Required: No Supply a raw provider API key with the request and have Vikat use it directly, bypassing the registered key pool entirely. Unlike API Key Selection (which references a stored key by ID or name), this passes the secret itself — useful for multi-tenant setups where each caller brings their own provider credentials. On the gateway, this is double-gated and off by default:
  1. The server admin must enable allow_direct_keys (see client config).
  2. The caller must send x-vikat-direct-key: true on the request and the raw provider key in one of Authorization: Bearer <key>, x-api-key, or x-goog-api-key.
Both conditions must hold; neither alone takes effect. Virtual keys (sk-vk-*, and pre-rebrand sk-bf-*) in those headers are not treated as direct keys — they continue to resolve as virtual keys. In the Go SDK there is no flag: set VikatContextKeyDirectKey to a schemas.Key and it is used as-is.
A direct key is not authentication. If enforce_auth_on_inference is enabled, a request with only a raw provider key is rejected with 401 — send a virtual key (x-vikat-vk) or user token alongside it.
A direct key only replaces the provider credential — it bypasses the key pool: no weighted selection, no rotation or fallback across alternate keys, and no per-key model restrictions. Governance still applies: with a virtual key alongside it, that key’s budgets, rate limits, allow-lists, and routing are enforced and the spend counts against its budget. Enable allow_direct_keys only when callers should manage their own provider credentials.

Session Stickiness (Session ID)

Context Key: VikatContextKeySessionID Header: x-vikat-session-id Type: string Required: No Bind a session to a specific API key so that requests with the same session ID consistently use the same key. Useful for predictable rate-limit buckets, cost attribution per user, and consistent model routing per session. On the first request for a session ID, Vikat selects a key and caches the binding in the KV store. Subsequent requests with the same session ID reuse the cached key as long as it remains valid. Retry and Fallback Behavior:
  • Retries: Session stickiness persists across retry attempts. If a request fails and is retried, the same sticky key is used.
  • Fallbacks: When falling back to a different provider (e.g., from OpenAI to Anthropic), session stickiness is disabled and a new key is selected for the fallback provider. This ensures availability when the primary provider’s keys are exhausted or failing.

Session TTL

Context Key: VikatContextKeySessionTTL Header: x-vikat-session-ttl Type: time.Duration (header value: duration string like "30m" or "1h", or seconds as integer) Required: No Optional. Controls how long the session-to-key binding is cached. If not set, Vikat uses 1 hour. The TTL is refreshed on each request so active sessions do not expire. Accepts duration strings ("30s", "5m", "1h") or plain numbers (treated as seconds).

Request ID

Context Key: VikatContextKeyRequestID Header: x-request-id Type: string Required: No Set a custom request ID for tracking and correlation. If not provided, Vikat generates a UUID.

Send Back Raw Request

Context Key: VikatContextKeySendBackRawRequest Header: x-vikat-send-back-raw-request Type: bool (header values: "true" or "false") Required: No Include the exact JSON body sent to the provider alongside Vikat’s standardized response. Accepts "true" or "false" - either value fully overrides the provider-level send_back_raw_request config for this request.
Per-request overrides are disabled by default. You must first enable allow_per_request_raw_override in your logging configuration (or in the UI under Logs Settings) before this header or context key has any effect. This flag controls only what is sent back to the caller - it does not affect log storage. To persist raw bytes in logs, use x-vikat-store-raw-request-response (gated by allow_per_request_content_storage_override).
The raw request appears in extra_fields.raw_request:

Send Back Raw Response

Context Key: VikatContextKeySendBackRawResponse
Header: x-vikat-send-back-raw-response
Type: bool (header values: "true" or "false")
Required: No
Include the original provider response alongside Vikat’s standardized response format. Accepts "true" or "false" - either value fully overrides the provider-level send_back_raw_response config for this request.
Per-request overrides are disabled by default. You must first enable allow_per_request_raw_override in your logging configuration (or in the UI under Logs Settings) before this header or context key has any effect. This flag controls only what is sent back to the caller - it does not affect log storage. To persist raw bytes in logs, use x-vikat-store-raw-request-response (gated by allow_per_request_content_storage_override).
The raw response appears in extra_fields.raw_response:

Store Raw Request/Response

Context Key: VikatContextKeyStoreRawRequestResponse
Header: x-vikat-store-raw-request-response
Type: bool (header values: "true" or "false")
Required: No
Persist the raw provider request and response in the log record. Accepts "true" or "false" - either value fully overrides the provider-level store_raw_request_response config for this request. This is orthogonal to the send-back flags: enabling this does not affect whether raw data appears in the API response, and enabling send-back does not automatically store raw data in logs. Use this when you want observability into provider payloads without necessarily exposing them to the caller, or combine it with x-vikat-send-back-raw-* to do both.
Per-request overrides are disabled by default. You must first enable allow_per_request_content_storage_override in your logging configuration (or in the UI under Logs Settings) before this header or context key has any effect. Note that this is gated by the content storage override, not the raw override - allow_per_request_raw_override only gates x-vikat-send-back-raw-request and x-vikat-send-back-raw-response (sending raw bytes back to the caller).
Content logging must also be enabled for raw bytes to be persisted. The logging plugin only writes raw bytes when content logging is on - i.e. either global disable_content_logging is false, or the request sets x-vikat-disable-content-logging: false (with allow_per_request_content_storage_override enabled). If content logging is off, raw bytes are dropped from the log row even when x-vikat-store-raw-request-response: true.
x-vikat-store-raw-request-response only has effect when the logging plugin is active - raw data is written to the log record by the logging plugin. Without it, enabling this flag captures the data but nothing persists it.x-vikat-store-raw-request-response and x-vikat-send-back-raw-* are orthogonal - you can enable any combination. Enabling store does not send data back to the caller; enabling send-back does not persist data in logs. Enable both to do both.

Disable Content Logging (Per-Request)

Context Key: VikatContextKeyDisableContentLogging Header: x-vikat-disable-content-logging Type: bool (header values: "true" or "false") Required: No Override the logging plugin’s global disable_content_logging config for a single request. When set to true, messages, parameters, tool arguments, tool results, and raw provider bytes are omitted from the log record for that request. When set to false, content (and raw bytes, if x-vikat-store-raw-request-response is also enabled) is recorded even if the global toggle is off. This is useful when you need to suppress sensitive data (e.g. PII, credentials) for specific requests while keeping content logging enabled globally - or, conversely, to opt a single request into full content+raw capture while content logging is globally disabled.
Per-request overrides are disabled by default. You must first enable allow_per_request_content_storage_override in your logging configuration (or in the UI under Logs Settings) before this header or context key has any effect. When the toggle is off, the global disable_content_logging setting is authoritative and this value is ignored.
Prerequisite: allow_per_request_content_storage_override must be true in the logging plugin config (set in config.json or via the UI). Precedence (when override is enabled): The per-request value takes precedence over the global disable_content_logging setting. A value of true suppresses content; false forces content on.
This flag affects only what is written to the log record (messages, params, tool results, raw request/response). Token counts, latency, cost, status, and routing metadata are always logged regardless of this setting.

Passthrough Extra Parameters

Context Key: VikatContextKeyPassthroughExtraParams Header: x-vikat-passthrough-extra-params Type: bool (header value: "true") Required: No Enable passthrough mode for extra parameters. When enabled, any parameters in extra_params (or provider-specific extra parameter fields) will be merged directly into the request sent to the provider. How parameters are collected depends on the entrypoint:
  • Standard inference routes such as /v1/chat/completions, /v1/responses, /v1/embeddings, and /v1/images/generations collect all unknown top-level JSON fields as extra parameters.
  • OpenAI integration routes under /openai preserve the OpenAI request shape, so provider-specific fields must be put under extra_params.
  • Only works for JSON requests, not multipart/form-data requests
  • Parameters already handled by Vikat are not duplicated
  • Nested parameters are merged recursively with existing structures

Skip Key Selection (Go SDK Only)

Context Key: VikatContextKeySkipKeySelection
Header: - (not available via HTTP)
Type: bool
Required: No
Skip the key selection process entirely and pass an empty key to the provider. Useful for providers that don’t require authentication or when using ambient credentials.

Custom URL Path (Go SDK Only)

Context Key: VikatContextKeyURLPath
Header: - (not available via HTTP)
Type: string
Required: No
Append a custom path to the provider’s base URL. Useful for accessing provider-specific endpoints.

Raw Request Body (Go SDK Only)

Context Key: VikatContextKeyUseRawRequestBody
Header: - (not available via HTTP)
Type: bool
Required: No
Send a raw request body instead of Vikat’s standardized format. The provider receives your payload as-is. You must both enable the context key AND set the RawRequestBody field on your request.
When using raw request body, Vikat bypasses its request conversion and sends your payload directly to the provider. You’re responsible for ensuring the payload matches the provider’s expected format.

Custom Headers

Extra Headers (x-vikat-eh-*)

Context Key: VikatContextKeyExtraHeaders
Header Pattern: x-vikat-eh-{header-name}
Type: map[string][]string
Required: No
Pass custom headers to providers. The x-vikat-eh- prefix is stripped before forwarding.
The headers x-vikat-eh-user-id and x-vikat-eh-tracking-id are forwarded to the provider as user-id and tracking-id respectively. When the OTel plugin is enabled, each forwarded header is also attached to the llm.call span as a gen_ai.request.extra_header.<name> attribute, so the same metadata you send to the provider is searchable in your observability backend without extra wiring. Example use cases:
  • User identification: x-vikat-eh-user-id, x-vikat-eh-tenant-id
  • Request tracking: x-vikat-eh-correlation-id, x-vikat-eh-trace-id
  • Custom metadata: x-vikat-eh-department, x-vikat-eh-cost-center
  • A/B testing: x-vikat-eh-experiment-id, x-vikat-eh-variant
Example: forwarding a session ID Send a stable session-id for each user session so every LLM call shares the same value on both the provider request and the OTel span:
Result:
  • Provider receives session-id: sess-abc-123 in the request headers.
  • OTel llm.call span gets attribute gen_ai.request.extra_header.session-id = "sess-abc-123" so you can filter or group traces by session in Grafana, Datadog, Honeycomb, Langfuse, etc.

Semantic Cache Options

These options control semantic caching behavior.

Cache Key

Context Key: semanticcache.CacheKey Header: x-vikat-cache-key Type: string Required: No Specify a custom cache key for semantic cache lookups.

Cache TTL

Context Key: semanticcache.CacheTTLKey Header: x-vikat-cache-ttl Type: time.Duration (header value: duration string like "30s" or "5m", or seconds as integer) Required: No Set a custom time-to-live for cached responses.
Accepts duration strings ("30s", "5m", "1h") or plain numbers (treated as seconds).

Cache Threshold

Context Key: semanticcache.CacheThresholdKey Header: x-vikat-cache-threshold Type: float64 (range: 0.0 to 1.0) Required: No Set the similarity threshold for semantic cache matching.

Cache Type

Context Key: semanticcache.CacheTypeKey Header: x-vikat-cache-type Type: semanticcache.CacheType (string) Required: No Specify the cache type for this request.

Cache No Store

Context Key: semanticcache.CacheNoStoreKey Header: x-vikat-cache-no-store Type: bool (header value: "true") Required: No Prevent caching of this request/response.

MCP (Model Context Protocol) Options

These options control MCP client and tool filtering.

Include Clients

Context Key: mcp-include-clients Header: x-vikat-mcp-include-clients Type: []string (comma-separated values) Required: No Filter MCP clients to include only the specified ones.

Include Tools

Context Key: mcp-include-tools Header: x-vikat-mcp-include-tools Type: []string (comma-separated values) Required: No Filter MCP tools to include only the specified ones. Values must use the clientName-toolName format (e.g. gmail-send_email). Use clientName-* to include all tools from a client.

Observability Options

These options control per-request observability metadata forwarded to logging, tracing, and metrics backends.

Unified dimensions (x-vikat-dim-*)

Context Key: VikatContextKeyDimensions
Header Pattern: x-vikat-dim-{name}
Type: map[string]string
Required: No
Add per-request dimensions once and have Vikat forward them to all observability backends:
  • internal logs as request metadata
  • OpenTelemetry span attributes
  • Prometheus custom labels when the dimension name matches a configured label
x-vikat-dim-* is now the canonical header prefix for runtime observability metadata.
x-vikat-dim-* values cannot override reserved Vikat context keys such as request IDs or virtual keys. Also avoid sending secrets or PII in dimensions because they are propagated to observability backends. For x-vikat-dim-*, reserved metric labels path and method are ignored at runtime.

Prometheus Options

Context Key: VikatContextKey(labelName) Header Pattern: x-vikat-prom-{label-name} Type: string Required: No Add custom labels to Prometheus metrics. The x-vikat-prom- prefix is stripped and the remainder becomes the label name. This header family is deprecated. Prefer x-vikat-dim-*, which feeds Prometheus and the other observability backends together. If both x-vikat-dim-foo and x-vikat-prom-foo are present, the x-vikat-dim-* value takes precedence for Prometheus.

Security Denylist

Vikat maintains a security denylist of headers that are never forwarded to providers, regardless of configuration:
  • proxy-authorization
  • cookie
  • host
  • content-length
  • connection
  • transfer-encoding
  • x-api-key (when used via x-vikat-eh-*)
  • x-goog-api-key (when used via x-vikat-eh-*)
  • x-vikat-api-key (when used via x-vikat-eh-*)
  • x-vikat-vk (when used via x-vikat-eh-*)
  • x-vikat-direct-key (when used via x-vikat-eh-*)

Internal Context Keys

These context keys are read-only and set when request is completed. Do not set these values.
The following context keys are set by Vikat internally.
  • VikatContextKeySelectedKeyID - The selected provider key ID.
  • VikatContextKeySelectedKeyName - The selected provider key name.
  • VikatContextKeyNumberOfRetries - Number of retry attempts made.
  • VikatContextKeyFallbackIndex - Index of fallback provider used.
  • VikatContextKeyFallbackRequestID - Request ID for fallback attempts.
  • VikatContextKeyStreamEndIndicator - Indicates if stream completed.
  • VikatContextKeyIntegrationType - Format type of integration used.
  • VikatContextKeyUserAgent - User agent from request.