Skip to content
DocsResponses API
AI features

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.

The one change: set the SDK’s base URL to https://api.vectoraxis.ai/v1 and its API key to a virtual key (vk-…). The environment variables OPENAI_BASE_URL and OPENAI_API_KEY work too. The key decides the provider; the request stays in OpenAI’s format either way.
Quick start
Python
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)
TypeScript
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.

How a request reaches the provider
Key forWhat the provider receives
OpenAIYour 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 providerThe 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.

What carries over to other providers
FeatureNotes
Inputinstructions, 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 toolstools 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.
Streamingstream: 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).
Parametersmax_output_tokens, temperature, top_p, reasoning.effort, and safety_identifier (recorded as the request’s user in Logs).
Structured outputtext.format of type json_schema or json_object.
Claude thinkingClaude’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.
Usageusage in the Responses shape, with the provider’s prompt-cache reads in input_tokens_details.cached_tokens.
Only OpenAI can do these, and another provider refuses them with a 400 naming what would be lost, rather than dropping it silently: built-in tools (web_search, file_search, code_interpreter, image_generation, mcp, custom, …) and their call items, item_reference, previous_response_id, conversation, prompt, background, an image by file id and a file by URL. Settings that only mean something to OpenAI (store, include, prompt_cache_key, text.verbosity, truncation, service_tier, metadata) and OpenAI’s own reasoning items are not sent to other providers. Keep conversation state on your side (send the history as input items) when the model is not OpenAI’s.
The same controls as chat completions
  • 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.

Stored responses

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 CLI

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.

TOML
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"
Prefer chat completions? The same keys and models work on /v1/chat/completions: see OpenAI SDK. Writing against Anthropic’s API instead? See Claude SDK.
NVIDIA Inception Program member

VectorAxis is built by GK Labs, a member of NVIDIA Inception.