Skip to content
DocsOpenAI SDK
AI features

OpenAI SDK

POST /v1/chat/completions is OpenAI’s Chat Completions API, so the official OpenAI SDK (and any tool built on it) works by changing its base URL and using a VectorAxis virtual key as its API key. The key decides the provider: the same code reaches OpenAI, Anthropic, Google, Groq and every other provider, with VectorAxis translating to each one’s own format.

The one change: set base_url to https://api.vectoraxis.ai/v1 (with /v1: the SDK appends /chat/completions) and api_key to a virtual key (vk-…). The SDK sends it as Authorization: Bearer. OPENAI_BASE_URL and OPENAI_API_KEY work too.
Quick start
Python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.vectoraxis.ai/v1",
    api_key="vk-1a2b3c4d5e6f7a8b.Xk3pQ9vN2mR7tY1wZ8bC4dF6gH0jK5lM3nP7qS9uV2w",   # your VectorAxis API key
    default_headers={"x-cache-mode": "simple"},                               # optional gateway features
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
TypeScript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://api.vectoraxis.ai/v1',
  apiKey: process.env.VECTORAXIS_KEY,   // vk-...
});

const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Hello!' }],
});

Every VectorAxis feature (caching, retries, fallbacks, guardrails, routing configs) is a request header: set it once with default_headers / defaultHeaders, or per call with extra_headers. The body stays pure OpenAI format.

What is supported
FeatureNotes
Streamingstream=True returns OpenAI-format chunks ending in [DONE]. The gateway always asks the provider for usage, so the last chunk carries token counts (with an empty choices list). An error after the first chunk (an output guardrail block, a provider failing mid-answer) arrives as a chunk with an error object, which the SDK raises. Streams use the cache and are retried or failed over until their first token: see Streaming.
Toolstools (with strict), tool_choice, parallel_tool_calls and tool-role results, on every provider; for Claude they are translated to Anthropic’s tool_use / tool_result.
Images, PDFs and audioContent parts image_url, file (file_data, or a vxf-… id from Files) and input_audio go to the provider as sent. Claude takes images and PDFs; audio on a Claude model is a 400.
Structured outputresponse_format json_schema, sent to Claude as its output_config.format.
Reasoningreasoning_effort (Claude: output_config.effort), and Claude’s thinking through extra_body. Claude’s thinking comes back on the message as thinking_blocks; send them back on the assistant message to continue a thinking turn.
Prompt cachingOn Claude models, cache_control on a content part or a tool, or at the top level through extra_body. Below.
Stop sequencesstop. On Claude the choice also carries the sequence that matched as stop_sequence.
Useruser is recorded in Logs.
Claude through the OpenAI SDK

Create an Anthropic virtual key and name a Claude model; nothing else changes. Anthropic-specific options ride in extra_body:

Python
claude = OpenAI(base_url="https://api.vectoraxis.ai/v1", api_key=ANTHROPIC_VIRTUAL_KEY)

response = claude.chat.completions.create(
    model="claude-sonnet-4-5",
    max_tokens=4096,
    messages=[{"role": "user", "content": "Plan a three-step migration."}],
    extra_body={"thinking": {"type": "enabled", "budget_tokens": 2048}},
)
message = response.choices[0].message
print(message.content)
print(message.model_extra.get("thinking_blocks"))   # signed thinking, to send back next turn

If your code is written for Anthropic’s own API, use the Claude SDK instead: it adds token counting and Message Batches.

Prompt caching

This is the provider’s own prompt cache, separate from the gateway’s response cache. On a Claude model a cache_control breakpoint goes on the content part (or tool) it should end at:

Python
response = claude.chat.completions.create(
    model="claude-haiku-4-5",
    messages=[
        {"role": "system", "content": [{
            "type": "text",
            "text": LONG_REFERENCE_TEXT,
            "cache_control": {"type": "ephemeral"},
        }]},
        {"role": "user", "content": "Summarise section 3."},
    ],
)
usage = response.usage
print(usage.prompt_tokens_details.cached_tokens)              # read from the cache
print(usage.model_extra.get("cache_creation_input_tokens"))   # written to it
  • prompt_tokens includes the cached tokens, as OpenAI reports it; the part read from the cache is prompt_tokens_details.cached_tokens, and writes are cache_creation_input_tokens.
  • OpenAI caches long prompts automatically, with no breakpoint; its cached_tokens are reported the same way.
  • Cached tokens are charged at the model’s cache rates, not as fresh input.
  • cache_control is removed before the request reaches OpenAI and other OpenAI-format providers, which would reject it, and passed on to OpenRouter, which forwards it to the Claude models it serves.
Errors

Errors raise the SDK’s usual exceptions with the HTTP status. A provider error keeps the provider’s own status and message. Two statuses come from the gateway itself:

StatusMeaning
422A guardrail or the tool-result scan blocked the request: x-guardrail-status: BLOCK, plus x-tool-scan-status: BLOCK for the scan.
503A provider 502 or 504 is returned as 503 (the original status in X-Upstream-Status), so it passes the edge network intact; the SDK retries it like any 5xx.
Other OpenAI endpoints

The same client reaches audio, images, files, batches and the Responses API: see Documents & media. client.decisions.create(...) reaches OpenAI’s Decisions API (/v1/decisions): see OpenAI Decisions. Managed prompts run as a chat completion through /v1/prompts/{slug}/completions (Prompt management).

Every endpoint is listed in Endpoints, and every header in Request headers.
NVIDIA Inception Program member

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