API Reference

The Neural Router API

An OpenAI-compatible REST API. Point an existing OpenAI SDK at the base URL below, then use a routing alias or the X-NR-* headers to control model selection.

Overview

All requests are made over HTTPS to:

Base URL
https://api.neuralrouter.ai/v1

Requests and responses follow the OpenAI Chat Completions schema exactly, the body is unmodified, so existing OpenAI client libraries work by setting only the base URL and API key.

Routing is controlled two ways, neither of which changes the request body: the model field accepts a routing alias, and optional X-NR-* request headers override behaviour per call. Every response carries X-NR-* headers describing the decision. See Routing headers.

Authentication

Pass your workspace key as a bearer token. Keys are prefixed sk-nr- and scoped to one workspace.

Header
Authorization: Bearer sk-nr-xxxxxxxxxxxxxxxxxxxx

Chat completions

POST/v1/chat/completions

Generate a model response for a conversation. Request parameters:

FieldTypeDescription
modelstringrequiredA concrete model id, or a routing alias: "auto", "cheapest", "fastest", or "best".
messagesarrayrequiredConversation messages in OpenAI chat format.
streambooleanoptionalStream the response as server-sent events. Defaults to false.
temperaturenumberoptionalSampling temperature, 0–2.
max_tokensintegeroptionalMaximum tokens to generate.
toolsarrayoptionalTool/function definitions, OpenAI-compatible.
response_formatobjectoptionalForce JSON output with { "type": "json_object" }.

Example request body:

Request
{
  "model": "auto",
  "messages": [
    { "role": "system", "content": "You are concise." },
    { "role": "user", "content": "Summarize routing in one line." }
  ],
  "temperature": 0.7,
  "max_tokens": 256,
  "stream": false
}

Example response:

200 OK
{
  "id": "nrc_8f2a1c...",
  "object": "chat.completion",
  "created": 1782000000,
  "model": "claude-sonnet",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Routing sends each request to the best model for your objective." },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 24, "completion_tokens": 16, "total_tokens": 40 }
}

Routing headers

Routing is controlled with optional request headers, so the request body stays byte-for-byte OpenAI-compatible and any OpenAI SDK can send them without a schema override.

FieldTypeDescription
X-NR-PinstringoptionalForce one catalog model, bypassing policy selection. Equivalent to naming a concrete model in `model`, and takes precedence over X-NR-Allow. An unknown id returns 404.
X-NR-AllowstringoptionalComma-separated model ids to restrict this request's candidate set. A routing preference, not an access boundary, the enforced limit is the key's allowed models.
X-NR-ObjectivestringoptionalOverride the workspace objective for this request: lowest-cost, lowest-latency, highest-quality, or quality-per-dollar. Unrecognized values are ignored.
X-NR-PresetstringoptionalApply a saved preset. Accepts name, name@version to pin a version, or name|env to resolve an environment. A missing or stale reference is ignored rather than erroring.
X-NR-SessionstringoptionalGroup related requests into one session for cache and routing affinity. Echoed back on the response.
X-NR-ZDRstringoptionalSet to "true" to restrict routing to providers under a zero-retention agreement.
X-NR-RegionstringoptionalCaller region hint. Honored only as a fallback when the edge cannot derive a region, since a client-supplied value is spoofable.

Alternatively, set the model field to a routing alias instead of a concrete id: auto defers to your workspace policy, cheapest selects on lowest cost, fastest on lowest time-to-first-token, and best on highest quality. Any other non-empty value is treated as a concrete model and pins the route.

Request headers
curl https://api.neuralrouter.ai/v1/chat/completions \
  -H "Authorization: Bearer $NEURALROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-NR-Objective: lowest-latency" \
  -H "X-NR-Allow: gpt-4o,claude-sonnet" \
  -d '{
    "model": "auto",
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'

Every response carries the routing decision:

FieldTypeDescription
X-NR-ModelstringoptionalThe model that actually served the request.
X-NR-Route-ReasonstringoptionalWhy that route was selected.
X-NR-Overhead-MsstringoptionalRouter overhead in milliseconds, excluding provider time.
X-NR-Trace-IdstringoptionalTrace id for this request; quote it in support requests.
X-NR-CachestringoptionalCache outcome. Present only when a cache was consulted.
X-NR-SessionstringoptionalThe session id the request was grouped under, your value, or one derived from the conversation prefix.
Response headers
X-NR-Model: claude-sonnet
X-NR-Route-Reason: lowest-latency within allow-list
X-NR-Overhead-Ms: 7
X-NR-Trace-Id: nrq_8f2a1c4b
X-NR-Cache: miss

Models

GET/v1/models

Returns the models available to your workspace, each with provider, pricing, context window, and live health.

Response
{
  "object": "list",
  "data": [
    {
      "id": "claude-sonnet",
      "provider": "Anthropic",
      "context_window": 200000,
      "input_per_m": 3.0,
      "output_per_m": 15.0,
      "health": "healthy"
    }
  ]
}

Embeddings

POST/v1/embeddings

Create an embedding vector for the given input, OpenAI-compatible. Routing applies the same way, set model to a specific embedding model or "auto".

Request
{
  "model": "auto",
  "input": "The quick brown fox."
}

Streaming format

When stream is true, the response is a sequence of server-sent events. Each event is a data: line carrying a chat.completion.chunk, ending with data: [DONE].

text/event-stream
data: {"choices":[{"delta":{"content":"Rou"}}]}

data: {"choices":[{"delta":{"content":"ting"}}]}

data: [DONE]

Rate limits

Rate limits are per workspace and returned on every response via x-ratelimit-remaining and x-ratelimit-reset headers. A 429 indicates you should retry after the reset window with exponential backoff. Upstream provider 429s are absorbed by failover and do not count against your limit.

Errors

Errors use standard HTTP status codes and a JSON body of the form { "error": { "type", "message" } }.

StatusTypeDescription
400invalid_requestMalformed request or missing required field.
401unauthenticatedMissing or invalid API key.
403forbiddenKey lacks access, or a guardrail blocked the request.
402budget_exceededThe workspace budget cap has been reached.
404model_not_foundRequested model id is not available to this workspace.
429rate_limitedToo many requests; retry with backoff.
503no_provider_availableAll candidates and fallbacks are unavailable.

New to the API? Start with the Documentation.