Media generation (video, images, music)
NordRouter can generate images, video and music — with the same sk-nr-… key and the same balance as the text models. Pay per use, no tokens or packs.
How it works
Generation is asynchronous (video and music take from seconds to a couple of minutes):
- Create a task —
POST /media/generatewith a model and parameters. - Wait for the result — poll
GET /media/job/:iduntilstatusisdone. - Fetch the file — from
result_url(a link onnordrouter.com).
1. Create a task
curl https://nordrouter.com/media/generate \
-H "Authorization: Bearer sk-nr-YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "image/nano-banana-2",
"input": { "prompt": "a cozy cabin in a winter forest, watercolor", "resolution": "2K" }
}'Response:
{ "id": "beefb531-…", "model": "image/nano-banana-2", "status": "processing",
"poll": "https://nordrouter.com/media/job/beefb531-…" }2. Wait for the result
curl https://nordrouter.com/media/job/beefb531-…{ "id": "beefb531-…", "status": "done",
"result_url": "https://nordrouter.com/media/file/beefb531-…",
"cost_usd": 0.052, "error": null }status: processing → done (or failed). The finished file is at result_url.
🎵 Suno generates two tracks per task: the first is at
result_url, the second atresult_url_2(same link format). You pay per task — both tracks are included.
Webhooks (instead of polling)
Don't want to poll — pass a callback_url to POST /media/generate and we'll push the result with a POST when the task finishes:
curl https://nordrouter.com/media/generate \
-H "Authorization: Bearer sk-nr-YOUR-KEY" -H "Content-Type: application/json" \
-d '{
"model": "image/nano-banana-2",
"input": { "prompt": "…" },
"callback_url": "https://your-server.com/webhooks/nordrouter",
"callback_secret": "your-secret"
}'When the task reaches done/failed, a POST hits your callback_url with the same body as GET /media/job/:id plus an event field:
{ "event": "media.completed", "id": "beefb531-…", "status": "done",
"result_url": "https://nordrouter.com/media/file/beefb531-…", "cost_usd": 0.052, "error": null }event: media.completed or media.failed.
Verify the signature. If you set callback_secret, the X-NR-Signature header carries sha256=<hmac> — HMAC-SHA256 of the raw request body keyed by your secret. Verify it to confirm the request is from us:
import hmac, hashlib
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
assert hmac.compare_digest(expected, request.headers["X-NR-Signature"])Requirements & reliability:
callback_urlmust behttps://and a public address (internal/private IPs are rejected with 400).- Up to 4 delivery attempts with increasing backoff; respond
2xxor we'll retry. - Webhooks don't replace polling — combine them, or use
GET /media/job/:idas a fallback.
More detail
The job lifecycle, signature verification with examples, and delivery reliability — on the Jobs and webhooks page.
3. Models and pricing
GET /media/models returns available models, their parameters and a price estimate:
{ "models": [
{ "id": "image/nano-banana-2", "type": "image",
"fields": [ {"name":"prompt","type":"textarea"}, {"name":"resolution","type":"select","options":["1K","2K","4K"]} ],
"est_usd": 0.052 }
], "retention_days": 14 }Full reference
Every model with its input parameters and price — on the Media: all models & billing page.
Models
95 models are available — the always-current list with parameters and prices lives in GET /media/models. Main families:
| Type | Family | Modes | ≈ price |
|---|---|---|---|
| 🖼 Images | Nano Banana / 2 / Pro (image/nano-banana*) | text→image, edit, up to 4K | from $0.025 |
| 🖼 | Imagen 4 Fast / Ultra (image/imagen4*) | text→image | from $0.025 |
| 🖼 | GPT Image 1.5 / 2 (image/gpt-image-*) | text→image, edit, up to 4K | from $0.025 |
| 🖼 | Flux 2 Pro / Flex (image/flux2-*) | text→image, edit | from $0.03 |
| 🖼 | Seedream v4 / 4.5 / 5 Lite (image/seedream-*) | text→image, edit | from $0.04 |
| 🖼 | Ideogram v3 / Character (image/ideogram-*) | text, remix, character | from $0.02 |
| 🖼 | Qwen / Wan Image / Grok / Z-Image | text→image, edit | from $0.01 |
| 🛠 Utils | Topaz / Recraft (image/*upscale*, image/recraft-remove-bg) | upscale up to 8K, background removal | from $0.01 |
| 🎬 Video | Veo 3.1 Lite / Fast / Quality (video/veo-3.1-*) | text/image→video | from $0.19 |
| 🎬 | Kling 2.1 → 3.0 (video/kling-*) | text/image→video, motion, avatars, up to 4K & 15s | from $0.16 |
| 🎬 | Wan 2.2 → 2.7 (video/wan-*) | text/image/video→video, speech-to-video | from $0.25 |
| 🎬 | Seedance 1.5 / 2 / Fast / Mini (video/seedance-*) | text/image→video, up to 4K, audio | from $0.06 |
| 🎬 | Hailuo 02 / 2.3 (video/hailuo-*) | text/image→video | from $0.08 |
| 🎬 | HappyHorse 1.0 / 1.1 (video/happyhorse-*) | text/image/reference→video, video edit | from $0.70 |
| 🎬 | Grok Video / 1.5 (video/grok-*) | text/image→video, up to 30s | from $0.06 |
| 🎬 | Gemini Omni (video/gemini-omni) | video with audio, up to 4K | from $0.39 |
| 🗣 Avatars | Kling Avatar, OmniHuman, InfiniteTalk, Lip Sync | photo+audio→talking video | from $0.19 |
| 🎵 Music | Suno V4–V5.5 (music/suno-v5) | text/style→2 tracks | ~$0.08 |
| 🎙 Speech | ElevenLabs Turbo / Multilingual (audio/elevenlabs-*) | text→speech, vocal isolation | from $0.04 / 1000 chars |
Parameters
Parameters depend on the model — the exact list is in /media/models (the fields array: name, type, options, default). Common ones:
prompt— description (for all generative models).resolution—1K/2K/4K(images) or480p/720p/1080p/4k(video). Price depends on resolution.aspect_ratio—1:1,16:9,9:16, etc.duration— video length in seconds (most models5/10, Kling 3.0 & Wan 2.7 up to15, Grok up to30). Video is billed per second.sound/generate_audio— audio track (Kling, Seedance). Audio costs more —/media/estimateaccounts for it.mode/quality/rendering_speed— quality tier (Kling 3.0std/pro/4K, GPT Imagemedium/high, IdeogramTURBO/BALANCED/QUALITY).image— source image (edit, image→video; pass a direct link or upload via/media/upload).video_url/audio_url— source video/audio (video-edit, lip sync, avatars).- For music:
title,style,instrumental,version(V4…V5_5).
POST /media/estimate with the same model + input returns the exact price of a specific configuration before you commit.
Cost and storage
- Charged to your USD balance by the actual generation cost — the exact amount is in
cost_usdafter completion. - Failed generations (provider errors) are not charged — the reserve is refunded automatically.
- Files are kept on our servers for a limited time (see
retention_daysin/media/models) — download to keep them.