Skip to content

- API reference

API reference

One gateway for OpenAI-compatible, Anthropic-compatible, and Responses API traffic. Point your SDK at routr.cloud and keep the code you already wrote.

Connecting for the first time? Start with the application quickstart for account, balance, model selection, and first-request verification.

Quickstart

Three values get you live: an API key, the base URL, and a model id. From there it's the OpenAI surface you already know.

Connection details
The three values your existing client needs.
Base URL
https://api.routr.cloud/v1
Authentication
Authorization: Bearer $ROUTR_KEY
Model
Any id listed by /v1/models

1. Your key

Keys are created in your workspace, use the sk-user-… prefix, and travel in requests as a bearer token.

2. List models

bash
curl https://api.routr.cloud/v1/models \
  -H "Authorization: Bearer $ROUTR_KEY"

3. First completion

bash
curl https://api.routr.cloud/v1/chat/completions \
  -H "Authorization: Bearer $ROUTR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek-v4-pro",
  "messages": [
    { "role": "user", "content": "Explain PKCE in two sentences." }
  ]
}'

Authentication

Pass your key as a bearer token in the Authorization header (OpenAI style) or in the x-api-key header (Anthropic style). Both headers are accepted on every endpoint.

http
Authorization: Bearer $ROUTR_KEY

Treat a key like a password: it proves who you are and controls your spending. Rotate it from the workspace the moment it leaks.

Endpoints

All routes hang off https://api.routr.cloud/v1. Bodies and responses are JSON; streaming endpoints switch to SSE.

MethodPathDescription
POST/v1/chat/completionsOpenAI Chat Completions: chat, tools, stream.
POST/v1/responsesOpenAI Responses API: stateless text and tools.
POST/v1/messagesAnthropic Messages API for the Claude SDK and Claude Code.
GET/v1/modelsList available customer-facing models.
GET/v1/models/{id}Retrieve one model by id.
GET/manifestPublic catalog, context, pricing, and billing formula.
GET/healthLiveness probe.
GET/health/readyReadiness probe (DB and rate card).

SDK examples

The OpenAI Python and Node SDKs connect with no code changes. Swap in the base URL and key, and your existing calls keep working.

curl
curl https://api.routr.cloud/v1/chat/completions \
  -H "Authorization: Bearer $ROUTR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek-v4-pro",
  "messages": [{ "role": "user", "content": "Hello" }]
}'

Streaming

Add "stream": true to receive the reply as SSE (text/event-stream): a series of data: events closed by data: [DONE].

curl
curl https://api.routr.cloud/v1/chat/completions \
  -H "Authorization: Bearer $ROUTR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek-v4-pro",
  "stream": true,
  "messages": [
    { "role": "user", "content": "Count 1 to 5." }
  ]
}'

The last SSE event carries usage with prompt_tokens, completion_tokens, and prompt_tokens_details.cached_tokens whenever the prompt hit the cache.

Tool calling vs browser access

Tool calling forwards your schema and relays the model's request to call a function. The gateway never runs that function: no code execution, no browser, no device access, no outbound internet on your behalf.

To give a model browser access, supply the tool yourself (a web_search or open_url function), run it in your own trusted backend or tool runner, and return the outcome as a tool message. Only execute model-supplied URLs or commands inside a sandbox behind an allowlist.

bash
curl https://api.routr.cloud/v1/chat/completions \
  -H "Authorization: Bearer $ROUTR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek-v4-pro",
  "messages": [
    { "role": "user", "content": "What is the weather in Jakarta?" }
  ],
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Get current weather for a city",
      "parameters": {
        "type": "object",
        "properties": {
          "city": { "type": "string", "description": "City name" }
        },
        "required": ["city"]
      }
    }
  }],
  "tool_choice": "auto"
}'

A model can only request tools you declared; it can't invent new ones. Chat Completions surfaces these as tool_calls, while Responses clients see a function_call item.

Responses API

/v1/responses implements the OpenAI Responses API. Prompts go in input instead of messages, and replies return an output list of text and function calls.

bash
curl https://api.routr.cloud/v1/responses \
  -H "Authorization: Bearer $ROUTR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek-v4-pro",
  "input": "Explain async/await in three sentences."
}'

Streaming (Responses)

With "stream": true the stream walks through response.created → output_text.delta → response.completed → [DONE].

bash
curl https://api.routr.cloud/v1/responses \
  -H "Authorization: Bearer $ROUTR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek-v4-pro",
  "stream": true,
  "input": "Write a haiku about servers."
}'

Anthropic Messages

/v1/messages speaks the Anthropic Messages protocol, so Claude Code and the Anthropic SDK connect unchanged. Authenticate with x-api-key and include anthropic-version.

bash
curl https://api.routr.cloud/v1/messages \
  -H "x-api-key: $ROUTR_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "deepseek-v4-pro",
  "max_tokens": 1024,
  "messages": [
    { "role": "user", "content": "Hello" }
  ]
}'

Claude Code / Anthropic SDK

bash
# Claude Code / Anthropic SDK — same base URL & key
export ANTHROPIC_BASE_URL="https://api.routr.cloud"
export ANTHROPIC_AUTH_TOKEN="$ROUTR_KEY"

# or via the SDK
#   Anthropic({ baseURL: "https://api.routr.cloud", apiKey })

Parameters

Requests pass through to the upstream unchanged, so the full OpenAI parameter set works. The fields below are the ones you'll reach for most often.

FieldTypeScopeDescription
modelstringrequiredModel id from /v1/models (e.g. deepseek-v4-pro).
messagesarraychatConversation turns: {role, content}.
inputstringresponsesPrompt text (Responses API).
streambooleanoptionalStream tokens via SSE. Default false.
max_tokensintegeroptionalMax output tokens. Default 4096.
temperaturenumberoptional0–2. Higher = more random. Default 1.
top_pnumberoptionalNucleus sampling. Default 1.
toolsarrayoptionalFunction-calling tool definitions.
tool_choicestringoptional'auto', 'none', or a specific tool.
stopstringoptionalStop sequence (up to 4).
systemstringmessagesSystem prompt (Anthropic format).
response_formatobjectoptionalJSON mode: {type: 'json_object'}.

Errors

Failures come back as { "error": { "type", "code", "message" } }. The most common codes are listed below.

HTTPCodeMeaning
400invalid_requestMalformed body or missing required field.
401invalid_api_keyMissing, malformed, or revoked key.
402insufficient_balanceBalance too low for the request. Top up to continue.
403policy_forbiddenKey scope does not include this model.
404model_not_foundModel not in the catalog, or retired.
429rate_limit_exceededRPM or concurrency limit reached. Retry with backoff.
500internal_errorGateway-side failure. Retry shortly.
502upstream_errorUpstream returned an error after retry.
503service_unavailableNo healthy upstream for this model right now.

Rate limits

Every key in an account draws from the same shared budget, so adding keys doesn't raise the ceiling.

LimitDefaultResponse
Requests per minuteper plan429 rate_limit_exceeded
Concurrencyper plan429 rate_limit_exceeded
Context windowper model400 invalid_request

Credit billing

Each completed request settles in credits. The charge is:

text
credits = max(
  ceil(
    uncached_input_tokens × multiplier
  + cached_input_tokens × multiplier × cache_weight
  + output_tokens × multiplier × output_weight × surge_multiplier
  ),
  floor_credits
)

Cached input costs cache_weight of the input rate, and output costs output_weight. A temporary surge multiplier can apply under peak load; the Models page shows current per-model rates. A floor_credits minimum applies per request, and nothing is billed when the upstream fails before returning a usable response.

Management API

Programmatic access to your account, keys, usage, and wallet. Everything is authenticated with your API key (the same Authorization: Bearer sk-ngw_… header), and responses only ever contain data from your own organization.

MethodPathDescription
GET/api/meAccount info: org_id, key details, wallet and rate limits in one call.
GET/api/me/keysList your active API keys (prefix, scopes, status).
POST/api/me/keys/rotateRotate key. The old key is revoked and the new raw key is returned once.
DELETE/api/me/keys/{id}Revoke a specific key by id.
GET/api/me/usageUsage log: recent requests with tokens, charges and outcome.
GET/api/me/usage/logsAlias for /api/me/usage.
GET/api/me/walletWallet balance: balance, reserved and available credits.
GET/api/me/pricingModel pricing: input, cache and output rates, and floors.
GET/api/me/cache-savingsCache savings: how much prompt caching saved.

A single request returns the essentials a dashboard needs: org id, the calling key's prefix, scopes, and tier, the wallet balances, and the active rate limits.

bash
curl https://api.routr.cloud/api/me \
  -H "Authorization: Bearer sk-ngw_…"

# 200 OK
{
  "org_id": "org-abc123",
  "key": {
    "id": 42,
    "prefix": "I_raqEg4",
    "scopes": ["model:*"],
    "status": "active",
    "tier": "free",
    "created_at": 1788624646,
    "expires_at": null
  },
  "wallet": {
    "wallet_id": 181,
    "balance_credits": 5000,
    "reserved_credits": 0,
    "available_credits": 5000
  },
  "limits": {
    "rpm": null,
    "tpm": null,
    "concurrency": null
  }
}

Lists the active keys on your account. The secret is never returned, only an 8-character prefix that is enough to tell your keys apart.

bash
curl https://api.routr.cloud/api/me/keys \
  -H "Authorization: Bearer sk-ngw_…"

# 200 OK
{
  "keys": [
    {
      "id": "42",
      "name": "production",
      "prefix": "I_raqEg4",
      "scopes": ["model:*"],
      "status": "active",
      "created_at": 1788624646,
      "expires_at": null,
      "last_used_at": 1788624700
    }
  ],
  "count": 1
}

Recent requests with their token counts and charges. Narrow the list with ?model= and set the page size with ?limit=50 (up to 200).

bash
curl "https://api.routr.cloud/api/me/usage/logs?limit=5" \
  -H "Authorization: Bearer sk-ngw_…"

# 200 OK
{
  "items": [
    {
      "request_id": "req_abc",
      "attempt_no": 1,
      "key_name": "production",
      "key_name_status": "snapshot",
      "model": "deepseek-v4-pro",
      "upstream_status": 200,
      "outcome": "success",
      "input_tokens": 2323,
      "output_tokens": 156,
      "cache_read_tokens": 198000,
      "charged_credits": 12.5,
      "usage_source": "actual",
      "streamed": true,
      "created_at": 1788624700
    }
  ],
  "summary": {
    "requests": 1,
    "attempts": 1,
    "charged_credits": 12.5
  },
  "next_cursor": null,
  "from": "2026-09-06T00:00:00+00:00",
  "to": "2026-10-06T00:00:00+00:00"
}

bash
curl https://api.routr.cloud/api/me/wallet \
  -H "Authorization: Bearer sk-ngw_…"

# 200 OK
{
  "wallet_id": 181,
  "balance_credits": 5000,
  "reserved_credits": 0,
  "available_credits": 5000
}

The active rate card lists each model's input, cache, and output rates plus per-request floors. Rates are credits per token. Cache costs cache_weight×input, output costs output_weight×input.

bash
curl https://api.routr.cloud/api/me/pricing \
  -H "Authorization: Bearer sk-ngw_…"

# 200 OK
{
  "billing": "credit",
  "rate_card_version": 294,
  "models": [
    {
      "id": "deepseek-v4-pro",
      "context_limit": 1000000,
      "vision": true,
      "input_rate": 2.5,
      "cache_rate": 1.25,
      "output_rate": 10,
      "min_charge_credits": 1000,
      "per_request_floor_credits": null,
      "rate_card_version": 294
    }
  ],
  "note": "Rates are credits per token. Cache costs cache_weight×input, output costs output_weight×input."
}