Skip to Content
Proxy Execution

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

RouteStreamingCurrent exposed behavior
POST /v1/proxy/openaiYesText generation, streaming, image-understanding, gpt-image-1 generation or edit, audio transcription, and audio generation inferred from payload shape.
POST /v1/proxy/anthropicYesText messages with sync and streaming support.
POST /v1/proxy/googleYesText generation with sync and streaming support, plus an image-understanding subset.
POST /v1/proxy/xaiYesText and chat with sync and streaming support.
POST /v1/proxy/metaYesText 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_id in 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-Key header 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/openai
  • POST /v1/proxy/anthropic
  • POST /v1/proxy/google
  • POST /v1/proxy/xai
  • POST /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 ?? null

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
Last updated on Edit this page on GitHub