Skip to content

API reference

This task-oriented reference covers the routes implemented by Nexus. All examples use a placeholder key and a model returned for the authenticated key.

Common contract

  • Authentication: Authorization: Bearer <key>, x-api-key and api-key. Gemini routes also accept x-goog-api-key or ?key=.
  • Model placement: JSON body for OpenAI/Anthropic routes; {model} and an action suffix in a Gemini path; query model for Realtime.
  • Request ID: send x-request-id for correlation; Nexus returns it in the response header and local error envelope.
  • Limits: ordinary JSON routes accept up to 32 MiB; Gemini JSON up to 20 MiB; image/audio JSON up to 1 MiB; multipart image/audio up to 25 MiB.
  • Billing: successful measured usage or a compatible fixed-price response can be charged once. Missing or contradictory usage is left uncharged and is not charged later automatically.
  • Idempotency: to prevent duplicate charges on POST generation routes, send the Idempotency-Key (or X-Idempotency-Key) header. The key length must be 1 to 256 printable ASCII characters, scoped to the profile, API key, and endpoint family. Replays with identical payload return the cached response with Idempotency-Replayed: true (cache retained for 24 hours, followed by a 7-day tombstone window returning result_expired) and zero additional balance charges. See Retries and idempotency.
export NEXUS_API_KEY='replace-with-your-key'
curl https://api.nexus-hub.tech/v1/models \
  -H "Authorization: Bearer $NEXUS_API_KEY" \
  -H "x-request-id: docs-models-001"

A successful discovery response has this shape:

{"object":"list","data":[{"id":"MODEL","object":"model","created":0,"owned_by":"..."}]}

Local failures use one safe envelope across route families:

{"error":{"message":"model is not enabled for this API key","type":"nexus_error","code":"model_not_allowed","request_id":"docs-001"}}

Discovery and account

Method and path Model placement Successful response
GET /api.json none public OpenCode-compatible metadata catalog of active public models
GET /v1/models none key-visible OpenAI-style list
GET /v1/catalog none public models and verified endpoint capabilities
GET /v1/models/catalog none same public catalog as GET /v1/catalog
GET /v1/models/{model} path one visible model or model_not_found
GET /v1/balance none balance object for the key's profile
GET /v1beta/models none Gemini aliases, methods and optional token limits
GET /v1beta/openai/models none OpenAI-style Gemini model list for bridge clients
GET /v1/catalog?currency=RUB\|USD\|EUR\|CNY none public retail catalogue and price snapshot

Authenticated discovery routes are filtered by key, endpoint policy and active model access.

OpenCode metadata catalog

GET /api.json needs no API key. The public URL is https://api.nexus-hub.tech/api.json. It returns the current list of active public Nexus Hub models plus the metadata OpenCode, Delta and compatible clients use to choose a transport (@ai-sdk/anthropic, @ai-sdk/openai, or @ai-sdk/openai-compatible).

It is not a per-key access guarantee. Presence in /api.json only means the model is currently active and public in the shared Nexus Hub catalogue. Check key-specific access with authenticated GET /v1/models. Public GET /v1/catalog remains the capability and retail-price catalogue. Known text models include context and output hints plus text modalities for client discovery. Unknown limits appear as 0; this does not impose a zero request limit on Nexus.

curl https://api.nexus-hub.tech/api.json
{"opencode":{"id":"opencode","name":"Nexus Hub","npm":"@ai-sdk/openai-compatible","api":"https://api.nexus-hub.tech/v1","models":{"grok-4.6":{"id":"grok-4.6","name":"Grok 4.6","family":"grok","attachment":false,"reasoning":true,"reasoning_options":[{"type":"effort","values":["low","medium","high","xhigh"]}],"tool_call":true,"temperature":true,"modalities":{"input":["text"],"output":["text"]},"limit":{"context":500000,"output":500000},"provider":{"npm":"@ai-sdk/openai-compatible"}}}}}

Public catalog

GET /v1/catalog needs no API key and defaults to RUB. It accepts USD, EUR, and CNY with the currency query parameter. An unsupported value returns 400 with invalid_catalog_currency.

GET /v1/models/catalog is the same public catalog as GET /v1/catalog, including the optional currency query.

The response keeps the order of the active public catalogue, families, public model IDs and display names, endpoint families, billing mode, and final retail price components. It is not a per-key availability response; use authenticated GET /v1/models for that. Each money value is a decimal string with an explicit unit such as USD_per_1M_tokens or EUR_per_request. snapshot.fx_status is current, stale, or unavailable; when it is unavailable, the affected components are null rather than values incorrectly labelled as the selected currency.

{"snapshot":{"fetched_at":"2026-08-14T10:00:00Z","effective_date":"2026-08-14","fx_status":"current"},"currency":"EUR","families":[{"id":"example","models":[{"id":"MODEL","display_name":"MODEL","endpoint_families":["responses"],"prices":[{"endpoint_families":["responses"],"billing_mode":"per_token","components":{"input":{"amount":"1.250000","unit":"EUR_per_1M_tokens"},"cached_input":null,"cache_write":null,"output":{"amount":"5.000000","unit":"EUR_per_1M_tokens"},"request":null}}]}]}]}

This route is intended for the documentation table. It supports browser cache revalidation with ETag and has a short public cache lifetime.

GET /v1/catalog is a no-auth capability discovery endpoint. It includes only public model metadata and verified optional parameters; missing endpoint entries remain unknown and do not become unsupported.

Text generation

All rows below accept JSON up to 32 MiB. Use a model returned for the key.

Method and path Minimal JSON body Successful response Streaming/output control
POST /v1/chat/completions {"model":"MODEL","messages":[{"role":"user","content":"Reply OK"}],"max_completion_tokens":16} OpenAI Chat object stream: true; max_completion_tokens or max_tokens
POST /v1/completions {"model":"MODEL","prompt":"Reply OK","max_tokens":16} OpenAI completion object no stream; max_tokens
POST /v1/responses {"model":"MODEL","input":"Reply OK","max_output_tokens":16} Responses object stream: true; max_output_tokens
POST /v1/responses/compact {"model":"MODEL","input":"Reply OK","max_output_tokens":16} compact Responses object stream: true; max_output_tokens
POST /v1/messages {"model":"MODEL","max_tokens":16,"messages":[{"role":"user","content":"Reply OK"}]} Anthropic Messages object stream: true; positive max_tokens required
POST /v1/messages/count_tokens {"model":"MODEL","messages":[{"role":"user","content":"Reply OK"}]} {"input_tokens":...} no charge and no stream

Send anthropic-version: 2023-06-01 on both Messages routes. JSON streaming uses protocol-native SSE terminal events; a non-streaming request returns one JSON object. /v1/completions accepts only a string prompt: batch and token-ID prompts return unsupported_prompt_shape.

Minimal Responses request:

curl https://api.nexus-hub.tech/v1/responses \
  -H "Authorization: Bearer $NEXUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"MODEL_FROM_V1_MODELS","input":"Reply exactly OK.","max_output_tokens":16}'

Minimal Messages request:

curl https://api.nexus-hub.tech/v1/messages \
  -H "x-api-key: $NEXUS_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"model":"MODEL_FROM_V1_MODELS","max_tokens":16,"messages":[{"role":"user","content":"Reply exactly OK."}]}'

Embeddings, ranking and moderation

These JSON routes accept up to 32 MiB and do not stream.

Method and path Minimal JSON body Successful response
POST /v1/embeddings {"model":"MODEL","input":"Reply OK"} embedding list
POST /v1/rerank {"model":"MODEL","query":"OK","documents":["OK"],"top_n":1} ranked results
POST /v1/moderations {"model":"MODEL","input":"Reply OK"} moderation results

The key must have access to the endpoint family and model.

Images and audio

Method and path Minimal request fields Limit and successful response
POST /v1/images/generations JSON: model, prompt 1 MiB; JSON image result
POST /v1/images/edits multipart: model, image, prompt 25 MiB; JSON image result
POST /v1/images/variations multipart: model, image 25 MiB; JSON image result
POST /v1/audio/speech JSON: model, input, voice 1 MiB; binary audio
POST /v1/audio/transcriptions multipart: model, file 25 MiB; JSON transcript
POST /v1/audio/translations multipart: model, file 25 MiB; JSON translation

Media routes do not stream. A wrong content type returns unsupported_content_type; an oversized body returns payload_too_large.

Gemini-compatible actions

The path is POST /v1beta/models/{model}:{action}. All action bodies accept up to 20 MiB. The model is in the path; if a body also contains model, it must match.

Action Minimal request shape Response/stream and output control
generateContent contents; optional generationConfig JSON; generationConfig.maxOutputTokens
streamGenerateContent same SSE chunks, terminal [DONE]; same output field
countTokens contents {"totalTokens":...}; no charge and no stream
embedContent content one JSON embedding; no stream
batchEmbedContents requests[] JSON embeddings; no stream
curl "https://api.nexus-hub.tech/v1beta/models/MODEL:generateContent" \
  -H "x-goog-api-key: $NEXUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents":[{"role":"user","parts":[{"text":"Reply exactly OK."}]}],"generationConfig":{"maxOutputTokens":16}}'

countTokens is a preflight operation and does not change the balance. embedContent accepts one content; batchEmbedContents accepts a requests array.

Body-size limits and output-token limits are separate. When Nexus has an explicit output limit for a model, a larger max_tokens, max_completion_tokens, max_output_tokens or Gemini generationConfig.maxOutputTokens is rejected with invalid_request_error. Gemini discovery exposes outputTokenLimit when that metadata is configured; an omitted value does not create a hidden default.

Realtime WebSocket

Connect to wss://api.nexus-hub.tech/v1/realtime?model=MODEL_FROM_V1_MODELS and send the key as Authorization: Bearer or x-api-key during the handshake. The query model is fixed for the session; a message attempting to switch it is rejected. Text, binary, ping, pong and close frames are proxied. Output limits inside protocol messages are forwarded unchanged.

Errors and retries

Common codes are invalid_key, model_not_found, model_not_allowed, endpoint_not_allowed, insufficient_balance, streaming_not_supported, unsupported_content_type, payload_too_large, upstream_error, upstream_timeout, pricing_unavailable, duplicate_request_id, invalid_idempotency_key, idempotency_conflict, idempotency_in_progress, result_expired, as well as 429 rate/concurrency limit codes and 503 capacity codes (provider_capacity_exceeded, etc.). Both 429 and 503 include a Retry-After header. On network timeouts and disconnections, safely retry using the Idempotency-Key header. See Errors and support and Retries and idempotency.