Gateway API
The OpenAI‑compatible endpoint and Anthropic’s Messages API: endpoints, attribution and response headers, the request pipeline, errors, providers and the simulator.
On this page
The gateway is an OpenAI‑compatible HTTP API that also serves Anthropic’s Messages API. Point any OpenAI SDK at https://gateway.worksi.ai/v1, or an Anthropic SDK at https://gateway.worksi.ai, with an aiw_sk_… key and every call is authenticated, checked against your plan and policies, forwarded to the provider you chose, priced and traced. Providers & routing explains how a call finds its provider.
Send the key as Authorization: Bearer, as x-api-key (what the Anthropic SDKs send) or as api-key (Azure‑style clients).
Endpoints#
| Method and path | What it does |
|---|---|
POST / | Chat Completions, streaming and non-streaming, on every provider (translated to the Messages API for Claude). Usage is captured even for streams. |
POST / | Responses API, streaming and non-streaming, where the provider serves it |
POST / | Embeddings, where the provider serves them (the model’s registry type must be embedding) |
POST / | Anthropic’s Messages API, natively, for models on Anthropic credentials. See Claude. |
POST / | Anthropic token counting. Not metered. |
GET /, GET / | The models this key may use, in the OpenAI list format (Anthropic’s format when the request carries anthropic-version). ?include=catalog adds the unregistered catalog models of your preset credentials when your organization allows unregistered models (details). |
GET / | Pause and stop state, plus tool policy verdicts, for SDK pre-checks |
POST /, GET / | Request and poll a human approval |
POST /, POST / | Spans and business outcomes from the SDKs |
POST / | OpenTelemetry traces over OTLP/HTTP |
/, / | The Worksi MCP server and the MCP gateway. See MCP. |
Request headers#
All optional. The SDKs set them for you from the current run and step.
| Header | Meaning |
|---|---|
X-AIW-Agent, X-AIW-Workflow, X-AIW-Team | Attribution. Drives policies, dashboards, cost allocation and auto-discovery. |
X-AIW-Run-Id | Workflow run id (defaults to the trace id) |
X-AIW-Trace-Id, X-AIW-Parent-Span-Id | Attach the call to your own trace. W3C traceparent is used when these are absent. |
X-AIW-Step | Step name |
X-AIW-End-User, X-AIW-End-User-Plan | Your end user (a pseudonymous id) and their plan in your app. See end‑user plans. |
X-AIW-Tags | Comma-separated tags |
X-AIW-Capture | redacted or metadata_only. Can only make capture stricter. |
X-AIW-Approval-Id | An approved model-access approval, for models that require one |
X-AIW-Fallback | off turns the model’s fallbacks off for this request |
X-AIW-Simulate | Fault injection for the simulator (see below) |
anthropic-version, anthropic-beta | Forwarded to Anthropic. anthropic-version also selects Anthropic’s format for /. |
Response headers#
| Header | Meaning |
|---|---|
X-AIW-Request-Id | Gateway request id. Quote it when you contact support. |
X-AIW-Trace-Id, X-AIW-Span-Id, X-AIW-Run-Id | Where to find the call in Operations → Traces |
X-AIW-Provider | The provider preset that served the call, for example deepseek, else the provider kind |
X-AIW-Provider-Kind | openai, anthropic, openai_compatible or simulator |
X-AIW-Model | The model that served the call (the fallback model, when one did) |
X-AIW-Fallback-From | The model first resolved, when a fallback served the call |
X-AIW-Cost-USD | Cost of the call in USD (non-streaming responses; streams carry the cost on the span) |
X-AIW-Upstream-Request-Id | The provider’s own request id, when it sent one |
X-AIW-Sampling-Dropped, X-AIW-Params-Clamped, X-AIW-Params-Ignored | Parameters the gateway dropped, clamped into range or removed because the model or provider rejects them |
X-AIW-Tool-Choice-Downgraded | A forced tool choice set to auto, because the model cannot honor it |
X-AIW-Max-Tokens-Defaulted | The max_tokens the gateway supplied for Claude |
X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After | Rate-limit state |
What happens on every request#
- The body size is checked (10 MiB).
- The key is resolved to its organization, workspace and environment.
- The model is resolved through your model registry, by id or alias, or by its route prefix, and its provider must serve the endpoint.
- Operator controls apply: a paused agent or workflow gets
423, a stopped run gets409. - Plan and policy checks: your subscription status and monthly quota, then your policies (model allow and deny lists, spend, token and rate limits, model-access approvals, declared tools and end‑user quotas).
- The key’s own rate limit applies.
- The call goes to your provider, with timeouts and up to two retries with backoff on connection errors,
429and5xx, then the model’s fallbacks. There is never a retry or a fallback after the first streamed byte. - Tokens and cost are computed in USD from your registry prices (or the catalog’s, for an unregistered model of a preset credential) and the call is recorded as a span. Telemetry is asynchronous: it never fails or delays the request.
Errors#
Errors use the OpenAI error shape plus the gateway request id. On /v1/messages they use Anthropic’s error shape instead, with the gateway code in error.aiw_code, so the Anthropic SDKs raise their own typed errors.
{"error": {"message": "agent \"triage-agent\" is paused: investigating INC-12", "type": "…", "code": "agent_paused", "param": null, "aiw_request_id": "req_…"}}| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed request, the wrong model type for the endpoint, or a request Claude cannot take (n above 1, a JSON response_format) |
| 400 | unsupported_endpoint | The model’s provider does not serve this endpoint, for example embeddings on Anthropic |
| 401 | invalid_api_key | Unknown, revoked or expired key |
| 402 | budget_exceeded | A spend-limit policy’s budget for the period is used up |
| 402 | subscription_inactive | The trial has ended or the subscription is inactive |
| 403 | insufficient_scope | The key lacks the endpoint’s scope |
| 403 | model_not_allowed | Blocked model, an allow or deny list, or a model outside the end user’s plan |
| 403 | approval_required | The model needs an approved X-AIW-Approval-Id |
| 403 | tool_not_allowed | The request declares a tool the agent may not use |
| 403 | token_limit_exceeded | Per-request or daily token limit |
| 409 | run_stopped | An operator stopped this run. Don’t retry. |
| 413 | payload_too_large | Body over 10 MiB |
| 423 | agent_paused, workflow_paused | An operator paused the agent or workflow |
| 429 | rate_limited | Key or policy rate limit. Honor Retry-After. |
| 429 | plan_quota_exceeded | Your plan’s monthly gateway requests are used up. Retry-After counts down to the next month. |
| 429 | end_user_quota_exceeded | Your end user reached a limit of their plan |
| 502 | provider_error | Upstream 5xx or connection failure after retries and fallbacks, or a disabled provider named by a route prefix |
| 504 | provider_timeout | Upstream timeout |
Provider 4xx responses, such as a content-policy refusal, are passed through unchanged. Every refusal by the gateway itself is still recorded as a span with status=blocked, so blocked traffic stays visible and can raise a policy-violation incident.
Providers#
| Kind | Notes |
|---|---|
openai | https:// or your own base URL |
anthropic | Claude, through the native Messages API adapter |
openai_compatible | The catalog presets, from DeepSeek and Qwen to Ollama and vLLM, and any other server that speaks the OpenAI API at a base URL you register |
simulator | Deterministic, offline and free. Replies are derived from a hash of the prompt, latency is 150–600 ms, and streaming, embeddings and the Messages API are supported. |
The presets, their route prefixes and what each one serves are listed in Providers & routing.
The gateway refuses private network addresses unless they are explicitly allowed for your deployment, and it never follows redirects.
Simulator and fault injection#
When the resolved provider is the simulator, the X-AIW-Simulate header injects faults, so you can test your error handling and your alerting without breaking anything. Faults apply to the first call only, never to fallback models. Separate directives with ;.
| Directive | Effect |
|---|---|
latency=<ms> | Simulated latency |
error=<status> | The upstream answers with that HTTP status, for example error=503 |
timeout | The upstream hangs and the gateway returns 504 provider_timeout |
tokens=<n>, output_tokens=<n> | Report n input or output tokens |
tool_call=<name> | The model answers with a call of tool <name> |
stream_error | Abort the stream midway |
content=<url-encoded text> | Fixed reply text |
More examples#
curl -sN https://gateway.worksi.ai/v1/chat/completions \ -H "Authorization: Bearer $AIW_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "gpt-5-mini", "stream": true, "messages": [{"role": "user", "content": "Count to five"}]}'curl -s https://gateway.worksi.ai/v1/embeddings \ -H "Authorization: Bearer $AIW_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "text-embedding-3-small", "input": "refund policy"}'curl -s https://gateway.worksi.ai/v1/models \ -H "Authorization: Bearer $AIW_API_KEY"Questions? Email info@xeoo.io.