Responses API
VectorAxis serves OpenAI’s Responses API (POST /v1/responses) for every provider it routes to, so the OpenAI SDK’s client.responses, and tools built on it such as the Codex CLI, run on Claude, Gemini, Groq, Mistral and the rest by changing only the base URL, the virtual key and the model. Requests run through the same pipeline as chat completions and the Claude SDK: budgets, rate limits, guardrails, the tool-result scan, caching, fallbacks, routing configs, logs and cost.
from openai import OpenAI
client = OpenAI(
base_url="https://api.vectoraxis.ai/v1",
api_key="vk-c7d4e1f2a3b95a8b.Rq8mT2vX5nL9pW3kY7cJ1hF4dS6gB0zN2aE8uV5tQ1c", # an Anthropic virtual key
)
response = client.responses.create(
model="claude-sonnet-4-6",
instructions="Answer in one sentence.",
input="Why is the sky blue?",
)
print(response.output_text)import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.vectoraxis.ai/v1',
apiKey: process.env.VECTORAXIS_KEY, // vk-..., for any provider
});
const stream = await client.responses.create({
model: 'gemini-2.5-flash',
input: 'Write a haiku about gateways.',
stream: true,
});
for await (const event of stream) {
if (event.type === 'response.output_text.delta') process.stdout.write(event.delta);
}Every VectorAxis feature is a request header, exactly as on chat completions: set them once with the SDK’s default_headers / defaultHeaders, or per call with extra_headers. See Request headers, and the API reference for the endpoint itself.
| Key for | What the provider receives |
|---|---|
| OpenAI | Your request as you sent it, at OpenAI’s own /v1/responses, with only what the gateway decided written in: the key’s model, routing overrides, and any text a guardrail or the tool-result scan redacted. OpenAI’s response and stream events come back unchanged, so every Responses feature works: built-in tools, previous_response_id, stored responses, reasoning items, include. |
| Any other provider | The request translated to that provider’s chat format, and the answer translated back into a Responses object (or the Responses stream events). Not stored: store comes back false. |
The decision is made per call, so a fallback or a routing config can move a Responses request from OpenAI to Claude and back: each provider gets it in the form it can take.
| Feature | Notes |
|---|---|
| Input | instructions, input as a string or as items: message items in every role (developer becomes a system message), with input_text, input_image (a URL or data URL), input_file (file data or a file id) and input_audio parts. |
| Function tools | tools of type function (with strict), tool_choice (auto, none, required or a named function), parallel_tool_calls, and function_call / function_call_output items for the tool loop. |
| Streaming | stream: true returns the Responses event sequence: response.created, response.output_item.added, response.output_text.delta, response.function_call_arguments.delta, …, response.completed (or response.incomplete when the answer hit max_output_tokens). |
| Parameters | max_output_tokens, temperature, top_p, reasoning.effort, and safety_identifier (recorded as the request’s user in Logs). |
| Structured output | text.format of type json_schema or json_object. |
| Claude thinking | Claude’s thinking comes back as reasoning items: the thinking text as the summary, the signed block in encrypted_content. Send them back with the next turn’s input, as you would OpenAI’s, and Claude gets its thinking unchanged during tool use. |
| Usage | usage in the Responses shape, with the provider’s prompt-cache reads in input_tokens_details.cached_tokens. |
- Keys: BYOK and PLATFORM virtual keys, status, expiry, credit limit, model allowlist, and requests and tokens per minute and day. A raw provider key works on the direct-credential path: an OpenAI key unless x-provider names another provider.
- Plan limits: the workspace request rate.
- Guardrails: input and output, the key’s own plus any named in x-guardrail, streamed or not. A block is a 422 with x-guardrail-status: BLOCK and the error code guardrail_blocked.
- Tool-result scan: on every function_call_output, at the key’s own action.
- Gateway features: response caching (x-cache-mode; a hit streams as events too), retries and fallbacks across providers, routing configs (x-config), prompt attribution, logs and cost. Requests appear in Logs as Responses.
Errors come back in OpenAI’s shape, {"error":{"message","type","param","code"}}, so the SDK raises its usual exception classes; an OpenAI error keeps OpenAI’s own status and body. After the first stream event a failure arrives as an error event.
client.responses.retrieve, client.responses.delete and client.responses.input_items.list (GET / DELETE /v1/responses/{id}, GET /v1/responses/{id}/input_items) reach OpenAI, which stores the responses it creates unless the request sets store: false. A response from another provider is not stored anywhere, so it cannot be retrieved later.
Codex speaks the Responses API, so it routes through VectorAxis with a custom model provider in ~/.codex/config.toml. With an OpenAI key it runs OpenAI’s models as usual; with a key for another provider, set model to that provider’s model. See Coding agents.
model = "gpt-5.4-mini" model_provider = "vectoraxis" [model_providers.vectoraxis] name = "VectorAxis" base_url = "https://api.vectoraxis.ai/v1" env_key = "VECTORAXIS_API_KEY" # export VECTORAXIS_API_KEY=vk-... wire_api = "responses"