Developer guide

Pick a model, copy a snippet, ship.

Every endpoint below uses the model you select. Switch the dropdown and the snippets update instantly. When you're ready to try in Postman, the "Download collection" button builds a v2.1 collection pre-wired to that exact model.

Prefer to click before you code? sandbox.leanroute.dev runs the same request against three curated models — no signup, 20 free requests / day, live gateway headers surfaced next to the response.

Pick a model
anthropic/claude-sonnet-4-6anthropicflagshipglobalvisionupstream: $3.00 in / $15.00 out per 1M tokens
7 endpoints
POST/v1/chat/completions

The main routing endpoint. OpenAI-shape request, OpenAI-shape response.

curl https://api.leanroute.dev/v1/chat/completions \
  -H "authorization: Bearer gw_live_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4-6",
    "messages": [
      { "role": "user", "content": "Hello in one sentence." }
    ]
  }'
POST/v1/chat/completions • streaming

Set stream:true. SSE chunks terminated by data:[DONE]. Tool-call deltas translate across every provider.

curl https://api.leanroute.dev/v1/chat/completions \
  -H "authorization: Bearer gw_live_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4-6",
    "stream": true,
    "messages": [{ "role": "user", "content": "Count to 5." }]
  }'
POST/v1/chat/completions • tools

Standard OpenAI tools[]. The gateway translates per provider and back to OpenAI tool_calls in the response.

curl https://api.leanroute.dev/v1/chat/completions \
  -H "authorization: Bearer gw_live_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4-6",
    "messages": [{ "role": "user", "content": "Weather in SG?" }],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "parameters": { "type": "object", "properties": { "city": { "type": "string" } } }
      }
    }]
  }'
POST/v1/chat/completions • vision

OpenAI image_url content part. Accepts HTTPS URLs or data:image/* URIs. Per-provider wire translation handled upstream.

curl https://api.leanroute.dev/v1/chat/completions \
  -H "authorization: Bearer gw_live_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4-6",
    "messages": [{
      "role": "user",
      "content": [
        { "type": "text", "text": "What is in this image?" },
        { "type": "image_url", "image_url": { "url": "https://example.com/receipt.jpg" } }
      ]
    }]
  }'
POST/v1/embeddings

OpenAI-shape embeddings. Independent of the chat model selector; embedding ids are namespaced openai/text-embedding-3-*.

curl https://api.leanroute.dev/v1/embeddings \
  -H "authorization: Bearer gw_live_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "openai/text-embedding-3-small",
    "input": "the quick brown fox"
  }'
GET/v1/models

Authenticated discovery. OpenAI-shape {data:[{id,object:'model',…}]}.

curl https://api.leanroute.dev/v1/models \
  -H "authorization: Bearer gw_live_YOUR_KEY"
GET/health

Unauthenticated. Returns {ok:true, providers:{…}}. Suitable for a load-balancer health check.

curl https://api.leanroute.dev/health

Gateway-specific headers

Headers we read on the way in, and the diagnostic headers we emit on the way out. All ASCII (RFC 7230 §3.2.4 enforced by CI). Quick reference below; full docs at /docs/headers include per-header examples and JS/Python snippets.

HeaderDirectionMeaning
authorization: Bearer gw_live_*requestYour gateway API key. Required on every authenticated endpoint.
x-gateway-routing: explicitrequestDisable cheaper-model swaps for this single request, even if your org has them on.
x-gateway-credit-balance-usdresponseYour prepaid balance after the request, in USD with 6-digit precision.
x-gateway-byok: trueresponsePresent when the request was dispatched using your BYOK key for that provider.
x-gateway-failover: trueresponsePresent when the originally-routed provider returned 5xx and we transparently retried on a same-tier alternative.
x-gateway-failover-fromresponseOriginal provider name that 5xx'd. Only present when x-gateway-failover is set.
x-gateway-routed-fromresponseOriginal model id you requested, when the gateway swapped to a cheaper same-tier model. Only present with cheaper-model-swap opt-in.
x-gateway-model-deprecatedresponseOriginal model id when we auto-rewrote to its current canonical name (e.g. claude-sonnet-4.6 -> claude-sonnet-4-6).
x-gateway-prompts-persisted: falseresponsePresent when your org has flipped no-persistence mode in /dashboard/settings — prompts are not cached for this request.
x-gateway-throttle-scoperesponseOn 402 / 429: which limit fired (credit_balance, spend_cap_daily, spend_cap_monthly, rpm, tpm).

Error codes

All errors come back as { "error": { "code": "...", "message": "...", ...context } }. Codes are stable; messages may change.

HTTPCodeMeaning
400unknown_modelThe model string doesn't match any canonical id. See the dropdown above or /docs/models for the full catalog. Provider prefix (e.g. anthropic/) is required.
400bad_requestRequest body failed schema validation. The error message names the field.
400prompt_blockedA per-org guardrail blocked the prompt before dispatch. Body includes 'scope' (block | moderation) and the 'pattern' that fired (block) or 'categories' that tripped (moderation). Configure or disable in /dashboard/settings → Guardrails.
401unauthorizedMissing or revoked gateway API key. Issue a new one at /dashboard/keys.
402insufficient_creditPrepaid balance dropped below the dispatch floor. Top up at /dashboard/billing. Body includes balance_usd.
402spend_cap_exceededDaily or monthly spend cap hit. Body names which (scope=spend_cap_daily / spend_cap_monthly).
429rate_limitedRPM or TPM cap hit. Body names which scope. Retry after a moment.
503provider_not_configuredThe model routes to a provider you don't have a managed key for and don't have a BYOK key for. Add one at /dashboard/providers.
502upstream_errorThe upstream provider returned a 4xx/5xx the gateway couldn't recover from. Body includes upstream_status and a truncated upstream body.

See also: Model catalog & pricing · Integration guides · Compliance · Home