Cirrela API and MCP

Make videos and images from your own code, or let Claude and ChatGPT make them for you. Same models, same prices and same refunds as the studio.

REST and JSON, versioned under /v1 · An MCP server for Claude, ChatGPT and agents · Included with the Studio plan

Quickstart

  1. Create a key in Settings, under API and MCP (Studio plan).
  2. Start a video. The answer comes at once, with an id and status: queued.
  3. Ask for it until status is completed, then download outputs[0].url.
POST /v1/generations
curl https://cirrela.com/api/v1/generations \
  -H "Authorization: Bearer $CIRRELA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: fox-snow-001" \
  -d '{
    "prompt": "A red fox running through fresh snow at sunrise",
    "tier": "great",
    "aspect_ratio": "9:16",
    "duration": 5
  }'
GET /v1/generations/:id
curl https://cirrela.com/api/v1/generations/GENERATION_ID \
  -H "Authorization: Bearer $CIRRELA_API_KEY"

A video takes about 1 to 3 minutes, an image about 20 seconds. A render that fails is refunded automatically.

Authentication

Send your key in the Authorization header on every request. Keys start with cir_live_ and are shown once, when you create them. Keep them on a server: anyone with a key can spend your credits.

Authorization: Bearer cir_live_your_key

Revoke a key in Settings and it stops at once. Keys also stop while the account isn't on Studio or is suspended, and work again when it is back on Studio.

Base URL https://cirrela.com/api/v1

Make a video or an image

POST /v1/generations takes JSON. Only prompt is required: the rest starts from the tier's settings, like in the studio.

FieldWhat it does
typevideo (default) or image.
promptWhat to make, 3 to 4,000 characters. @handles use your saved characters. Required.
tierquick, great (default) or cinema: the studio's quality levels.
modelA model id from GET /v1/models, instead of a tier.
durationSeconds, from the model's durations.
aspect_ratio16:9, 9:16, 1:1… from the model's aspect_ratios.
resolutionOne of the model's resolutions your plan includes.
soundSound on or off, on models with a switch.
num_imagesImages per request, up to the model's max_images.
image, image_idA start image: base64 in the body (a data: URL works), or the id POST /v1/uploads returned.
end_image, end_image_idAn end image, on models with accepts_end_image.
photo_consentRequired with an image: true confirms you have the right to use it and the people in it agree.
publicShare it in the public Examples feed. Default false.
max_creditsRefuse instead of spending more than this many credits.

Send an Idempotency-Key header (a unique string of up to 255 characters) to retry safely: the same key and body give back the same creation for 24 hours, without charging twice. The same key with another body is refused with 409.

Every request goes through the studio's own checks: the price is taken when the render starts and given back if it fails, the prompt filter applies, and so do your plan's limits (renders at once, renders a day, resolution). Files carry AI-generated metadata.

Endpoints

GET/v1/me

Your plan, credit balance and limits.

curl https://cirrela.com/api/v1/me -H "Authorization: Bearer $CIRRELA_API_KEY"
Response
{
  "object": "account",
  "plan": "studio",
  "credits": 3170,
  "rendering": 1,
  "limits": { "parallel_renders": 8, "renders_per_day": 1500, "max_video_resolution": "4K", … }
}

GET/v1/models

The quality tiers and every model, with their options and prices in credits for your plan.

curl https://cirrela.com/api/v1/models -H "Authorization: Bearer $CIRRELA_API_KEY"

POST/v1/estimates

The exact price of a request, spending nothing. Same body as POST /v1/generations.

curl https://cirrela.com/api/v1/estimates \
  -H "Authorization: Bearer $CIRRELA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "prompt": "A lighthouse in a storm", "tier": "cinema", "duration": 10 }'
Response
{ "object": "estimate", "credits": 200, "balance": 3170, "affordable": true, … }

POST/v1/generations

Starts a render and takes its credits. Answers 201 with the creation, status: queued.

curl https://cirrela.com/api/v1/generations \
  -H "Authorization: Bearer $CIRRELA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: fox-snow-001" \
  -d '{
    "prompt": "A red fox running through fresh snow at sunrise",
    "tier": "great",
    "aspect_ratio": "9:16",
    "duration": 5
  }'
Response
{
  "id": "j57a8m3f0k2x9q1r4t6v",
  "object": "generation",
  "type": "video",
  "status": "queued",
  "progress": 0,
  "model": "minimax-h3",
  "tier": "great",
  "prompt": "A red fox running through fresh snow at sunrise",
  "settings": { "aspect_ratio": "9:16", "duration": 5, "sound": true, "resolution": "768P" },
  "credits": 30,
  "refunded": false,
  "outputs": [],
  "error": null,
  "public": false,
  "share_url": null,
  "ai_generated": true,
  "created_at": "2026-10-24T09:12:03.000Z",
  "completed_at": null
}

GET/v1/generations/:id

One of your creations: status (queued, running, completed, failed), progress from 0 to 1, and outputs once completed.

curl https://cirrela.com/api/v1/generations/GENERATION_ID \
  -H "Authorization: Bearer $CIRRELA_API_KEY"
Response
{
  "id": "j57a8m3f0k2x9q1r4t6v",
  "status": "completed",
  "progress": 1,
  "outputs": [{ "url": "https://…/video.mp4", "width": 720, "height": 1280 }],
  …
}

GET/v1/generations

Your creations, newest first. limit (1 to 60, default 20), cursor (the next_cursor of the previous page), type (video or image).

curl "https://cirrela.com/api/v1/generations?limit=20&type=video" -H "Authorization: Bearer $CIRRELA_API_KEY"
Response
{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "…" }

POST/v1/uploads

Sends a start or end image (JPEG, PNG or WebP, under 10 MB) as the raw body, and answers with an id for image_id. Uploads no render uses are deleted after a day.

curl https://cirrela.com/api/v1/uploads \
  -H "Authorization: Bearer $CIRRELA_API_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg
Response
{ "id": "kg2…", "object": "upload" }

Errors

Errors are JSON with a stable code. Branch on the code, not the message: messages are written for people and can change.

{
  "error": {
    "code": "insufficient_credits",
    "message": "This generation needs 100 credits — you have 42. Top up to continue.",
    "details": { "required": 100, "balance": 42 }
  }
}
StatusCodeMeaning
400invalid_request, invalid_jsonThe body or a header isn't what the endpoint expects.
401invalid_keyMissing, unknown or revoked key.
402insufficient_creditsNot enough credits. details has required and balance.
403plan_requiredThe account isn't on Studio, or the plan doesn't include that resolution.
403account_suspended, account_pausedThe account can't create right now; the message says why and until when.
404not_foundNo such endpoint, or no creation with this id on your account.
409idempotency_conflictThis Idempotency-Key was already used with a different body.
413payload_too_largeThe body or the image is too large (photos: 10 MB).
415unsupported_media_typeThe image isn't a JPEG, PNG or WebP.
422validation_errorA field is invalid: param names it, the message lists what the model takes.
422moderation_blockedThe prompt filter refused it. Nothing was charged.
429rate_limited, concurrency_limit, daily_limitToo many requests, renders at once, or renders today. See Retry-After.
500internal_errorSomething failed on our side. Retry a little later.

A render that fails later is not an HTTP error: GET /v1/generations/:id answers status: failed, error.message says why in plain words, and refunded is true.

Rate limits

Each key may send 120 requests a minute, and start 20 renders a minute. Your plan's limits still apply: on Studio, 8 renders at once and 1,500 a day.

Every answer carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix seconds); a 429 adds Retry-After, in seconds.

MCP server for Claude, ChatGPT and agents

With the MCP server, an AI assistant makes videos on your account. Ask Claude “make me a 9:16 video of a fox running through snow”: it checks the price, starts the render and brings back the link.

Server URL
https://cirrela.com/api/mcp

Streamable HTTP, JSON answers, no sessions. Your API key goes in the Authorization header.

Claude Code

Run this once in a terminal:

claude mcp add --transport http cirrela https://cirrela.com/api/mcp \
  --header "Authorization: Bearer cir_live_your_key"

Claude (claude.ai and the desktop app)

  1. Open Settings, then Connectors, and choose Add custom connector.
  2. Name it Cirrela and paste the server URL.
  3. Choose No sign-in. Under Request headers, add authorization with the value Bearer followed by a space and your key.

Request headers are in beta on claude.ai. On Team and Enterprise plans, an owner adds the connector for the organization.

ChatGPT, Cursor and other clients

Any client that speaks MCP over Streamable HTTP and can send a header works: give it the server URL and Authorization: Bearer <key>. For clients set up with a JSON file:

mcp.json
{
  "mcpServers": {
    "cirrela": {
      "type": "http",
      "url": "https://cirrela.com/api/mcp",
      "headers": { "Authorization": "Bearer cir_live_your_key" }
    }
  }
}

Tools

  • get_balancePlan, credit balance and limits.
  • list_modelsTiers and models, with prices in credits.
  • estimate_costThe price of a video or image, spending nothing.
  • create_videoStarts a video and takes its credits.
  • create_imageStarts one or more images.
  • get_generationStatus, progress and download links.

Protocol versions 2025-03-26 to 2025-11-25 (with initialize) and 2026-07-28 (stateless, with server/discover).

Get a key

Studio includes the API and the MCP server, with 3,200 to 12,100 credits a month.