Get started
AXM API
Make videos from your code through one authenticated, asynchronous API.
AXM plans a video, writes every scene as code and renders the MP4. You send a prompt (or a web page), choose a model if you want one, then poll or get a webhook when it’s done. Every video stays editable: change one scene and only that scene renders again.
Get started
Quickstart
- Create a test key (free, rules only) and export it as
AXM_API_KEY. - Send one request. It returns at once with a video id.
- Poll
GET /videos/:iduntilstatusisdone, then downloadurl.
curl https://mcp.axm.lol/v1/videos \
-H "Authorization: Bearer $AXM_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: launch-0001" \
-d '{"prompt": "A 30 second launch video for a budgeting app", "duration": 30, "model": "astron-6"}'Get started
Authentication
Send a key as Authorization: Bearer axm_live_… to https://mcp.axm.lol/v1. Each key is shown once and stored only as a hash. Test keys (axm_test_) plan with rules, cost nothing and never export, so you can wire up a flow before spending credits.
| Scope | Allows |
|---|---|
| videos:create | Start and cancel videos |
| videos:read | Read videos and their jobs |
| projects:read | Read projects, scenes, versions, quotes and exports |
| projects:write | Create and edit projects and scenes, render previews, export |
| assets:write | Upload and delete images, video and audio |
| usage:read | Read credit usage and request logs |
Managing keys and webhooks needs a signed-in account; API keys can’t create other keys.
Get started
How the API works
- 01
queuedAccepted and charged for writing. - 02
planningThe model storyboards and writes each scene. - 03
renderingScenes render; finals are assembled. - 04
doneThe MP4 is at url. Every scene stays editable.
A failed video gives its credits back. cancelled is the fifth end state, after POST /videos/:id/cancel.
Core concepts
Make a video
One request plans the video, renders every scene and assembles the MP4. Poll the video until its status is done:
{
"id": "g_…",
"object": "video",
"status": "planning", // queued · planning · rendering · done · failed · cancelled
"stage": "storyboard",
"project": "p_…",
"mode": "studio",
"model": "astron-6", // null when AXM picked
"credits": 15,
"url": null, // the MP4 once status is "done"
"error": null
}| Field | What it does |
|---|---|
| prompt | What the video is about (up to 4,000 characters). |
| url | A public https page to turn into a video; its brand becomes a brand kit. |
| model | A model id from GET /models. Leave it out and AXM picks one for the mode. |
| mode | fast, studio (default) or cinematic. Without a model: 2, 5 or 10 credits to write. |
| duration | 6–120 seconds (default 30). |
| aspect | 16:9, 9:16, 1:1 or 4:5. |
| brand_kit, assets | A saved brand kit, and uploads or URLs to use. |
| narration, captions | A voice-over, and captions: normal, highlight, karaoke or social. |
| export | false stops at free previews. |
Core concepts
Models and pricing
Pick who writes your video with model. The model plans, writes every scene and repairs it; nothing else is swapped in. A video costs, in credits:
ceil(seconds × model credits per second) writing, when the video starts + ceil(seconds × 4) the final render, when you export
A 30-second video with Astron 6 is 15 + 120 = 135 credits, about $3.86 with Studio credits. The same video with Claude Opus 5.5 is 210 credits. Previews while you edit are free (10 a day, then 1 credit each). If the model can’t answer and the rules write the video instead, you pay the mode’s flat fee and get the rest back.
curl https://mcp.axm.lol/v1/models
# {"object": "list", "render_credits_per_second": 4, "data": [
# {"id": "astron-6", "name": "Astron 6", "credits_per_second": 0.5,
# "total_credits_per_second": 4.5, "usd_per_second": 0.1286, "available": true}, …]}| Model | id | Writing | Total / s | From |
|---|---|---|---|---|
| Astron 6.1 | astron-6.1 | 3 cr | 7 cr | $0.200 |
| Astron 6 | astron-6 | 0.5 cr | 4.5 cr | $0.129 |
| Astron 5 | astron-5 | 0.5 cr | 4.5 cr | $0.129 |
| Astron 1 | astron-1 | 0.25 cr | 4.25 cr | $0.121 |
| Zenith Flash | zenith-flash | 0.5 cr | 4.5 cr | $0.129 |
| Claude Opus 5.5 | claude-opus-5.5 | 3 cr | 7 cr | $0.200 |
| Claude Opus 5 | claude-opus-5 | 3 cr | 7 cr | $0.200 |
| Claude Opus 4.8 | claude-opus-4.8 | 3 cr | 7 cr | $0.200 |
| Claude Opus 4.7 | claude-opus-4.7 | 3 cr | 7 cr | $0.200 |
| Claude Opus 4.6 | claude-opus-4.6 | 3 cr | 7 cr | $0.200 |
| Claude Mythos Preview | claude-mythos-preview | 3 cr | 7 cr | $0.200 |
| Claude Fable 5.1 | claude-fable-5.1 | 6 cr | 10 cr | $0.286 |
| Claude Fable 5 | claude-fable-5 | 6 cr | 10 cr | $0.286 |
| Claude Sonnet 5 | claude-sonnet-5 | 1.5 cr | 5.5 cr | $0.157 |
| GPT-5.6 Sol | gpt-5.6-sol | 3 cr | 7 cr | $0.200 |
| GPT-5.6 Terra | gpt-5.6-terra | 1.5 cr | 5.5 cr | $0.157 |
| GPT-5.6 Luna | gpt-5.6-luna | 0.25 cr | 4.25 cr | $0.121 |
| GPT-5.5 Pro | gpt-5.5-pro | 3 cr | 7 cr | $0.200 |
| GPT-5.5 | gpt-5.5 | 3 cr | 7 cr | $0.200 |
| Gemini 4 Argon | gemini-4-argon | 1.5 cr | 5.5 cr | $0.157 |
| Gemini 3.1 Pro | gemini-3.1-pro | 1.5 cr | 5.5 cr | $0.157 |
| Gemini 3.7 Flash | gemini-3.7-flash | 0.5 cr | 4.5 cr | $0.129 |
| Gemini 3.6 Flash | gemini-3.6-flash | 1 cr | 5 cr | $0.143 |
| Gemma 2 2B | gemma-2-2b | 0.1 cr | 4.1 cr | $0.117 |
| Grok 4.6 | grok-4.6 | 1 cr | 5 cr | $0.143 |
| Grok 4.5 | grok-4.5 | 1 cr | 5 cr | $0.143 |
| Kimi K3 | kimi-k3 | 2 cr | 6 cr | $0.171 |
| Kimi K2.6 | kimi-k2.6 | 0.5 cr | 4.5 cr | $0.129 |
| DeepSeek V4 Pro Max | deepseek-v4-pro-max | 0.75 cr | 4.75 cr | $0.136 |
| DeepSeek V4 Pro | deepseek-v4-pro | 0.25 cr | 4.25 cr | $0.121 |
| DeepSeek V4 Flash | deepseek-v4-flash | 0.1 cr | 4.1 cr | $0.117 |
| Qwen 3.8 Max | qwen3.8-max | 0.75 cr | 4.75 cr | $0.136 |
| Qwen 3.7 Max | qwen3.7-max | 0.75 cr | 4.75 cr | $0.136 |
| Qwen 3.8 27B | qwen3.8-27b | 0.25 cr | 4.25 cr | $0.121 |
| Seed 2.1 Pro | seed-2.1-pro | 0.5 cr | 4.5 cr | $0.129 |
| Seed 2.1 Turbo | seed-2.1-turbo | 0.5 cr | 4.5 cr | $0.129 |
| Muse Spark 1.1 | muse-spark-1.1 | 0.75 cr | 4.75 cr | $0.136 |
Core concepts
Edit one scene
Every video is a project of scenes. Change a scene with a sentence, patch ops or a whole spec; the scene gets a new version and only it renders again. Exporting reuses every other scene’s final as is.
curl -X PATCH https://mcp.axm.lol/v1/projects/p_…/scenes/s_4 \
-H "Authorization: Bearer $AXM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"instruction": "make the headline shorter and use the brand green"}'Core concepts
Idempotent requests
Send Idempotency-Key (8–128 letters, digits or . _ : -) on POST /videos, /projects and /exports. For 24 hours the same key and body replays the first response with Idempotent-Replayed: true, the same key with a different body is a 422, and a key whose first request is still running is a 409.
Core concepts
Webhooks
Add an HTTPS endpoint on the Webhooks page and pick events. We POST JSON with AXM-Event, AXM-Delivery and AXM-Signature: t=…,v1=…, an HMAC-SHA256 of {t}.{raw body} with the webhook’s secret. Reply with any 2xx within 10 seconds; failures retry with backoff and redirects aren’t followed. Rotating a secret shows the new one once; for the next 24 hours each delivery carries a second v1 signed with the old one, so accept a match on any v1.
video.queuedvideo.planningvideo.renderingvideo.completedvideo.failedproject.updatedexport.completedexport.failed
import { createHmac, timingSafeEqual } from "node:crypto";
// header: AXM-Signature: t=1761480000,v1=<hex>[,v1=<hex>] (two v1 while a secret is being rotated)
export function verify(secret: string, header: string, rawBody: string): boolean {
const t = /(?:^|,)t=(\d+)/.exec(header)?.[1];
if (!t || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const want = Buffer.from(createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex"));
return [...header.matchAll(/v1=([a-f0-9]{64})/g)].some(([, v]) => {
const got = Buffer.from(v);
return want.length === got.length && timingSafeEqual(want, got);
});
}Core concepts
Errors and limits
Errors are {"error": {"code", "message"}}. Each key gets 120 requests and 10 video or export creations per minute, and an account’s keys together get twice that.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The body or a parameter is wrong, or the model id is unknown. The message says which. |
| 401 | unauthenticated | Missing, revoked or unknown key. |
| 402 | insufficient_credits | Not enough credits for this video or export. |
| 403 | forbidden / test_mode | The key lacks a scope, or a test key tried to export or generate media. |
| 404 | not_found | No such resource for this account. |
| 409 | idempotency_pending / cannot_cancel | A request with the same key is still running, or the video already finished. |
| 422 | idempotency_conflict | The Idempotency-Key was used with a different body. |
| 429 | rate_limited | Slow down. Retry-After says how many seconds. |
| 503 | model_unavailable | That model isn't live right now. Pick another, or leave model out. |
| 5xx | internal | Our side. Safe to retry GETs and requests with an Idempotency-Key. |
Reference
Endpoints
Base URL https://mcp.axm.lol/v1.
Videos and models
| Request | Scope | What it does |
|---|---|---|
| POST/videos | videos:create | Plan and render a video from a prompt or URL, optionally with a model. Returns 202 with a video to poll. |
| GET/videos | videos:read | Your recent videos, newest first. |
| GET/videos/:id | videos:read | Status, stage, progress, model, credits and the final URL. |
| POST/videos/:id/cancel | videos:create | Stop a video that is still planning or rendering. |
| GET/models | none | Every model with its price per second and whether it is live. No key needed. |
Projects and scenes
| Request | Scope | What it does |
|---|---|---|
| POST/projects | projects:write | Create a project, optionally with scenes. |
| GET/projects | projects:read | Your projects. |
| GET/projects/:id | projects:read | A project with its scenes and their render state. |
| PATCH/projects/:id | projects:write | Rename, change brand kit or settings. |
| DELETE/projects/:id | projects:write | Delete a project and its renders. |
| POST/projects/:id/scenes | projects:write | Add scenes. |
| PATCH/projects/:id/scenes/:scene | projects:write | Change one scene by spec, patch ops or an instruction. Only that scene re-renders. |
| GET/projects/:id/scenes/:scene/versions | projects:read | Every version of a scene. |
| POST/projects/:id/scenes/:scene/revert | projects:write | Make an earlier version current. |
| DELETE/projects/:id/scenes/:scene | projects:write | Remove a scene. |
| POST/projects/:id/render | projects:write | Render draft previews (free) for stale scenes. |
| GET/projects/:id/quote | projects:read | Credits an export would cost right now. |
| POST/projects/:id/exports | projects:write | Render missing finals and assemble the video. Live keys only. |
| GET/exports/:id | projects:read | Export status and the final URL. |
Brand kits and assets
| Request | Scope | What it does |
|---|---|---|
| GET/brand-kits | projects:read | Saved brand kits. |
| POST/brand-kits | projects:write | Save a brand kit (colors, fonts, logo, voice). |
| DELETE/brand-kits/:id | projects:write | Delete a brand kit. |
| POST/assets | assets:write | Upload a file (raw body with its Content-Type). Returns asset:a_… |
| GET/assets | assets:write | Your uploads. |
| DELETE/assets/:id | assets:write | Delete an upload that no render uses. |
Usage
| Request | Scope | What it does |
|---|---|---|
| GET/usage | usage:read | Balance, free previews left today and 30-day totals. |
| GET/logs | usage:read | Recent requests made with your keys. |
Reference
SDK
@axm/sdk wraps every endpoint, adds an Idempotency-Key to creates, retries 429s and 5xx safely and throws AXMError with the status and code.
import { AXM } from "@axm/sdk";
const axm = new AXM({ apiKey: process.env.AXM_API_KEY! });
const { data: models } = await axm.models.list();
const video = await axm.videos.create({ prompt: "Chart announcement: revenue up 42%", mode: "fast", model: "zenith-flash" });
const done = await axm.videos.wait(video.id);
console.log(done.url);