Proxy Execution
Provider-native execution routes for Keel-managed requests.
For most use cases, use the SDK provider wrappers instead of calling proxy endpoints directly. The wrappers handle permits, usage reporting, and error handling automatically with a single import change.
Use these routes when Keel should execute the provider request and record usage in the same path, and you need direct control over the proxy layer.
Need to choose between execution surfaces first? See the route comparison in Quickstart.
Official public proxy routes
| Route | Streaming | Current exposed behavior |
|---|---|---|
POST /v1/proxy/openai | Yes | Text generation, streaming, image-understanding, gpt-image-1 generation or edit, audio transcription, and audio generation inferred from payload shape. |
POST /v1/proxy/anthropic | Yes | Text messages with sync and streaming support. |
POST /v1/proxy/google | Yes | Text generation with sync and streaming support, plus an image-understanding subset. |
POST /v1/proxy/xai | Yes | Text and chat with sync and streaming support. |
POST /v1/proxy/meta | Yes | Text generation with sync and streaming support, plus an image-understanding and embeddings subset. |
All five proxy routes support SSE streaming for text generation. Pass stream: true in the provider-native request payload. Advanced operations (image generation, audio, embeddings) remain sync-only where supported.
These routes remain provider-specific. Keel still does not expose a provider-neutral request shape here. Use POST /v1/executions when you want one canonical execution contract instead of provider-native payloads and provider-native responses.
Execution routes infer project context from the project API key and do not require
project_idin the request body.
What the proxy path does
- authenticates the caller with a client-scoped project API key
- applies Keel governance before provider dispatch
- preserves the provider-native request and response shape for the selected proxy route
- enforces the route-specific execution controls that Keel documents publicly
- records governance, routing, usage, and request state for later readback
Idempotency on proxy routes
- Keel uses the
Idempotency-Keyheader for replay protection on proxy routes - same key plus the same payload replays the cached response
- same key plus a different payload returns
409 conflict - if the header is omitted, Keel still executes the request, but retries are treated as new executions
On hosted runtimes, execution routes may require additional request freshness headers.
Prompt Firewall scope on proxy routes
Prompt Firewall currently runs on the public proxy routes for the prompt-bearing content Keel can extract from those payloads, including:
POST /v1/proxy/openaiPOST /v1/proxy/anthropicPOST /v1/proxy/googlePOST /v1/proxy/xaiPOST /v1/proxy/meta
That is still a route-dependent inspection boundary, not a claim of full provider parity across every payload field.
API example
curl
curl -i -sS https://api.keelapi.com/v1/proxy/openai \
-H "Authorization: Bearer keel_sk_your_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: proxy-001" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "Summarize this text in one sentence."}
],
"max_tokens": 200
}'Proxy routes return provider-native responses, not the normalized execution envelope.
Need the route matrix? See Route comparison.
Test this request in the Playground: Try in Playground
JavaScript
const response = await fetch('https://api.keelapi.com/v1/proxy/openai', {
method: 'POST',
headers: {
Authorization: 'Bearer keel_sk_your_key_here',
'Content-Type': 'application/json',
'Idempotency-Key': 'proxy-001'
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{ role: 'user', content: 'Summarize this text in one sentence.' }
],
max_tokens: 200
})
})
const data = await response.json()
console.log(data)Python
import requests
response = requests.post(
"https://api.keelapi.com/v1/proxy/openai",
headers={
"Authorization": "Bearer keel_sk_your_key_here",
"Content-Type": "application/json",
"Idempotency-Key": "proxy-001",
},
json={
"model": "gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Summarize this text in one sentence.",
}
],
"max_tokens": 200,
},
)
print(response.json())Response example
{
"id": "chatcmpl-B9MBs8CjcvOU2jLn4n570S5qMJKcT",
"object": "chat.completion",
"created": 1764104521,
"model": "gpt-4o-mini-2024-07-18",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The text says the team shipped the feature ahead of schedule and will monitor adoption over the next week."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 21,
"completion_tokens": 18,
"total_tokens": 39
}
}const requestId = data.id
const model = data.model
const text = data.choices?.[0]?.message?.content ?? null
const finishReason = data.choices?.[0]?.finish_reason ?? null
const providerErrorMessage = data.error?.message ?? nullRelated route guidance
For the canonical route matrix, see Route comparison.
Routing boundary
Routing and fallback controls are route-specific. Not all proxy routes support the same routing and fallback capabilities. See the provider support table for current coverage.
Current non-claims
- no claim that proxy routes are provider-neutral
- no public realtime session API
- advanced operation coverage (image generation, audio, embeddings) varies by provider — see the provider support table
- cost estimation accuracy varies by operation type, with multimodal operations relying on heuristic pre-dispatch estimates