Documentation
Integrate Zopyr AI with the standard OpenAI SDK in minutes.
Quickstart
Zopyr AI implements the OpenAI Chat Completions specification. Replace your baseURL with https://api.zopyr.com/v1.
Extended Endpoints (Responses, Anthropic, Embeddings, Files & Realtime WS)
In addition to /v1/chat/completions, Zopyr natively serves the OpenAI 2026 Responses API, Anthropic Messages API (Claude Code compatible), vector Embeddings, encrypted organization Files, and stateful Realtime WebSockets under one API key.
Model Catalog
Browse all available models, context windows, and per-token pricing.
Open Playground
Test models side-by-side with live streaming and token telemetry.
Quickstart
Zopyr AI implements the OpenAI Chat Completions specification. Replace your baseURL with https://api.zopyr.com/v1.
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.zopyr.com/v1',
apiKey: process.env.ZOPYR_API_KEY,
});
const completion = await client.chat.completions.create({
model: 'openai/gpt-6.1-sol-pro',
messages: [
{ role: 'system', content: 'You are a concise engineering assistant.' },
{ role: 'user', content: 'Write a binary search in TypeScript.' },
],
});
console.log(completion.choices[0]?.message.content);Authentication & API keys
Pass your key in the Authorization: Bearer zpr-v1-... header. You can configure per-key USD credit caps, RPM rate limits, and IP allowlists in /app/keys
Models, routing & automatic fallbacks
Pass any canonical model slug (such as openai/gpt-4o or anthropic/claude-3.7-sonnet). If the primary upstream endpoint returns a 5xx or rate-limit error before streaming begins, the gateway automatically fails over to the next healthy provider.
Streaming (SSE)
Pass stream: true to receive Server-Sent Events chunks ending with data: [DONE]. Include stream_options.include_usage = true to receive the final usage and exact USD cost object.
const stream = await client.chat.completions.create({
model: 'openai/gpt-4o',
stream: true,
stream_options: { include_usage: true },
messages: [{ role: 'user', content: 'Stream a haiku about distributed systems.' }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
if (chunk.usage) {
console.log('\nTokens & exact USD cost:', chunk.usage);
}
}Tool calling & functions
Models with the tools capability accept standard OpenAI tools definitions and tool_choice controls for deterministic function calling.
const response = await client.chat.completions.create({
model: 'openai/gpt-6.1-sol-pro',
messages: [{ role: 'user', content: 'What is the exchange rate for USD to EUR?' }],
tools: [
{
type: 'function',
function: {
name: 'get_fx_rate',
description: 'Get live market exchange rate for a currency pair',
parameters: {
type: 'object',
properties: {
base: { type: 'string', enum: ['USD'] },
quote: { type: 'string', enum: ['EUR', 'GBP', 'CHF'] },
},
required: ['base', 'quote'],
},
},
},
],
tool_choice: 'auto',
});Structured outputs & JSON schema
Enforce strict JSON schema compliance by passing response_format with type: json_schema or json_object on supported models.
const response = await client.chat.completions.create({
model: 'google/gemini-2.5-pro',
messages: [{ role: 'user', content: 'Extract invoice fields from: Invoice #904 for $25.00' }],
response_format: {
type: 'json_schema',
json_schema: {
name: 'invoice',
strict: true,
schema: {
type: 'object',
properties: {
invoiceNumber: { type: 'string' },
amountUsd: { type: 'number' },
},
required: ['invoiceNumber', 'amountUsd'],
additionalProperties: false,
},
},
},
});Reasoning tokens
For reasoning models (such as deepseek/deepseek-r1 or claude-3.7-sonnet), control thinking depth via reasoning_effort ('low' | 'medium' | 'high'). Reasoning tokens are metered and reported under completion_tokens_details.
const response = await client.chat.completions.create({
model: 'deepseek/deepseek-r1',
reasoning_effort: 'high',
messages: [{ role: 'user', content: 'Prove that the square root of 2 is irrational.' }],
});Rate limits & headers
Every response includes x-ratelimit-limit, x-ratelimit-remaining, and x-ratelimit-reset headers. When a limit is reached, HTTP 429 is returned with a Retry-After header.
Billing, atomic holds & ledger
Before forwarding a request, the gateway places an atomic hold for the worst-case token cost and settles the exact nano-USD cost when the completion finishes. Query your live balance and generation costs via REST.
# Check API key limits & remaining budget
curl https://api.zopyr.com/v1/key \
-H "Authorization: Bearer $ZOPYR_API_KEY"
# Check wallet balance & total usage
curl https://api.zopyr.com/v1/credits \
-H "Authorization: Bearer $ZOPYR_API_KEY"
# Inspect exact token count, latency & settled cost for a generation
curl "https://api.zopyr.com/v1/generation?id=gen-0192a3b4..." \
-H "Authorization: Bearer $ZOPYR_API_KEY"Privacy & zero-retention
By default, prompts and completions are never stored. Only request timing, token counts, and a monthly-salted IP hash are recorded. Opt-in content logging can be enabled per key and is encrypted with AES-256-GCM.
Extended Endpoints (Responses, Anthropic, Embeddings, Files & Realtime WS)
In addition to /v1/chat/completions, Zopyr natively serves the OpenAI 2026 Responses API, Anthropic Messages API (Claude Code compatible), vector Embeddings, encrypted organization Files, and stateful Realtime WebSockets under one API key.
const res = await fetch('https://api.zopyr.com/v1/responses', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ZOPYR_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'openai/gpt-6.1-sol-pro',
instructions: 'Return concise engineering guidance.',
input: 'Explain distributed circuit breaking in 3 bullets.',
max_output_tokens: 512,
}),
});
const data = await res.json();
console.log(data.output_text, data.usage);Error code catalog
Stable machine-readable error codes returned by the platform and inference gateway.
| Code | HTTP | Description |
|---|---|---|
| AUTH_UNAUTHENTICATED | 401 | You need to sign in to do this. |
| AUTH_FORBIDDEN | 403 | You don't have permission to do this. |
| AUTH_2FA_REQUIRED | 403 | Two-factor authentication is required for this account. |
| AUTH_STEP_UP_REQUIRED | 403 | Confirm your two-factor code to continue with this action. |
| AUTH_IP_NOT_ALLOWED | 403 | Access from your IP address is not allowed. |
| AUTH_OTP_RATE_LIMITED | 429 | Too many code requests. Try again in {retryAfter} seconds. |
| AUTH_PASSWORD_BREACHED | 400 | This password appears in a known data breach. Choose a different one. |
| AUTH_CODE_INVALID | 401 | The verification code is invalid or expired. |
| ACCOUNT_BANNED | 403 | This account has been suspended. |
| KEY_INVALID | 401 | The API key is invalid. |
| KEY_REVOKED | 401 | This API key has been revoked. |
| KEY_EXPIRED | 401 | This API key has expired. |
| KEY_IP_NOT_ALLOWED | 403 | This API key cannot be used from your IP address. |
| KEY_MODEL_NOT_ALLOWED | 403 | This API key is not allowed to use the model {model}. |
| KEY_CREDIT_LIMIT_REACHED | 402 | This API key has reached its spending limit. |
| BILLING_INSUFFICIENT_CREDITS | 402 | Not enough credits. Add credits to continue. |
| BILLING_HOLD_EXCEEDED | 402 | The response was stopped because it exceeded your available credits. |
| RATE_LIMIT_EXCEEDED | 429 | Rate limit exceeded. Try again in {retryAfter} seconds. |
| CONCURRENCY_LIMIT_EXCEEDED | 429 | Too many requests are running at the same time. Try again shortly. |
| VALIDATION_FAILED | 400 | Some fields are invalid. |
| IDEMPOTENCY_KEY_REUSED | 422 | This Idempotency-Key was already used with a different request. |
| RESOURCE_NOT_FOUND | 404 | The requested resource was not found. |
| RESOURCE_CONFLICT | 409 | This resource already exists or conflicts with another one. |
| GATEWAY_MODEL_NOT_FOUND | 404 | The model {model} does not exist. |
| GATEWAY_MODEL_UNAVAILABLE | 503 | The model {model} is temporarily unavailable. |
| GATEWAY_CONTEXT_TOO_LONG | 400 | The request is longer than the model's context window. |
| GATEWAY_PARAM_UNSUPPORTED | 400 | The parameter {param} is not supported for this request. |
| GATEWAY_NO_ENDPOINT_MATCH | 400 | No provider for this model supports all the requested features. |
| GATEWAY_UPSTREAM_ERROR | 502 | The model provider returned an error. |
| GATEWAY_UPSTREAM_TIMEOUT | 504 | The model provider did not respond in time. |
| GATEWAY_UPSTREAM_RATE_LIMITED | 429 | The model provider is rate-limiting requests. Try again shortly. |
| GATEWAY_CONTENT_FILTERED | 400 | The request was blocked by the provider's content filter. |
| GATEWAY_ALL_PROVIDERS_FAILED | 502 | All providers for this model failed. Try again shortly. |
| GATEWAY_ENDPOINT_NOT_IMPLEMENTED | 501 | This endpoint is not available yet. Use /v1/chat/completions. |
| PAYMENT_GATEWAY_UNAVAILABLE | 503 | This payment method is temporarily unavailable. |
| PAYMENT_AMOUNT_OUT_OF_RANGE | 400 | The amount must be between {min} and {max}. |
| PAYMENT_VERIFICATION_FAILED | 400 | We could not verify this payment. |
| PAYMENT_ALREADY_PROCESSED | 409 | This payment has already been processed. |
| PAYMENT_EXPIRED | 410 | This payment has expired. Start a new one. |
| PAYMENT_PHONE_REQUIRED | 400 | Verify an Iranian mobile number to use this payment method. |
| FX_RATE_UNAVAILABLE | 503 | Exchange rates are temporarily unavailable. Try again later. |
| ORG_PERMISSION_DENIED | 403 | Your role in this organization does not allow this action. |
| ORG_MEMBER_SPEND_LIMIT_REACHED | 402 | You have reached your monthly spending limit in this organization. |
| ORG_LIMIT_REACHED | 409 | You have reached the maximum number of organizations. |
| ORG_MEMBERS_LIMIT_REACHED | 409 | This organization has reached its member limit. |
| ORG_OWNER_CANNOT_LEAVE | 409 | Transfer ownership before leaving this organization. |
| ORG_INVITATION_INVALID | 410 | This invitation is invalid or has expired. |
| INTERNAL_ERROR | 500 | Something went wrong on our side. Please try again. |
| SERVICE_UNAVAILABLE | 503 | The service is temporarily unavailable. Please try again shortly. |