Multi API

Submit text, get video. The Multi API lets you integrate video production into any workflow — from scripts and CI pipelines to AI agents. All endpoints require an active subscription.

Authentication

All API requests are authenticated with a Bearer token. Generate a key from your account page under API Keys.

# Pass your key in the Authorization header
Authorization: Bearer mk_live_your_key_here
Keys are shown once. Save your key when you create it — it's never shown again. If you lose it, revoke it and create a new one.
Subscription required. API keys require an active Multi subscription. If your subscription lapses, your key will return 403 Forbidden until you resubscribe.

Quick start

Submit content, poll until done, download the files.

# 1. Submit a job
curl -X POST https://makemulti.com/api/v1/jobs \
  -H "Authorization: Bearer mk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"content": "Your content here..."}'

# Returns:
# { "job_id": "abc123", "status": "processing" }

# 2. Poll for completion
curl https://makemulti.com/api/v1/jobs/abc123 \
  -H "Authorization: Bearer mk_live_..."

# When done, returns signed download URLs:
# { "status": "completed", "video_url": "...", "podcast_url": "..." }

Errors

Errors return a JSON object with an error field and an appropriate HTTP status code.

StatusMeaning
400Bad request — missing or invalid parameters
401Missing or invalid API key
402Credit limit exceeded — increase your overage limit
403No active subscription for this key
404Job or resource not found
500Server error — retry after a moment

Submit a job

POST /api/v1/jobs

Submit text content for processing. Returns a job_id immediately. Processing takes 3–10 minutes depending on content length.

Request body

FieldTypeDescription
contentstringRequired. Text to convert. Min 400 chars, max 21,000 chars.
visual_stylestringOptional. "stock" (default) or "ai". Stock uses licensed footage. AI generates custom visuals using more credits.
webhook_urlstringOptional. URL to POST when this specific job completes or fails. Delivered without an X-Multi-Signature header. For signed deliveries, register a webhook endpoint.
{
  "content": "Your content here — changelog, doc, blog post, anything...",
  "visual_style": "stock",
  "webhook_url": "https://yourapp.com/hooks/multi"
}

Response — 202 Accepted

{
  "job_id": "d4e5f6a7-...",
  "status": "processing",
  "created_at": "2026-03-05T12:00:00.000Z"
}

Get job status

GET /api/v1/jobs/:job_id

Poll this endpoint to check job progress. Download URLs are returned once the job is complete. URLs expire after 24 hours — call this endpoint again to get fresh URLs.

Status values

StatusMeaning
processingPipeline is running. Check again in a few minutes.
completedDone. Download URLs are included in the response.
failedPipeline error. Submit a new job.

Response — processing

{
  "job_id": "d4e5f6a7-...",
  "status": "processing",
  "created_at": "2026-03-05T12:00:00.000Z"
}

Response — completed

{
  "job_id": "d4e5f6a7-...",
  "status": "completed",
  "title": "The Rise of Zero-Person Companies",
  "video_duration": 187,
  "render_ratio": 4.2,
  "video_url": "https://makemulti.com/api/v1/files/d4e5.../video?token=...&expires=...",
  "podcast_url": "https://makemulti.com/api/v1/files/d4e5.../podcast?token=...&expires=...",
  "captions_url": "https://makemulti.com/api/v1/files/d4e5.../captions?token=...&expires=...",
  "completed_at": "2026-03-05T12:07:33.000Z",
  "created_at": "2026-03-05T12:00:00.000Z"
}

List jobs

GET /api/v1/jobs

List recent jobs for this API key's account. Returns up to 100 jobs, sorted newest first.

Query parameters

ParamTypeDescription
limitnumberOptional. Max jobs to return. Default 20, max 100.

Response

{
  "jobs": [
    {
      "job_id": "d4e5f6a7-...",
      "status": "completed",
      "title": "The Rise of Zero-Person Companies",
      "video_duration": 187,
      "render_ratio": 4.2,
      "source": "api",
      "created_at": "2026-03-05T12:00:00.000Z"
    }
  ],
  "count": 1
}

Signed download URLs

Download URLs returned by GET /api/v1/jobs/:id and webhook payloads are time-limited signed URLs. They expire after 24 hours. No API key is required to use them — the signed URL itself is the authorization token.

This means you can safely hand a video URL to another service (a YouTube upload agent, a CDN, a storage bucket) without sharing your API key.

URL expired? Call GET /api/v1/jobs/:id again — fresh signed URLs are generated on every request.

Usage & credits

GET /api/v1/usage

Returns credit usage for the current billing period.

{
  "credits_used": 142,
  "credits_limit": 100,
  "credits_remaining": 58,
  "overage_accrued_cents": 0,
  "overage_limit_cents": 1000,
  "plan": "starter",
  "current_period_end": "2026-04-05T00:00:00.000Z"
}

Credit costs

Visual styleCredits per minute of video
stock5 credits/min
ai (short, ≤89s)13 credits/min
ai (long, >89s)8 credits/min

Duration is estimated from word count (~150 words/min). Longer AI videos use a more cost-efficient model, so the credit rate drops automatically. A 3-minute stock video costs 15 credits. The starter plan includes 100 credits/month.

API key management

Keys can be managed from your account page or programmatically via the API (using an existing key to create or revoke others).

POST /api/v1/keys

Create a new API key. The full key is returned once and never stored — save it immediately. Maximum 10 keys per account.

Request body

FieldTypeDescription
namestringOptional. Display name for the key. Defaults to "default".
// Request — name is optional
{ "name": "my-agent" }

// Response — 201 Created
{
  "id": "key-uuid",
  "key": "mk_live_a1b2c3d4e5f6...",
  "key_prefix": "mk_live_a1b2c3d4...",
  "name": "my-agent",
  "created_at": "2026-03-05T12:00:00.000Z",
  "note": "Save this key — it will not be shown again."
}
DELETE /api/v1/keys/:id

Revoke a key immediately. Any agent using it will lose access. This cannot be undone.

{ "success": true }

Webhook management

Register webhook URLs to receive POST notifications when jobs complete or fail. Each webhook has a unique HMAC signing secret — use it to verify the payload came from Multi.

POST /api/v1/webhooks

Register a webhook URL. The signing secret is returned once — save it.

// Request
{
  "url": "https://yourapp.com/hooks/multi",
  "events": ["job.completed", "job.failed"]
}

// Response — 201 Created
{
  "id": "webhook-uuid",
  "url": "https://yourapp.com/hooks/multi",
  "events": ["job.completed", "job.failed"],
  "secret": "a1b2c3d4...",
  "note": "Save this secret — it will not be shown again."
}
DELETE /api/v1/webhooks/:id

Remove a webhook URL.

{ "success": true }

Webhook events

Multi sends a POST to your registered URL when a job completes or fails. The payload includes signed download URLs (valid 24 hours).

job.completed

{
  "event": "job.completed",
  "job_id": "d4e5f6a7-...",
  "status": "completed",
  "title": "The Rise of Zero-Person Companies",
  "video_duration": 187,
  "render_ratio": 4.2,
  "video_url": "https://makemulti.com/api/v1/files/...",
  "podcast_url": "https://makemulti.com/api/v1/files/...",
  "captions_url": "https://makemulti.com/api/v1/files/...",
  "timestamp": "2026-03-05T12:07:33.000Z"
}

job.failed

{
  "event": "job.failed",
  "job_id": "d4e5f6a7-...",
  "status": "failed",
  "timestamp": "2026-03-05T12:07:33.000Z"
}

Verifying webhook signatures

Every registered webhook POST includes an X-Multi-Signature header. Verify it to confirm the payload came from Multi and wasn't tampered with. Per-job webhooks (via the webhook_url field) do not include a signature.

// Node.js verification example
import crypto from 'crypto';

function verifyWebhook(rawBody, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody)  // rawBody must be the raw string, not parsed JSON
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your Express handler:
app.post('/hooks/multi', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-multi-signature'];
  if (!verifyWebhook(req.body, sig, process.env.MULTI_WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  const payload = JSON.parse(req.body);
  // handle payload.event === 'job.completed' etc.
  res.sendStatus(200);
});
Use raw body for verification. Parse the body after verifying the signature, not before. Parsing JSON first can alter whitespace and break the HMAC check.
No retries. Webhook delivery is best-effort and fire-and-forget. Failed deliveries are not retried. If your endpoint is unreachable, the payload is lost. Use the polling API (GET /api/v1/jobs/:id) as a fallback.

MCP server for AI agents

Multi ships an MCP (Model Context Protocol) server that wraps the API as tools for Claude, GPT, and other MCP-enabled agents. Instead of writing API integration code, your agent can call Multi natively.

Tools available

ToolDescription
create_videoSubmit text content, get a job_id back
get_job_statusCheck status, get download URLs when complete
list_jobsList recent jobs
check_usageCheck credit balance and usage

Setup

Claude Desktop: Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent config on your OS.

Claude Code: Add to .mcp.json in your project root or ~/.claude/mcp.json globally.

{
  "mcpServers": {
    "multi": {
      "command": "node",
      "args": ["/path/to/multi/mcp-server.mjs"],
      "env": {
        "MULTI_API_KEY": "mk_live_...",
        "MULTI_API_URL": "https://makemulti.com"
      }
    }
  }
}

Example agent session

# In a Claude conversation, after MCP is configured:

User: Turn this product update into a video and upload it to YouTube.

Claude: I'll submit it to Multi first.
[calls create_video with the content]
→ job_id: d4e5f6a7, status: processing

[polls get_job_status after a few minutes]
→ status: completed
→ video_url: https://makemulti.com/api/v1/files/...

[passes video_url to YouTube upload tool]
→ Uploaded. YouTube URL: https://youtu.be/...

Questions? Email dru@makemulti.com · Your account