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

# Bring Your Own API Key

> Use your own Anthropic, OpenAI, or Google key to call providers directly — bypassing OpenRouter.

## Overview

By default, OkraPDF routes all chat completions through OpenRouter. If you'd rather call Anthropic, OpenAI, or Google directly — for cost control, latency, or compliance — you can pass your own API key.

Two ways to provide keys:

| Method                            | Persistence                 | Best for             |
| --------------------------------- | --------------------------- | -------------------- |
| `X-Vendor-Keys` header            | Per-request (ephemeral)     | Scripts, CI, testing |
| Settings > API Keys > Vendor Keys | Encrypted at rest (AES-GCM) | Production apps      |

Your key is never logged, never included in prompts, and never stored unless you explicitly save it to the vault.

## Quick example (curl)

```bash theme={null}
curl -X POST https://api.okrapdf.com/document/doc-abc123/chat/completions \
  -H "Authorization: Bearer okra_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H 'X-Vendor-Keys: {"openai": "sk-proj-..."}' \
  -d '{
    "messages": [{"role": "user", "content": "What was total revenue?"}],
    "agentConfigOverride": {
      "llm": {"chat": {"provider": "openai", "model": "gpt-4o-mini"}}
    }
  }'
```

The request hits `api.openai.com/v1` directly. OpenRouter is not involved.

## Supported providers

| Provider   | `provider` value | Example `model`              | Base URL                            |
| ---------- | ---------------- | ---------------------------- | ----------------------------------- |
| OpenRouter | `openrouter`     | `anthropic/claude-haiku-4.5` | `openrouter.ai/api/v1`              |
| Anthropic  | `anthropic`      | `claude-haiku-4-5-20251001`  | `api.anthropic.com`                 |
| OpenAI     | `openai`         | `gpt-4o`, `gpt-4o-mini`      | `api.openai.com/v1`                 |
| Google     | `google`         | `gemini-2.5-flash`           | `generativelanguage.googleapis.com` |

## SDK usage

```ts theme={null}
import { createOkra } from '@okrapdf/runtime';

const okra = createOkra({ apiKey: process.env.OKRA_API_KEY });
const session = okra.sessions.from('doc-abc123');

const { answer } = await session.prompt('Summarize the risk factors', {
  vendorKeys: { openai: process.env.OPENAI_API_KEY },
  agentConfigOverride: {
    llm: { chat: { provider: 'openai', model: 'gpt-4o-mini' } },
  },
});
```

## MCP usage (Claude Desktop / Claude Code)

In MCP tools like `ask_document` and `extract_data`, use the `provider:model` colon format:

```
> Ask doc-abc123 "What was total revenue?" using openai:gpt-4o-mini
```

The colon tells OkraPDF to route directly. A slash (`anthropic/claude-haiku-4.5`) routes through OpenRouter.

| Format                                | Route               |
| ------------------------------------- | ------------------- |
| `openai:gpt-4o`                       | Direct to OpenAI    |
| `anthropic:claude-haiku-4-5-20251001` | Direct to Anthropic |
| `google:gemini-2.5-flash`             | Direct to Google    |
| `anthropic/claude-haiku-4.5`          | Via OpenRouter      |

<Note>
  For MCP, store your vendor key in **Settings > API Keys > Vendor Keys** so it persists across requests. The MCP transport doesn't support custom headers.
</Note>

## Storing keys in the vault

Go to [okrapdf.com/settings/api-keys](https://okrapdf.com/settings/api-keys) and add your vendor key under the appropriate namespace (`openai`, `anthropic`, or `google`). Keys are encrypted with AES-GCM and only decrypted at call time.

Once stored, you don't need `X-Vendor-Keys` — OkraPDF resolves your key automatically when `provider` is set.

## Key resolution order

When a completion request specifies a provider, OkraPDF resolves the API key in this order:

1. `X-Vendor-Keys` header (per-request override)
2. Vault lookup by secret namespace
3. Resolved secrets overlay (internal)
4. Worker environment variable (platform default)

The first match wins. This means `X-Vendor-Keys` always takes priority.

## Security

* **In transit**: All requests use HTTPS/TLS
* **At rest**: Vault keys encrypted with AES-GCM (KEK stored as CF Worker secret)
* **Ephemeral keys** (`X-Vendor-Keys`): held in Worker memory for the request duration, never persisted
* **No logging**: Key values are never written to logs, SQLite, or R2
* **Scoped forwarding**: Your key is only sent to the provider you specified — never to third parties
