> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getbifrost.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Request Options

> Complete reference of all request options supported by Bifrost, including HTTP headers for the gateway and context keys for the Go SDK.

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

## Complete Reference

| Context Key                                | Header                                               | Type                  | Description                                                                                                                           |
| ------------------------------------------ | ---------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `BifrostContextKeyVirtualKey`              | `x-bf-vk`                                            | `string`              | Virtual key identifier for governance                                                                                                 |
| `BifrostContextKeyAPIKeyName`              | `x-bf-api-key`                                       | `string`              | Explicit API key name selection                                                                                                       |
| `BifrostContextKeyAPIKeyID`                | `x-bf-api-key-id`                                    | `string`              | Explicit API key ID selection (takes priority over name)                                                                              |
| `BifrostContextKeySessionID`               | `x-bf-session-id`                                    | `string`              | Session ID for key stickiness (requires KV store)                                                                                     |
| `BifrostContextKeySessionTTL`              | `x-bf-session-ttl`                                   | `time.Duration`       | Session-to-key cache TTL (duration string or seconds)                                                                                 |
| `BifrostContextKeyRequestID`               | `x-request-id`                                       | `string`              | Custom request ID for tracking                                                                                                        |
| `BifrostContextKeySendBackRawRequest`      | `x-bf-send-back-raw-request`                         | `bool`                | Include raw provider request in the response                                                                                          |
| `BifrostContextKeySendBackRawResponse`     | `x-bf-send-back-raw-response`                        | `bool`                | Include raw provider response in the response                                                                                         |
| `BifrostContextKeyStoreRawRequestResponse` | `x-bf-store-raw-request-response`                    | `bool`                | Persist raw request/response in log records                                                                                           |
| `BifrostContextKeyDisableContentLogging`   | `x-bf-disable-content-logging`                       | `bool`                | Per-request override for content logging; only honored when `allow_per_request_content_storage_override` is enabled in logging config |
| `BifrostContextKeyPassthroughExtraParams`  | `x-bf-passthrough-extra-params`                      | `bool`                | Enable passthrough for extra parameters                                                                                               |
| `BifrostContextKeyExtraHeaders`            | `x-bf-eh-*`                                          | `map[string][]string` | Custom headers forwarded to provider                                                                                                  |
| `BifrostContextKeySkipKeySelection`        | `-`                                                  | `bool`                | Skip key selection process (Go SDK only)                                                                                              |
| `BifrostContextKeyURLPath`                 | `-`                                                  | `string`              | Custom URL path appended to provider base URL (Go SDK only)                                                                           |
| `BifrostContextKeyUseRawRequestBody`       | `-`                                                  | `bool`                | Use raw request body (Go SDK only, requires RawRequestBody field)                                                                     |
| `semanticcache.CacheKey`                   | `x-bf-cache-key`                                     | `string`              | Custom cache key                                                                                                                      |
| `semanticcache.CacheTTLKey`                | `x-bf-cache-ttl`                                     | `time.Duration`       | Cache TTL (duration string or seconds)                                                                                                |
| `semanticcache.CacheThresholdKey`          | `x-bf-cache-threshold`                               | `float64`             | Similarity threshold (0.0-1.0)                                                                                                        |
| `semanticcache.CacheTypeKey`               | `x-bf-cache-type`                                    | `string`              | Cache type                                                                                                                            |
| `semanticcache.CacheNoStoreKey`            | `x-bf-cache-no-store`                                | `bool`                | Prevent caching                                                                                                                       |
| `mcp-include-clients`                      | `x-bf-mcp-include-clients`                           | `[]string`            | Filter MCP clients (comma-separated).                                                                                                 |
| `mcp-include-tools`                        | `x-bf-mcp-include-tools`                             | `[]string`            | Filter MCP tools (`clientName-toolName` format, comma-separated)                                                                      |
| `BifrostContextKeyMCPExtraHeaders`         | *(any header in a client's `allowed_extra_headers`)* | `map[string][]string` | Headers forwarded to MCP servers at tool execution time, filtered per-client against `allowed_extra_headers`                          |
| `maxim.TraceIDKey`                         | `x-bf-maxim-trace-id`                                | `string`              | Maxim trace ID                                                                                                                        |
| `maxim.GenerationIDKey`                    | `x-bf-maxim-generation-id`                           | `string`              | Maxim generation ID                                                                                                                   |
| `maxim.TagsKey`                            | `x-bf-maxim-*`                                       | `map[string]string`   | Maxim tags (custom tag names)                                                                                                         |
| `BifrostContextKeyDimensions`              | `x-bf-dim-*`                                         | `map[string]string`   | Unified per-request dimensions forwarded to logs, spans, Prometheus custom labels, and Maxim tags                                     |
| `BifrostContextKey(labelName)`             | `x-bf-prom-*`                                        | `string`              | Deprecated Prometheus-only label headers for backward compatibility                                                                   |

## Request Configuration Options

These options configure how Bifrost processes and forwards requests.

### Virtual Key

**Context Key:** `BifrostContextKeyVirtualKey`\
**Header:** `x-bf-vk`\
**Type:** `string`\
**Required:** Yes (when governance **is** enabled and enforced)

Specify the virtual key identifier for governance, routing, and access control.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-vk: sk-bf-*' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeyVirtualKey, "sk-bf-*")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

<Note>
  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.
</Note>

### API Key Selection

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

#### By ID

**Context Key:** `BifrostContextKeyAPIKeyID`
**Header:** `x-bf-api-key-id`
**Type:** `string`
**Required:** No

Explicitly select a key by its unique ID. Takes priority over name selection when both are provided.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-api-key-id: key-uuid-1234' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeyAPIKeyID, "key-uuid-1234")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

#### By Name

**Context Key:** `BifrostContextKeyAPIKeyName`
**Header:** `x-bf-api-key`
**Type:** `string`
**Required:** No

Explicitly select a named API key from your configured keys.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-api-key: premium-key' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeyAPIKeyName, "premium-key")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Session Stickiness (Session ID)

**Context Key:** `BifrostContextKeySessionID`
**Header:** `x-bf-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, Bifrost 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.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-session-id: user-123-session-abc' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeySessionID, "user-123-session-abc")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Session TTL

**Context Key:** `BifrostContextKeySessionTTL`
**Header:** `x-bf-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, Bifrost 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).

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-session-id: user-123-session-abc' \
    --header 'x-bf-session-ttl: 30m' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeySessionID, "user-123-session-abc")
    ctx = context.WithValue(ctx, schemas.BifrostContextKeySessionTTL, 30*time.Minute)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Request ID

**Context Key:** `BifrostContextKeyRequestID`
**Header:** `x-request-id`
**Type:** `string`
**Required:** No

Set a custom request ID for tracking and correlation. If not provided, Bifrost generates a UUID.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-request-id: req-12345-abc' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeyRequestID, "req-12345-abc")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Send Back Raw Request

**Context Key:** `BifrostContextKeySendBackRawRequest`
**Header:** `x-bf-send-back-raw-request`
**Type:** `bool` (header values: `"true"` or `"false"`)
**Required:** No

Include the exact JSON body sent to the provider alongside Bifrost's standardized response. Accepts `"true"` or `"false"` - either value fully overrides the provider-level `send_back_raw_request` config for this request.

<Warning>
  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-bf-store-raw-request-response` (gated by `allow_per_request_content_storage_override`).
</Warning>

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-send-back-raw-request: true' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeySendBackRawRequest, true)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    // Access raw request
    if response.ChatResponse != nil {
    rawReq := response.ChatResponse.ExtraFields.RawRequest
    }

    ```
  </Tab>
</Tabs>

The raw request appears in `extra_fields.raw_request`:

```json theme={null}
{
    "choices": [...],
    "usage": {...},
    "extra_fields": {
        "provider": "openai",
        "raw_request": {
            // Exact JSON sent to the provider
        }
    }
}
```

### Send Back Raw Response

**Context Key:** `BifrostContextKeySendBackRawResponse`\
**Header:** `x-bf-send-back-raw-response`\
**Type:** `bool` (header values: `"true"` or `"false"`)\
**Required:** No

Include the original provider response alongside Bifrost's standardized response format. Accepts `"true"` or `"false"` - either value fully overrides the provider-level `send_back_raw_response` config for this request.

<Warning>
  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-bf-store-raw-request-response` (gated by `allow_per_request_content_storage_override`).
</Warning>

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-send-back-raw-response: true' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeySendBackRawResponse, true)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    // Access raw response
    if response.ChatResponse != nil {
    rawResp := response.ChatResponse.ExtraFields.RawResponse
    }

    ```
  </Tab>
</Tabs>

The raw response appears in `extra_fields.raw_response`:

```json theme={null}
{
    "choices": [...],
    "usage": {...},
    "extra_fields": {
        "provider": "openai",
        "raw_response": {
            // Original provider response here
        }
    }
}
```

### Store Raw Request/Response

**Context Key:** `BifrostContextKeyStoreRawRequestResponse`\
**Header:** `x-bf-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-bf-send-back-raw-*` to do both.

<Warning>
  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-bf-send-back-raw-request` and `x-bf-send-back-raw-response` (sending raw bytes back to the caller).
</Warning>

<Warning>
  **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-bf-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-bf-store-raw-request-response: true`.
</Warning>

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-store-raw-request-response: true' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeyStoreRawRequestResponse, true)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })
    // Raw data is persisted in the log record.
    // ExtraFields.RawRequest/RawResponse are nil unless send-back flags are also enabled.

    ```
  </Tab>
</Tabs>

<Note>
  `x-bf-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-bf-store-raw-request-response` and `x-bf-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.
</Note>

### Disable Content Logging (Per-Request)

**Context Key:** `BifrostContextKeyDisableContentLogging`
**Header:** `x-bf-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-bf-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.

<Warning>
  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.
</Warning>

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    # Suppress content for this request only
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-disable-content-logging: true' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Sensitive data here"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    bfCtx := schemas.NewBifrostContext(ctx, schemas.NoDeadline)

    // Suppress content logging for this request
    bfCtx.SetValue(schemas.BifrostContextKeyDisableContentLogging, true)

    response, err := client.ChatCompletionRequest(bfCtx, &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

**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.

<Note>
  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.
</Note>

### Passthrough Extra Parameters

**Context Key:** `BifrostContextKeyPassthroughExtraParams`
**Header:** `x-bf-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.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-passthrough-extra-params: true' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}],
        "custom_param": "value",
        "nested_param": {
            "a": "value",
            "b": 123
        }
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeyPassthroughExtraParams, true)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    Params: &schemas.ChatParameters{
    ExtraParams: map[string]interface{}{
    "custom_param": "value",
    "nested_param": map[string]interface{}{
    "a": "value",
    "b": 123,
    },
    },
    },
    })

    ```
  </Tab>
</Tabs>

<Note>
  * Only works for JSON requests, not multipart/form-data requests
  * Parameters already handled by Bifrost are not duplicated
  * Nested parameters are merged recursively with existing structures
</Note>

### Skip Key Selection (Go SDK Only)

**Context Key:** `BifrostContextKeySkipKeySelection`\
**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.

```go theme={null}
ctx := context.Background()
ctx = context.WithValue(ctx, schemas.BifrostContextKeySkipKeySelection, true)

response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model:    "gpt-4o-mini",
    Input:    messages,
})
```

### Custom URL Path (Go SDK Only)

**Context Key:** `BifrostContextKeyURLPath`\
**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.

```go theme={null}
ctx := context.Background()
ctx = context.WithValue(ctx, schemas.BifrostContextKeyURLPath, "/custom/endpoint")

response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model:    "gpt-4o-mini",
    Input:    messages,
})
```

### Raw Request Body (Go SDK Only)

**Context Key:** `BifrostContextKeyUseRawRequestBody`\
**Header:** `-` (not available via HTTP)\
**Type:** `bool`\
**Required:** No

Send a raw request body instead of Bifrost'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.

```go theme={null}
// Prepare your raw JSON payload
rawPayload := []byte(`{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Hello!"}],
    "custom_field": "provider-specific-value"
}`)

ctx := context.Background()
ctx = context.WithValue(ctx, schemas.BifrostContextKeyUseRawRequestBody, true)

response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider:       schemas.OpenAI,
    Model:          "gpt-4o",
    RawRequestBody: rawPayload,
})
```

<Note>
  When using raw request body, Bifrost 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.
</Note>

## Custom Headers

### Extra Headers (x-bf-eh-\*)

**Context Key:** `BifrostContextKeyExtraHeaders`\
**Header Pattern:** `x-bf-eh-{header-name}`\
**Type:** `map[string][]string`\
**Required:** No

Pass custom headers to providers. The `x-bf-eh-` prefix is stripped before forwarding.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-eh-user-id: user-123' \
    --header 'x-bf-eh-tracking-id: trace-456' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    extraHeaders := map[string][]string{
        "user-id":     {"user-123"},
        "tracking-id": {"trace-456"},
    }
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeyExtraHeaders, extraHeaders)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

The headers `x-bf-eh-user-id` and `x-bf-eh-tracking-id` are forwarded to the provider as `user-id` and `tracking-id` respectively.

**Example use cases:**

* User identification: `x-bf-eh-user-id`, `x-bf-eh-tenant-id`
* Request tracking: `x-bf-eh-correlation-id`, `x-bf-eh-trace-id`
* Custom metadata: `x-bf-eh-department`, `x-bf-eh-cost-center`
* A/B testing: `x-bf-eh-experiment-id`, `x-bf-eh-variant`

## Semantic Cache Options

These options control semantic caching behavior.

### Cache Key

**Context Key:** `semanticcache.CacheKey`
**Header:** `x-bf-cache-key`
**Type:** `string`
**Required:** No

Specify a custom cache key for semantic cache lookups.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-cache-key: custom-key-123' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, semanticcache.CacheKey, "custom-key-123")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Cache TTL

**Context Key:** `semanticcache.CacheTTLKey`
**Header:** `x-bf-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.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-cache-ttl: 300' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, semanticcache.CacheTTLKey, 5*time.Minute)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

Accepts duration strings (`"30s"`, `"5m"`, `"1h"`) or plain numbers (treated as seconds).

### Cache Threshold

**Context Key:** `semanticcache.CacheThresholdKey`
**Header:** `x-bf-cache-threshold`
**Type:** `float64` (range: 0.0 to 1.0)
**Required:** No

Set the similarity threshold for semantic cache matching.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-cache-threshold: 0.85' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, semanticcache.CacheThresholdKey, 0.85)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Cache Type

**Context Key:** `semanticcache.CacheTypeKey`
**Header:** `x-bf-cache-type`
**Type:** `semanticcache.CacheType` (string)
**Required:** No

Specify the cache type for this request.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-cache-type: semantic' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, semanticcache.CacheTypeKey, semanticcache.CacheTypeSemantic)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Cache No Store

**Context Key:** `semanticcache.CacheNoStoreKey`
**Header:** `x-bf-cache-no-store`
**Type:** `bool` (header value: `"true"`)
**Required:** No

Prevent caching of this request/response.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-cache-no-store: true' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, semanticcache.CacheNoStoreKey, true)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

## MCP (Model Context Protocol) Options

These options control MCP client and tool filtering.

### Include Clients

**Context Key:** `mcp-include-clients`
**Header:** `x-bf-mcp-include-clients`
**Type:** `[]string` (comma-separated values)
**Required:** No

Filter MCP clients to include only the specified ones.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-mcp-include-clients: client1,client2' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKey("mcp-include-clients"), []string{"client1", "client2"})

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Include Tools

**Context Key:** `mcp-include-tools`
**Header:** `x-bf-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.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-mcp-include-tools: gmail-send_email,filesystem-read_file' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKey("mcp-include-tools"), []string{"gmail-send_email", "filesystem-read_file"})

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

## Maxim Observability Options

These options enable Maxim observability integration and tag propagation.

### Maxim Trace ID

**Context Key:** `maxim.TraceIDKey`
**Header:** `x-bf-maxim-trace-id`
**Type:** `string`
**Required:** No

Set the Maxim trace ID for distributed tracing.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-maxim-trace-id: trace-12345' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, maxim.TraceIDKey, "trace-12345")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Maxim Generation ID

**Context Key:** `maxim.GenerationIDKey`
**Header:** `x-bf-maxim-generation-id`
**Type:** `string`
**Required:** No

Set the Maxim generation ID for request correlation.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-maxim-generation-id: gen-12345' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, maxim.GenerationIDKey, "gen-12345")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

### Unified dimensions (x-bf-dim-\*)

**Context Key:** `BifrostContextKeyDimensions`\
**Header Pattern:** `x-bf-dim-{name}`\
**Type:** `map[string]string`\
**Required:** No

Add per-request dimensions once and have Bifrost 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
* Maxim generation and trace tags

`x-bf-dim-*` is now the canonical header prefix for runtime observability metadata.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-dim-environment: production' \
    --header 'x-bf-dim-team: engineering' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    dims := map[string]string{
        "environment": "production",
        "team":        "engineering",
    }
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKeyDimensions, dims)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
        Provider: schemas.OpenAI,
        Model:    "gpt-4o-mini",
        Input:    messages,
    })
    ```
  </Tab>
</Tabs>

<Note>
  `x-bf-dim-*` values cannot override reserved Bifrost 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-bf-dim-*`, reserved metric labels `path` and `method` are ignored at runtime.
</Note>

### Maxim Tags (x-bf-maxim-\*)

**Context Key:** `maxim.TagsKey`
**Header Pattern:** `x-bf-maxim-{tag-name}`
**Type:** `map[string]string`
**Required:** No

Add Maxim-specific tags to traces. Any header starting with `x-bf-maxim-` that isn't a reserved header becomes a tag.

Use `x-bf-dim-*` for tags that should also appear in logs, OpenTelemetry, and Prometheus. Use `x-bf-maxim-*` only for Maxim-specific tagging or when you need to override a same-named dimension for Maxim.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-maxim-environment: production' \
    --header 'x-bf-maxim-team: engineering' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    tags := map[string]string{
        "environment": "production",
        "team":        "engineering",
    }
    ctx := context.Background()
    ctx = context.WithValue(ctx, maxim.TagsKey, tags)

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

## Prometheus Options

**Context Key:** `BifrostContextKey(labelName)`
**Header Pattern:** `x-bf-prom-{label-name}`
**Type:** `string`
**Required:** No

Add custom labels to Prometheus metrics. The `x-bf-prom-` prefix is stripped and the remainder becomes the label name.

This header family is deprecated. Prefer `x-bf-dim-*`, which feeds Prometheus and the other observability backends together. If both `x-bf-dim-foo` and `x-bf-prom-foo` are present, the `x-bf-dim-*` value takes precedence for Prometheus.

<Tabs>
  <Tab title="Gateway (cURL)">
    ```bash theme={null}
    curl --location 'http://localhost:8080/v1/chat/completions' \
    --header 'x-bf-prom-environment: production' \
    --header 'x-bf-prom-team: engineering' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "Hello!"}]
    }'
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    ctx := context.Background()
    ctx = context.WithValue(ctx, schemas.BifrostContextKey("environment"), "production")
    ctx = context.WithValue(ctx, schemas.BifrostContextKey("team"), "engineering")

    response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), &schemas.BifrostChatRequest{
    Provider: schemas.OpenAI,
    Model: "gpt-4o-mini",
    Input: messages,
    })

    ```
  </Tab>
</Tabs>

## Security Denylist

Bifrost 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-bf-eh-*`)
* `x-goog-api-key` (when used via `x-bf-eh-*`)
* `x-bf-api-key` (when used via `x-bf-eh-*`)
* `x-bf-vk` (when used via `x-bf-eh-*`)

## Internal Context Keys

<Warning>
  These context keys are read-only and set when request is completed. **Do not set these values.**
</Warning>

The following context keys are set by Bifrost internally.

* `BifrostContextKeySelectedKeyID` - The selected provider key ID.
* `BifrostContextKeySelectedKeyName` - The selected provider key name.
* `BifrostContextKeyNumberOfRetries` - Number of retry attempts made.
* `BifrostContextKeyFallbackIndex` - Index of fallback provider used.
* `BifrostContextKeyFallbackRequestID` - Request ID for fallback attempts.
* `BifrostContextKeyStreamEndIndicator` - Indicates if stream completed.
* `BifrostContextKeyIntegrationType` - Format type of integration used.
* `BifrostContextKeyUserAgent` - User agent from request.

## Related Documentation

* **[Gateway Provider Configuration](../quickstart/gateway/provider-configuration)** - Configure providers and headers
* **[Go SDK Context Keys](../quickstart/go-sdk/context-keys)** - Programmatic context key usage
* **[Virtual Keys](../features/governance/virtual-keys)** - Virtual key usage and governance
* **[Semantic Cache](../features/semantic-caching)** - Caching configuration

```
```
