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_xxxxxxxxxxxxxxxx

Endpoints

MethodPathDescription
POST/generationsCreate a generation (charges credits)
GET/generations/{id}Get a generation; polls the provider while running
GET/generationsList your generations (page, pageSize)
POST/generations/{id}/cancelCancel a running generation (credits refunded)
POST/images/generationsOpenAI-compatible image generation (waits for the result)
POST/chat/completionsChat completion (OpenAI-compatible, stream or not)
POST/quotePrice a request on every provider (no charge, no key needed)
GET/modelsList models with parameters and prices (?type=video|image|audio|chat)
GET/models/{slug}Get one model
GET/providersList 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" } }
400invalid_requestInvalid body or parameter value
401unauthorizedMissing or invalid API key
402insufficient_creditsNot enough credits
404not_foundUnknown model or generation
409not_cancelableThe task cannot be canceled (already finished, or the provider does not support canceling)
429rate_limitedToo many requests — retry after the given seconds
429concurrency_limitToo many tasks running for this API key; wait for some to finish
502upstream_errorEvery provider rejected the task (credits refunded)
503no_providerNo provider supports these parameters
504timeoutImage is still generating after the wait; poll GET /generations/:id

All model ids and parameters: Models