JTRouterJTRouter beta/ DocsSign in
Docs

One endpoint. Every model.

Open dashboard

Introduction

JTRouter is a unified AI gateway that exposes a single OpenAI-compatible endpoint for every major language model. You write one integration — we handle model selection, fallback, and billing. No additional SDKs, no per-provider auth flows, no version drift.

The API is a strict superset of the OpenAI Chat Completions format. Any existing code that calls OpenAI can point at JTRouter with two changes: swap the base URL and add your JTRouter key.

Base URL
https://api.jtrouter.io/v1

Quickstart

Grab your API key from the Keys dashboard and send your first request. Set model to auto to let JTRouter pick the optimal model automatically.

POST /v1/chat/completions — auto routing
curl https://api.jtrouter.io/v1/chat/completions \
  -H "Authorization: Bearer $JTROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [
      { "role": "user", "content": "Explain monads in plain English." }
    ]
  }'

The response is identical to the OpenAI format, with a few extra headers that tell you which model was selected, the actual latency, and the exact cost charged.

Response headers
HTTP/2 200
x-jt-model: claude-sonnet-4-6
x-jt-route: quality
x-jt-latency-ms: 1124
x-jt-cost-usd: 0.00031
x-jt-fallback: false

Authentication

All requests must include a bearer token in the Authorization header. Keys are prefixed jtk_ and are scoped to your workspace. You can create multiple keys with different rate limits and permission scopes from the dashboard.

Security note

Never expose your API key in frontend code or public repositories. Use environment variables or a secrets manager. Keys can be rotated instantly from the dashboard without downtime.

Routing

When model is set to auto, JTRouter scores every available model against four dimensions — quality, latency, cost, and context fit — then routes to the highest scorer above your configured quality floor. Scoring runs in under 2 ms and is invisible to callers.

You can bias the routing strategy with the x-jt-route request header:

qualityMaximise output quality regardless of cost.
costMinimise cost per token while meeting quality floor.
latencyMinimise time-to-first-token.
balancedDefault. Weighted blend of all three.
Bias towards low latency
curl https://api.jtrouter.io/v1/chat/completions \
  -H "Authorization: Bearer $JTROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "x-jt-route: latency" \
  -d '{
    "model": "auto",
    "messages": [{ "role": "user", "content": "Hello" }]
  }'

Fallback

If the selected model returns a non-200 status, JTRouter automatically retries with the next-best candidate from the scoring list. This happens synchronously — from your perspective the request either succeeds or returns a single error after all candidates are exhausted. The x-jt-fallback response header indicates whether a fallback occurred.

Fallback behaviour
  • Up to 3 automatic retries across different providers.
  • Billing reflects the model that ultimately responded.
  • Fallback events are logged in your request history.
  • Set x-jt-no-fallback: true to disable and surface the raw error.

Models

Pass any JTRouter alias as the model field to pin a specific model. The full list — with live availability, context windows, and per-token pricing — is always up to date in the Models catalogue.

AliasVendorNotes
autoJTRouterDynamic — best model for the prompt
claude-sonnetAnthropicBalanced quality / cost
claude-opusAnthropicHighest quality
gpt-5OpenAIStrong coding & function calling
gemini-proGoogleLong context window
deepseek-r1DeepSeekCheapest reasoning model

To pin to Claude Sonnet specifically, replace auto with claude-sonnet:

Pin a model
curl https://api.jtrouter.io/v1/chat/completions \
  -H "Authorization: Bearer $JTROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet",
    "messages": [
      { "role": "user", "content": "Write a unit test for this function." }
    ]
  }'

Errors

JTRouter uses standard HTTP status codes. All errors return a JSON body with error.code, error.message, and an optional error.param field identifying the offending input field.

StatusNameDescription
401UnauthorizedMissing or invalid API key.
429Rate limitedToo many requests. Back off and retry.
503No routeAll candidate models are unavailable. Rare.
400Bad requestMalformed JSON or missing required fields.

Ready to integrate?

Get your API key and make your first request in under two minutes.