REST + MCP · METERED IN CREDITS

The video-creation API for AI agents.

Open a session, converse, approve the script at the gate, get a hosted MP4 link. REST and MCP, 1:1. Metered in credits — system failures auto-refund.

Delivered link, or an automatic refund — system failures only.

animated-explainer · certified · 16:9 — a real delivered render. hold 500 → capture 308 → release 192.

OPEN → CONVERSE → GATE → DELIVER

Your agent runs the session. Every state has a name.

  1. 01 Open

    POST /v1/sessions (open_session over MCP) with a pipeline, a brief, and budget_credits. The budget is held, not spent — credits: {budget, held, spent} on every poll from here on.

  2. 02 Converse

    POST …/messages returns 202 {turn_id}; the engine researches, scripts, and stages assets while your agent polls get_session or streams events. Everything is async — there is no synchronous "give me a video" call.

  3. 03 Gate

    At status: awaiting_gate, your agent reads the artifact_excerpt (or the full artifact at GET …/artifacts/:name), then POST …/gates/:gateIdapprove, or revise with feedback. Nothing renders until the gate is resolved.

  4. 04 Deliver

    video_url appears the moment a hosted render actually exists — the dot fills. POST …/close releases the unspent hold.

If the system can't deliver, the turn auto-refunds. You don't pay for a render that fails on us.

QUICKSTART

Connect is one line. The first render is 10–30 minutes of async work. Both are true.

REST

POST /v1/sessions
curl -sX POST $BASE/v1/sessions \
  -H "authorization: Bearer $KEY" -H "content-type: application/json" \
  -H "idempotency-key: drpost-sess-42" \
  -d '{"pipeline":"animated-explainer","budget_credits":500,"format":"9:16",
       "brief":"Explain how our invoicing API works, 60s, friendly"}'
POST /v1/sessions/:id/messages
curl -sX POST $BASE/v1/sessions/$SID/messages \
  -H "authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"message":"Explain how our invoicing API works, 60s, friendly tone"}'

MCP

claude mcp add
claude mcp add --transport http macaroni \
  https://api.macaroni.video/mcp \
  --header "Authorization: Bearer $MAC_KEY"
mcpServers
{
  "mcpServers": {
    "macaroni": {
      "type": "http",
      "url": "https://api.macaroni.video/mcp",
      "headers": { "Authorization": "Bearer YOUR_API_KEY" }
    }
  }
}

Full walkthrough, failure table included

THE CONTRACT, ITEMIZED

What your agent can count on.

  • Delivery honesty

    video_url — non-null iff a playable video exists

    video_url is set if and only if a gateway-resolvable hosted MP4 exists — never a placeholder, never stale. video.ready fires only then; otherwise the turn settles no_deliverable and auto-refunds. Your agent never has to detect a dead link, because a dead link never gets a URL.

  • Sessions & gates

    A conversation with a checkpoint

    open → converse → gate → delivered link. At awaiting_gate, your agent reads the artifact_excerpt — script and scenes — and resolves the gate: approve, or revise with feedback, before a credit renders. Approvals are manual by design; your agent resolves them programmatically — the decision point is the feature.

  • Credit economics

    hold → capture → release → auto-refund

    Opening a session holds your budget; each turn captures only actual spend; close releases the rest — visible as credits: {budget, held, spent} on every poll. A system failure auto-refunds the turn: a refund entry in GET /v1/credits. Your actions — user_interrupted, budget_exceeded — bill actual spend and are not refunded. Every failure carries a failure_class; engine_error refunds automatically alongside no_deliverable.

  • Unattended by design

    Fail-closed, sandboxed, replay-safe

    Per-session model-spend caps fail closed: if the capping proxy is unavailable, turns refuse to start rather than run uncapped. Each session's engine runs in its own isolated, ephemeral sandbox — terminated on POST …/interrupt, never shared across accounts. Idempotency-Key makes every retry safe to replay. The safe default is "do nothing," never "spend freely."

  • An honest catalog

    One certified pipeline. Twelve labeled experimental.

    animated-explainer is certified for hosted delivery. The other 12 pipelines are experimental and marked as such everywhere they appear — an experimental run that finishes without a hosted video settles no_deliverable and auto-refunds. list_pipelines tells you which is which; so does this site.

  • BYOK

    Your provider keys, encrypted, never returned

    POST /v1/providers/keys stores your provider keys — AES-256-GCM at rest; byok: true on open_session runs the pipeline on them. They are never returned and never fall back to platform keys — store a key for every provider the pipeline needs or the run fails. One exception: without your own Anthropic key, the reasoning model runs metered on ours.

  • Format, self-describing

    16:9 and 9:16, certified — and the file tells you so

    Landscape for YouTube, LinkedIn, X, and embeds — or vertical for TikTok, Reels, and Shorts. Every delivered video is a hosted MP4. get_video returns width, height, and aspect_ratio, so callers route per platform without probing the file. Share links stream through the gateway, Range-seekable, and are intended to be long-lived (about a year). 9:16 vertical via format on open_session — landscape and vertical from the same session.

  • Connect in one line

    14 MCP tools, 1:1 with REST

    claude mcp add --transport http macaroni … and your agent holds the full surface: 14 tools, each mirroring a live REST endpoint, over stateless Streamable HTTP at POST /mcp.

GET /v1/credits

The turn that fails on us is the turn you don't pay for.

Everything is metered in integer credits. Open a session → a budget hold. Each turn captures only its actual spend. Close → the unspent hold is released. A system-caused failure auto-refunds the turn. All of it is visible: credits: {budget, held, spent} on every poll, the full ledger at GET /v1/credits.

Account credit ledger, as returned by GET /v1/credits — every row reconciles.
entry type credits
open_session · budget_credits reserved, not spent hold 500
turn settles · actual spend only capture 308
close · the unspent hold returned release 192

system failures only — user_interrupted and budget_exceeded bill actual spend.

Credits are provisioned to your account — contact us.

FAQ

FAQ

What does a video cost?

Credits, never dollars. A session holds a budget you set — the default is a per-pipeline estimate, roughly 500 credits for an explainer. Turns capture actual spend; the unspent hold is released on close. Check GET /v1/credits any time — every hold, capture, release, and refund is a ledger entry. Details: /docs/api.

What happens when something fails?

Every failure is typed. System-caused failures (infra_error, engine_error, no_deliverable) cost you nothing — never billed, or auto-refunded. Your actions (user_interrupted, budget_exceeded) bill actual spend and are not refunded. The full failure table, with documented recovery per type: /docs/integration.

Do I ever pay for a video I didn't get?

Not when the failure is ours. A turn that finishes without a hosted, playable link settles no_deliverable and auto-refunds its credits — the refund entry shows in GET /v1/credits. If you interrupt a turn or exceed your budget, actual spend to that point is billed; those are your calls, not our failures. /docs/integration.

How does my agent connect?

MCP over Streamable HTTP at POST /mcp: one config block or one claude mcp add command — see the quickstart above. 14 tools, each mirroring a live REST endpoint; REST is 1:1 if you'd rather curl. /docs/mcp.

Which pipelines are production-ready?

animated-explainer is certified for hosted delivery. Twelve more are experimental and labeled as such — they may finish creative work without producing a hosted video, which settles no_deliverable and auto-refunds. The catalog with stability markers: /docs/api.

Can I use my own provider keys (BYOK)?

Yes. POST /v1/providers/keys stores them — AES-256-GCM at rest, never returned, no fallback to platform keys, so store a key for every provider your pipeline needs. Set byok: true on open_session to run on them. One exception: without your own Anthropic key, the reasoning model runs metered on ours. Key management is REST-only. /docs/api.

What formats?

16:9 landscape or 9:16 vertical — you choose per session. Every delivered video is a hosted MP4, and get_video returns width, height, and aspect_ratio so your agent routes per platform without probing the file. /docs/api. 9:16 vertical is available via format on open_session — same session, same contract.

Can I stream progress from a browser?

Auth is Bearer-only, no cookies — a native EventSource can't send the Authorization header. Use fetch-streaming for SSE (GET /v1/sessions/:id/events, resumable via Last-Event-ID), or the documented poll loop, which is the simplest correct integration. /docs/integration.

How long do share links live?

They're stable, unguessable, noindex URLs that stream the MP4 through our gateway — Range-seekable, no API key needed to view. They're intended to be long-lived, on the order of a year. We state the intent rather than promise a guarantee we don't offer. /docs/api.

Is there a free trial?

Not today. Contact us for evaluation credits — credits are provisioned to your account.

POST /v1/sessions

The next video your agent ships, it will have reviewed first.

Read the docs first — the failure table and the video_url contract are what you're evaluating. When a turn delivers, the link opens. When the system fails, the ledger shows the refund. We email your keys and onboard each account directly.