API reference · API
Create a response (OpenAI Responses wire format)
POST/v1/responsesAPI keyNo key
OpenAI's Responses format over the same dispatch path as chat completions: rate limit, monthly spend cap, the models fallback chain, autopilot, key policy, credits, cache and metering all behave as they do there. Stateless unless the operator turns stored responses on (ANTIMATTER_STORED_RESPONSES=1): then store: true keeps the response and its whole conversation, previous_response_id continues a kept one (an unknown id is a 404, code previous_response_not_found; a conversation past the stored ceiling a 400, code stored_response_too_large), and GET and DELETE /v1/responses/{id} read and remove it; both need a key. Otherwise previous_response_id and store: true are refused, and always background, conversation, item references and hosted tools (web_search, computer; file_search where vector stores are off) are refused with a 400 that names the field in error.param, code unsupported_parameter. Unknown fields are refused as unknown_parameter. With no key and x402 on, a 402 names the price; see GET /api/x402.
Request body
application/json, required
| Field | Type | What it is |
|---|---|---|
| model | string | Required, unless the prompt's version names a model. At most 200 characters. |
| models | array of string | The gateway's fallback chain, tried in order after model, as on the chat wire. |
| input | string or array of object | A string, or message, function_call and function_call_output items. Reasoning items are dropped. |
| instructions | string or null | |
| max_output_tokens | integer or null | |
| temperature | number or null | |
| top_p | number or null | |
| tools | array of object or null | Function tools, and file_search while vector stores are on. Other hosted tools (web_search, computer) are refused. |
| tool_choice | string or object or null | |
| parallel_tool_calls | boolean or null | |
| text | object or null | |
| reasoning | object or null | |
| metadata | object or null | |
| stream | boolean or null | |
| stream_options | object or null | |
| user | string or null | |
| safety_identifier | string or null | |
| prompt_cache_key | string or null | |
| prompt_cache_retention | string or null | |
| include | array of string or null | |
| store | boolean or null | true keeps the response and its conversation for previous_response_id, GET and DELETE /v1/responses/{id}, while stored Responses are on (ANTIMATTER_STORED_RESPONSES=1); refused otherwise. |
| background | boolean or null | Refused unless false or absent: this gateway is stateless. |
| previous_response_id | string or null | A stored response this one continues, while stored Responses are on; refused otherwise. |
| conversation | any | Refused unless null or absent: this gateway is stateless. |
| prompt | any | A prompt kept here (lib/prompts.ts): {id, version, variables}. version is a number or a label such as production; rendered before the instructions and input. |
| context_management | any | Refused unless null or absent: this gateway is stateless. |
| moderation | any | Refused unless null or absent. |
| top_logprobs | integer or null | Refused above 0. |
| truncation | string or null | auto is refused. |
| service_tier | string or null | Only auto or default. |
Example
{
"model": "antimatter/auto",
"input": "Say hello in five words."
}Answer 200
A response object, or when stream is true the Responses event stream: response.created, response.in_progress, the output item, content part, text and function call argument events, then one of response.completed, response.incomplete or response.failed. Every event has a sequence_number.
Headers: x-antimatter-upstream, x-antimatter-request-id, x-request-id, x-antimatter-cost-micros, x-antimatter-adjusted, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, x-antimatter-model, x-antimatter-route, x-antimatter-json, x-antimatter-compress, x-antimatter-pii-redacted, x-antimatter-pii-kinds, x-antimatter-prompt-version, x-antimatter-memory, x-antimatter-overhead-ms, x-antimatter-stream-id
| Field | Type | What it is |
|---|---|---|
| id | string | resp_ followed by the gateway request id. |
| object | "response" | |
| created_at | integer | |
| status | string | One of "completed", "incomplete", "failed". |
| model | string | The catalog id that answered. |
| output | array of object | |
| output[] | string | One of "message", "function_call". |
| output[] | string | |
| output[] | string | |
| usage | object | |
| usage. | integer | |
| usage. | object | |
| usage. | integer | |
| usage. | integer | |
| usage. | object | |
| usage. | integer | |
| usage. | integer | |
| error | object or null | |
| incomplete_details | object or null | |
| metadata | object | |
| store | false |
Errors
- 400OpenAI shaped error.
- 401OpenAI shaped error.
- 402A funded account whose balance reached zero. An account that has never deposited is never gated this way.
- 403The key's policy refused the request: policy_violation when no candidate is on the allowlist, a model is on the blocklist, or the wire is not one the key may use; policy_exceeded when a named limit is spent; request_cost_exceeded when the request's worst case cost is over the key's per request ceiling.
- 404OpenAI shaped error.
- 413OpenAI shaped error.
- 429Rate limited, or a spent budget or spend cap. The type distinguishes rate_limit_error, policy_exceeded, and spend_cap_exceeded.
- 499The client closed the connection before the response finished.
- 502OpenAI shaped error.
- 503OpenAI shaped error.
- 504The upstream did not answer within the gateway's timeout (upstream_timeout).
Every error answers in one shape, with its type, code and the field it names. The whole list is in the docs' Errors section.
Request headers it reads (14)
| Field | Type | What it is |
|---|---|---|
| x-antimatter-session | string | A free form label that groups requests in the log. Printable ASCII, trimmed to 120 characters. At most 120 characters. |
| x-antimatter-cache | string | Send on to opt into the exact match and prefix cache layers, or semantic to add the similarity layer on a key that enabled it. Non streaming only, never for a request served on your own provider key, and always scoped to your account. The response echoes x-antimatter-cache: hit, semantic, or miss. A hit costs nothing and spends no credits. One of "on", "semantic", "off". |
| x-antimatter-route | string | A JSON object steering one autopilot decision. Every field is optional: policy (balanced, cheap, fast, quality), weights (price, latency, quality), max_price_per_1m, min_context, modality, require_tools, require_json. It shapes the routing of an antimatter/auto id only; a request that named a model is dispatched to that model and the directive is reported back in x-antimatter-route-warning as ignored rather than applied quietly. Anything unreadable in the object is reported the same way. At most 2000 characters. |
| x-antimatter-cache-control | string | Send auto to let the gateway place one provider side cache_control breakpoint at the boundary of a thread prefix a chain hash has proved unchanged. It does nothing when you placed your own markers, when the thread is not a verified continuation, or on a model whose wire does not read cache_control. The response says which in x-antimatter-cache-control. One of "auto". |
| x-antimatter-auto-cache | string | Automatic prompt caching for this request, over the key's autoCache policy and the deployment's default. On an Anthropic world the gateway marks a prompt start this account sent within five minutes (the system prompt and tools, or the conversation so far) so the vendor serves it from its cache; Gemini, OpenAI, DeepSeek and Grok cache by themselves. Cached tokens are billed at the world's cache read rate and written ones at its write rate; the hold stays the uncached worst case plus the write premium. One of "on", "off". |
| x-antimatter-hedge | string | <ms>; max=<micros>, or off. When the first source has sent no byte in that many milliseconds (50 to 60000), the same request goes to a second source of the same world at the same card and the first answer wins; the other is cancelled and billed its prompt bound, which must fit under max or nothing is hedged. Never on your own provider key or under strict JSON. Over the key's hedgeMs and hedgeMaxMicros. |
| x-antimatter-resumable | string | Send 1 on a streaming request made with a key to make the stream resumable. The answer carries x-antimatter-stream-id and numbers every SSE event with an id: line. If the connection drops, the generation carries on to its end and is billed in full, once, exactly as if you had stayed; pick it up at GET /v1/streams/{id}. The output is kept for ANTIMATTER_RESUME_TTL_S (600 s) after its last write, up to ANTIMATTER_RESUME_MAX_BYTES (4 MiB) of frames. Ignored on a request that does not stream, and on an x402 paid request, which has no key to resume with. One of "1". |
| x-antimatter-fallback | string | Send comparable to fall back, when the requested world and its models chain fail with a retriable error or every provider of it has an open breaker, to the nearest world priced at or below it on both sides with the capabilities and context this request needs, inside the key's allow and block lists. A request on your own provider key only falls back to a world that key serves. off turns off the key's own setting for this request. The answer names what happened in x-antimatter-fallback. One of "comparable", "off". |
| x-antimatter-json | string | Send strict on a request whose response_format is json_object or json_schema to have the answer checked before it is handed over: it must parse, and for json_schema match the schema (format annotations are not checked). An answer that fails is asked for once more on the same world with a short repair note, then from the comparable fallback when one is set. Every attempt is billed as a live call and the hold covers two. A final failure is a 422 json_invalid carrying the last answer as error.content. On a stream the answer is asked for whole and checked first, so the first byte waits for the check; the checked answer then streams as chunks. off turns off the key's strictJson policy for this request. One of "strict", "off". |
| x-antimatter-compress | string | Prompt compression, off unless asked for. safe: a document or tool result repeated later in the thread is sent once and each later copy becomes a short reference to the first; trailing spaces and blank line runs in long pasted blocks are tidied outside code fences; a long system prompt goes first in the system block; and on a world that reads cache_control, breakpoints mark the end of the stable prefix. aggressive: safe, and the turns before the last few are replaced by a summary from the cheapest paid model the key may use (or model=<id>; keep=<n> moves the cut), a request of its own, metered and billed. A short thread is not summarized, nor the last user turn or a tool call still waiting on its result. off turns off the key's compress policy for this request. |
| x-antimatter-memory | string | Long term memory, where the operator has it on: a memory space id, or default for the key's own. The memories nearest the last user turn, of the request's end user (user on chat completions, metadata.user_id on /v1/messages, user or else safety_identifier on /v1/responses), go in front of the model in the wire's own system field: one system message after the caller's own on chat completions, a paragraph at the end of system on /v1/messages, a paragraph at the end of instructions on /v1/responses (the answer still echoes the instructions as sent). The recall is one embeddings request billed as the key, which needs the embeddings scope. |
| x-antimatter-memory-write | string | 1: after the answer, the conversation and the answer's text are queued for extraction into the space named by x-antimatter-memory (or the default), read and billed as the key like POST /v1/memories. On chat completions, /v1/messages and /v1/responses; a stream is read as it passes. One of "1". |
| x-antimatter-prompt | string | A prompt kept here, by header instead of the body's prompt field: pmpt_..., pmpt_...@3 for a version, pmpt_...@staging for a label. With neither, the production label when it is set, else the newest version. |
| x-antimatter-prompt-variables | string | The prompt's values as a JSON object, beside x-antimatter-prompt. |