Cora AI Gateway Documentation

Documentation

Cora API Reference

A unified, OpenAI-compatible API surface across providers. Drop-in for existing SDKs.

Quick Start

  1. Generate an API key from your API Keys page.
  2. Make your first request:
curl
curl -X POST https://api.corax.live/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-haiku-4-5-20251001",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Authentication

Pass your API key in the Authorization header:

http
Authorization: Bearer YOUR_API_KEY

Never expose keys in client-side code. Rotate compromised keys immediately from the dashboard.

Endpoints

POST/v1/chat/completions
json
{
  "model": "claude-haiku-4-5-20251001",
  "messages": [{"role": "user", "content": "Hello"}],
  "smart_routing": false,
  "temperature": 0.7,
  "max_tokens": 1000,
  "stream": false
}

Response (truncated):

json
{
  "id": "chatcmpl_abc",
  "model": "smart-routing",
  "choices": [{"index":0,"message":{"role":"assistant","content":"Hi!"}}],
  "usage": {"prompt_tokens":10,"completion_tokens":5,"total_tokens":15},
  "cora": {"model_used":"smart-routing","smart_routing_enabled":true,"routing_savings_percent":"62.0%","billed_usd":"0.000035","credits_remaining":"9.98"}
}
POST/v1/images/generations

OpenAI-compatible image generation (synchronous). Same Bearer key as chat.

curl
curl -X POST https://api.corax.live/v1/images/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "a red panda coding at a desk, studio lighting",
    "n": 1,
    "size": "1024x1024",
    "response_format": "url"
  }'

Request body:

json
{
  "model": "gpt-image-2",
  "prompt": "a red panda coding at a desk, studio lighting",
  "n": 1,
  "size": "1024x1024",
  "response_format": "url"
}

Fields: prompt (required) · model default gpt-image-2 · n 1–4 · size 1024x1024 (default), 1024x1536, 1536x1024 · response_format url (default) or b64_json.

json
{
  "created": 1718323200,
  "data": [{ "url": "https://..." }],
  "cora": { "billed_usd": "0.0420", "credits_remaining": "9.92" }
}
POST/v1/videos/generations

Async video generation — submit a job, then poll. Same Bearer key.

curl
curl -X POST https://api.corax.live/v1/videos/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.0",
    "prompt": "drone shot over a misty mountain valley at sunrise",
    "duration": 5,
    "aspect_ratio": "16:9",
    "resolution": "1080p"
  }'

Request body:

json
{
  "model": "seedance-2.0",
  "prompt": "drone shot over a misty mountain valley at sunrise",
  "duration": 5,
  "aspect_ratio": "16:9",
  "resolution": "1080p"
}

Fields: prompt (required) · model default seedance-2.0 (also seedance-2.0-fast) · duration seconds (default 5) · aspect_ratio 16:9 (default), 9:16, 1:1 · resolution 480p, 720p, 1080p (default). Submit returns a job id:

json
{ "id": "vid_abc123", "status": "queued" }
GET/v1/videos/generations/{id}

Poll until status is done (url present) or failed. Billed once on completion — failed jobs are never charged. The finished video is auto-deleted after ~24h, so download it to keep.

curl
curl https://api.corax.live/v1/videos/generations/vid_abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{ "id": "vid_abc123", "status": "done", "url": "https://..." }
GET/v1/health
json
{ "status": "ok", "uptime_s": 1284921, "models": 12 }

Available Models

Set the model field to anyModel ID below to pick which LLM runs. An explicitly requested model is used exactly as specified — even when Smart Routing is enabled. Omit model (or send "model": "auto") to let Smart Routing choose for you.

curl
curl -X POST https://api.corax.live/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-4-6",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

This list is the live catalogue from GET /v1/models — only models the gateway currently serves, with retail prices per 1M tokens. The cora.model_used field in every response shows what served the call — your model, or “smart-routing” when the router chose.

Model IDProviderInput/MOutput/M
gpt-4o-miniOpenAI$0.15$0.60
DeepSeek-V4-FlashDeepSeek$0.17$0.34
glm-5.1Z.AI$0.19$0.78
glm-5.2Z.AI$0.26$0.91
deepseek-v3.2DeepSeek$0.34$0.51
gemini-3.1-flash-image-previewGoogle$0.50$60.00
gpt-5.4-miniOpenAI$0.75$4.50
claude-haiku-4-5Anthropic$1.00$5.00
claude-haiku-4-5-20251001Anthropic$1.00$5.00
gpt-5.6-lunaOpenAI$1.13$6.80
kimi-k2.7-codeOther$1.17$4.86
gemini-3.5-flashGoogle$1.50$9.00
gemini-3-pro-image-previewGoogle$2.00$120.00
gemini-3.1-pro-previewGoogle$2.00$12.00
deepseek-v4-proDeepSeek$2.05$4.10
gpt-5.4OpenAI$2.50$15.00
gpt-5.4-xhighOpenAI$2.50$15.00
gpt-5.4-highOpenAI$2.50$15.00
gpt-5.6-terraOpenAI$2.83$17.00
claude-sonnet-4-6-highAnthropic$3.00$15.00
claude-sonnet-4-5Anthropic$3.00$15.00
claude-sonnet-4-6Anthropic$3.00$15.00
claude-sonnet-5Anthropic$3.40$17.00
kimi-k3Other$3.60$18.00
gpt-5.5-highOpenAI$5.00$30.00
claude-opus-4-5Anthropic$5.00$25.00
claude-opus-4-8Anthropic$5.00$25.00
claude-opus-4-7-maxAnthropic$5.00$25.00
claude-opus-4-6-maxAnthropic$5.00$25.00
gpt-5.5-xhighOpenAI$5.00$30.00
claude-opus-4-7Anthropic$5.00$25.00
claude-opus-4-6Anthropic$5.00$25.00
gpt-5.5OpenAI$5.00$30.00
gpt-5.6-solOpenAI$5.67$34.00
claude-fable-5Anthropic$11.33$56.67

Smart Routing

The Smart Routing switch in your dashboard decides who picks the model. ON (the default) — Cora picks, and may serve a cheaper model than the one you named, never a more expensive one. OFF — you pick, by naming a model; we run exactly that and tell you what routing would have saved.

If you don't name a model at all (or send "model": "auto"), Cora picks the cheapest model that fits — switch on or off. Off means we won't override a model you chose; it doesn't mean we'll refuse when you haven't chosen one. To pin a model for a whole project without naming it on every call, set a default model on the API key.

When routing does apply, Cora reads the whole request — the task, the conversation, your attachments, tools, response_format and max_tokens — works out the capability it needs, then serves the cheapest model that clears that bar and can hold your context. Two guarantees: we never bill you above the model you asked for, and if a cheaper substitute returns a broken answer (empty, or invalid JSON when you asked for JSON) we re-run it on your model at our cost, not yours.

Override it per call with smart_routing, or per project on the API key — one app has many LLM calls, and they don't all want the same thing:

  • • "pin" — your model always runs. Routing applies only when you don't name one.
  • • "save" — we may substitute a cheaper model from the same provider, never a more expensive one.
  • • "max" — cross-provider substitution allowed. Biggest savings on bulk work (extraction, classification, translation).
  • • false / "off" — routing off entirely, no advisory.

Can't add fields to the request body? Send the header X-Cora-Smart-Routing: save instead (body wins if you send both). "quality_floor": 2 — or X-Cora-Quality-Floor — sets a minimum capability tier (0 nano → 3 frontier). Your org-wide default lives in Portal → Settings.

Pinned a model on a call that didn't need it? The response carries cora.routing_hint with what routing would have saved on that exact call — so you can enable it where it pays and leave it off where it doesn't.

Every response reports what happened under cora: model_used, routing_decision, routing_reason, task_detected and routing_savings_usd. Savings are measured against the model you asked for — delegate the choice and savings read 0, because there's nothing to compare against.

When Cora picks the model, the response's model reads smart-routing and your usage bills under Smart Routing as a single line — you're buying a capability tier, not a specific vendor, and we reprice and re-source underneath it. Pin a model (or use "smart_routing": "pin") whenever you need a named model echoed back.

Error Handling

401Invalid API key
402Insufficient credits
429Rate limit exceeded
500Internal gateway error
503Upstream provider unavailable
json
{ "error": { "code": "rate_limit_exceeded", "message": "Too many requests" } }

Rate Limits

100
Per minute
1,000
Per hour
10,000
Per day