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
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.
| Status | Meaning |
|---|---|
| 400 | Bad request — missing or invalid parameters |
| 401 | Missing or invalid API key |
| 402 | Credit limit exceeded — increase your overage limit |
| 403 | No active subscription for this key |
| 404 | Job or resource not found |
| 500 | Server error — retry after a moment |
Submit a job
Submit text content for processing. Returns a job_id immediately. Processing takes 3–10 minutes depending on content length.
Request body
| Field | Type | Description |
|---|---|---|
| content | string | Required. Text to convert. Min 400 chars, max 21,000 chars. |
| visual_style | string | Optional. "stock" (default) or "ai". Stock uses licensed footage. AI generates custom visuals using more credits. |
| webhook_url | string | Optional. URL to POST when this specific job completes or fails. Delivered without an X-Multi-Signature header. For signed deliveries, register a webhook endpoint. |
| skip_narration_rewrite | boolean | Optional. Default false. Pass your script through unchanged. Use when you've already written for spoken delivery and want your wording preserved. Pronunciation handling for numbers and acronyms still runs so the audio sounds natural. |
How content is handled
By default, Multi adapts your input for spoken delivery: readability for the ear and pacing for video. If you've already written your script for spoken delivery and want your exact wording, set skip_narration_rewrite to true.
{
"content": "Your content here — changelog, doc, blog post, anything...",
"visual_style": "stock",
"webhook_url": "https://yourapp.com/hooks/multi",
"skip_narration_rewrite": false
}
Response — 202 Accepted
{
"job_id": "d4e5f6a7-...",
"status": "processing",
"created_at": "2026-03-05T12:00:00.000Z"
}
Get job status
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
| Status | Meaning |
|---|---|
| processing | Pipeline is running. Check again in a few minutes. |
| completed | Done. Download URLs are included in the response. |
| failed | Pipeline 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
List recent jobs for this API key's account. Returns up to 100 jobs, sorted newest first.
Query parameters
| Param | Type | Description |
|---|---|---|
| limit | number | Optional. 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.
GET /api/v1/jobs/:id again — fresh signed URLs are generated on every request.
Usage & credits
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 style | Credits per minute of video |
|---|---|
| stock | 5 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).
Create a new API key. The full key is returned once and never stored — save it immediately. Maximum 10 keys per account.
Request body
| Field | Type | Description |
|---|---|---|
| name | string | Optional. 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."
}
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.
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."
}
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);
});
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
| Tool | Description |
|---|---|
| create_video | Submit text content, get a job_id back |
| get_job_status | Check status, get download URLs when complete |
| list_jobs | List recent jobs |
| check_usage | Check 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