Skip to main content

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:
MethodPersistenceBest for
X-Vendor-Keys headerPer-request (ephemeral)Scripts, CI, testing
Settings > API Keys > Vendor KeysEncrypted 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)

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

Providerprovider valueExample modelBase URL
OpenRouteropenrouteranthropic/claude-haiku-4.5openrouter.ai/api/v1
Anthropicanthropicclaude-haiku-4-5-20251001api.anthropic.com
OpenAIopenaigpt-4o, gpt-4o-miniapi.openai.com/v1
Googlegooglegemini-2.5-flashgenerativelanguage.googleapis.com

SDK usage

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.
FormatRoute
openai:gpt-4oDirect to OpenAI
anthropic:claude-haiku-4-5-20251001Direct to Anthropic
google:gemini-2.5-flashDirect to Google
anthropic/claude-haiku-4.5Via OpenRouter
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.

Storing keys in the vault

Go to 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