Gateway API reference
A single REST API for image, video, audio and chat models across fal.ai, Replicate, WaveSpeedAI, KIE AI, APIMart, EvoLink, AtlasCloud, Vercel AI Gateway and OpenRouter.
Base URL: https://01router.com/api/v1
Authentication
Send your API key as a Bearer token. Requests are billed to the key owner's credits. Get an API key
Authorization: Bearer sk_xxxxxxxxxxxxxxxxEndpoints
| Method | Path | Description |
|---|---|---|
| POST | /generations | Create a generation (charges credits) |
| GET | /generations/{id} | Get a generation; polls the provider while running |
| GET | /generations | List your generations (page, pageSize) |
| POST | /generations/{id}/cancel | Cancel a running generation (credits refunded) |
| POST | /images/generations | OpenAI-compatible image generation (waits for the result) |
| POST | /chat/completions | Chat completion (OpenAI-compatible, stream or not) |
| POST | /quote | Price a request on every provider (no charge, no key needed) |
| GET | /models | List models with parameters and prices (?type=video|image|audio|chat) |
| GET | /models/{slug} | Get one model |
| GET | /providers | List providers and the models they serve |
Create a generation
Pass the model id, its unified input parameters and optionally a provider slug. The response returns immediately with the task id; image models on synchronous providers may already be succeeded.
curl https://01router.com/api/v1/generations \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"provider": "fal", // optional: omit to auto-route
"input": {
"prompt": "A red fox running through fresh snow, cinematic",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9",
"generate_audio": true
}
}'{
"id": "gen_6f1c…",
"object": "generation",
"model": "seedance-2.5",
"type": "video",
"provider": "kie",
"status": "processing", // queued | processing | succeeded | failed
"input": { "prompt": "…", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true },
"outputs": [],
"error": null,
"credits": 512,
"price_usd": 2.0475,
"created_at": "2026-10-23T08:00:00.000Z",
"completed_at": null
}Get the result
Poll every few seconds until status is succeeded or failed. Output URLs are provider-hosted and may expire — download them promptly. Or pass callback_url to get the result pushed.
curl https://01router.com/api/v1/generations/gen_6f1c… -H "Authorization: Bearer $API_KEY"
{ "id": "gen_6f1c…", "status": "succeeded", "outputs": ["https://…/video.mp4"], … }Callbacks
Add callback_url (public https) and we POST the final generation object to it once the task succeeds or fails, retrying up to 5 times with backoff, so you don't need to poll.
curl https://01router.com/api/v1/generations \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"input": { "prompt": "A red fox running through fresh snow" },
"callback_url": "https://your-app.com/webhooks/generation"
}'Each callback carries X-Gateway-Timestamp and X-Gateway-Signature: sha256=HMAC-SHA256(your API key, timestamp + "." + raw body). Verify it, or simply re-fetch GET /generations/:id.
// Node.js: verify X-Gateway-Signature
import { createHmac, timingSafeEqual } from 'crypto';
const ts = req.headers['x-gateway-timestamp'];
const expected = 'sha256=' + createHmac('sha256', process.env.API_KEY)
.update(`${ts}.${rawBody}`).digest('hex');
const ok = timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers['x-gateway-signature']));Cancel a task
POST /generations/:id/cancel asks the provider to stop a running task. Once the provider confirms, the task ends as failed with error "Canceled by user" and its credits are refunded. Supported on fal (while still queued) and Replicate; other providers, or tasks already finished, answer 409 not_cancelable.
curl -X POST https://01router.com/api/v1/generations/gen_6f1c…/cancel -H "Authorization: Bearer $API_KEY"
{ "id": "gen_6f1c…", "status": "failed", "error": "Canceled by user", "credits": 0, … }OpenAI-compatible images
POST /images/generations accepts the OpenAI images API, so the OpenAI SDKs, LobeChat, Cherry Studio, Dify and n8n can use every image model here. size maps to the closest aspect_ratio, n to num_images, and any model parameter can be passed as an extra field. It waits up to ~110s; a slower task returns 504 with its id to poll.
from openai import OpenAI
client = OpenAI(base_url="https://01router.com/api/v1", api_key="sk_…")
res = client.images.generate(
model="nano-banana-pro",
prompt="A minimalist poster of a paper crane",
size="1024x1536", # mapped to the closest aspect_ratio
)
print(res.data[0].url)Audio models
Music (Suno) and text-to-speech (Gemini TTS) models use the same /generations flow as images and video: create a task, then poll it. Outputs are audio file URLs.
curl https://01router.com/api/v1/generations \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": { "prompt": "Welcome back, let us get started.", "voice": "Kore", "style_instructions": "warm and upbeat" }
}'
{ "id": "gen_9a2d…", "type": "audio", "status": "succeeded", "outputs": ["https://…/speech.wav"], … }Chat completions
Chat models (GPT, Claude, Gemini, Grok, DeepSeek…) use the OpenAI Chat Completions format, so the official OpenAI SDKs work with base URL https://01router.com/api/v1. Set "stream": true for server-sent events. Credits for the prompt plus max_tokens (4,096 when unset) are held first, then settled to the real token usage once the reply ends; the same request id appears in the X-Gateway-Request-Id header and the task log.
curl https://01router.com/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-5.5",
"messages": [{ "role": "user", "content": "Write a haiku about routers" }],
"max_tokens": 512,
"stream": true
}'from openai import OpenAI
client = OpenAI(base_url="https://01router.com/api/v1", api_key="sk_…")
res = client.chat.completions.create(
model="gpt-6-sol",
messages=[{"role": "user", "content": "Hello!"}],
)
print(res.choices[0].message.content, res.usage)Provider routing
Without provider we validate the input against every provider's supported values, price it, and submit to the cheapest one. If submission fails we refund and try the next provider (up to 3). With provider the request goes only there.
Automatic circuit breaker: a provider that fails 5 submissions in a row for a model is moved to the back of the line for 5 minutes, so requests go to healthy providers first. It still serves as the last fallback, and one success restores it.
Quote
Same body as creating a generation. Returns every available provider sorted by price, plus the ones that cannot serve the request and why.
curl https://01router.com/api/v1/quote -H "Content-Type: application/json" \
-d '{ "model": "nano-banana-pro", "input": { "prompt": "poster", "resolution": "2K" } }'
{
"model": "nano-banana-pro",
"providers": [
{ "provider": "kie", "provider_name": "KIE AI", "unit": "image", "quantity": 1, "price_usd": 0.117, "credits": 30 },
{ "provider": "openrouter", … }
],
"unavailable": [{ "provider": "atlascloud", "reason": "resolution must be one of 1K, 2K" }]
}Billing
Credits are charged when the task is submitted, based on the chosen provider's price for your parameters (per second of video, per image or per request). Failed or timed-out tasks are refunded automatically.
Errors
{ "error": { "message": "Insufficient credits: this request costs 512 credits", "code": "insufficient_credits" } }| 400 | invalid_request | Invalid body or parameter value |
| 401 | unauthorized | Missing or invalid API key |
| 402 | insufficient_credits | Not enough credits |
| 404 | not_found | Unknown model or generation |
| 409 | not_cancelable | The task cannot be canceled (already finished, or the provider does not support canceling) |
| 429 | rate_limited | Too many requests — retry after the given seconds |
| 429 | concurrency_limit | Too many tasks running for this API key; wait for some to finish |
| 502 | upstream_error | Every provider rejected the task (credits refunded) |
| 503 | no_provider | No provider supports these parameters |
| 504 | timeout | Image is still generating after the wait; poll GET /generations/:id |
All model ids and parameters: Models