DEVELOPER DOCS
API Reference
Render captioned and AI-edited videos programmatically. All endpoints require authentication via API key or Bearer token.
Quickstart
Go from video URL to captioned MP4 in 4 steps:
- Get an API key — create one below or on your account page
- Add captions — call POST /api/v1/captions with any public video_url and optional style_id. Returns immediately with a run ID.
- Poll for completion — call GET /api/v1/render/:id until status is "completed".
- Export & download — call POST /api/v1/render/:id/export, then poll until export_status is "completed" and grab the download_url.
Full example
# 1. Add captions to a video
curl -X POST https://api.elevideo.dev/v1/captions \
-H "X-API-Key: ck_your_key" \
-H "Content-Type: application/json" \
-d '{"video_url": "https://example.com/video.mp4", "style_id": "holographic"}'
# 2. Poll status (repeat until status = "completed")
curl https://api.elevideo.dev/v1/render/run_abc123 \
-H "X-API-Key: ck_your_key"
# 3. Trigger export
curl -X POST https://api.elevideo.dev/v1/render/run_abc123/export \
-H "X-API-Key: ck_your_key"
# 4. Poll again until export_status = "completed", then use download_url
# 5. Try a different style (free — no re-transcription)
curl -X POST https://api.elevideo.dev/v1/render/run_abc123/rerun \
-H "X-API-Key: ck_your_key" \
-H "Content-Type: application/json" \
-d '{"style_id": "beast"}'CLI
The Clipcode CLI lets you render videos directly from your terminal using local files or URLs.
Install
npm install -g @clipcode/cli
Authenticate
clipcode auth --key ck_your_key
Render a local file
clipcode render ./video.mp4 --style bold # ✓ Uploaded (12.4 MB) # ✓ Rendering … done # ✓ Exported → video-bold.mp4 clipcode styles # list available styles clipcode renders # list past renders clipcode status <run-id> # check render status
MCP — AI Agent Integration
Clipcode ships an MCP server so AI agents (Claude, Cursor, or any MCP-compatible client) can render videos autonomously — no API calls required from your code.
Install
npm install -g @clipcode/mcp-server
Claude Desktop — add to ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"clipcode": {
"command": "clipcode-mcp",
"env": {
"CLIPCODE_API_KEY": "ck_your_key"
}
}
}
}Cursor — add to .cursor/mcp.json in your project
{
"mcpServers": {
"clipcode": {
"command": "clipcode-mcp",
"env": {
"CLIPCODE_API_KEY": "ck_your_key"
}
}
}
}Available tools
- render_video — render a video with a template
- check_render_status — poll render progress
- export_render — trigger MP4 export
- list_templates — list all caption styles and AI templates
- get_account — check credit balance
Authentication
Pass your API key in the X-API-Key header with every request:
curl -H "X-API-Key: ck_your_key_here" \ https://api.elevideo.dev/v1/account
Bearer token authentication (Authorization: Bearer <token>) is also supported for web frontend integration.
Your API Keys
Loading keys...
How Renders Work
Upload Video ──▶ POST /captions ──▶ Transcription ──▶ Composition Built
or POST /ai-edits status: "completed"
│
▼
POST /render/:id/export
(async)
│
▼
Server-side Render
│
▼
Upload to CDN ──▶ download_url- You provide a video URL and optionally a style ID
- The API transcribes your video with word-level timing
- For caption templates: builds a composition with styled captions overlaid on your video
- For AI edit templates: also uses AI to extract highlights, quotes, or structured data from the transcript
- Once the composition is built, you trigger an export which renders a final MP4 on our servers
- The rendered MP4 is uploaded to CDN and a download URL is returned
Compositions & Re-editing
Every completed render produces a composition object — the full set of rendering instructions including captions, timing, styles, and overlays.
You can retrieve any render's composition via GET /api/v1/render/:id. The composition contains:
- segments — video clips with timing, transitions, animations
- captions — word-level caption data with style configuration
- transcriptionWords — raw word timing from transcription
- audioUrl — extracted audio track
- styleParams — video effects (zoom, pan, blur)
- aiEditTemplate — AI-extracted overlay data (for AI edit templates)
Every video you render is effectively a reusable template. You can take any public video URL, process it with different templates, and get different styled outputs from the same source.
Async Flow & Status
Both render and export operations are asynchronous. The API responds immediately and processes in the background. Poll the render endpoint to track progress.
Render status progression
processing ──▶ completed ──▶ (trigger export) ──▶ rendering ──▶ uploading ──▶ completed
│ │
▼ ▼
failed failed- processing — transcription + composition in progress
- completed — composition ready, can view or export
- failed — processing error (check error_message)
- rendering — server-side export in progress
- uploading — rendered MP4 uploading to CDN
- export_status: "completed" — download_url available
Re-runs (POST /render/:id/rerun) skip transcription entirely. Caption re-runs complete instantly. AI edit re-runs only need a brief LLM step. Re-runs are free — no credits charged.
Captions
Add captions to a video. Transcribes the audio and overlays styled captions. Returns immediately — poll GET /render/:id for completion.
Request body
{
"video_url": "https://example.com/video.mp4", // required — public URL or R2 upload URL
"style_id": "holographic", // optional (default "classic") — see GET /styles/captions
"duration_seconds": 60, // optional (default 30) — for credit calc
"auto_render": true // optional — trigger export automatically after composition is built
}Response
{
"id": "run_abc123",
"status": "processing",
"flow_type": "captions",
"style_id": "holographic",
"created_on": "2026-03-25T12:00:00.000Z"
}Returns 402 if insufficient credits. Returns 400 for invalid style_id. Credits: 0.3 per 30-second chunk (minimum 0.3). When auto_render is true, poll GET /render/:id until export_status = "completed" for the download_url.
AI Edits
Apply an AI-powered overlay template to a video. Transcribes audio, then uses AI to extract structured data (quotes, features, stats) and renders a styled overlay. Returns immediately — poll GET /render/:id for completion.
Request body
{
"video_url": "https://example.com/video.mp4", // required
"style_id": "property_showcase", // required — see GET /styles/ai-edits
"duration_seconds": 60, // optional (default 30)
"auto_render": true // optional — trigger export automatically after composition is built
}Response
{
"id": "run_abc123",
"status": "processing",
"flow_type": "ai_edit",
"style_id": "property_showcase",
"created_on": "2026-03-25T12:00:00.000Z"
}Returns 402 if insufficient credits. Returns 400 for invalid or missing style_id.
Renders
Get the status, composition, and export details of a render job.
Parameters
:id — The render run ID returned from POST /captions or POST /ai-edits
Response
{
"id": "run_abc123",
"status": "completed",
"flow_type": "captions",
"style_id": "holographic",
"parent_run_id": null, // set if this is a re-run
"composition": { ... }, // full composition when status = "completed"
"current_stage": null, // active processing stage: "transcribing" | "building" | "rendering" | "uploading" | null
"download_url": "https://cdn.elevideo.dev/renders/...",
"export_status": "completed", // null until export triggered
"export_progress": 1.0, // 0–1 float during rendering, null otherwise
"export_error": null,
"error_message": null,
"created_on": "2026-03-25T12:00:00.000Z"
}List all your render jobs (captions and AI edits).
Response
{
"renders": [
{
"id": "run_abc123",
"status": "completed",
"flow_type": "captions",
"style_id": "holographic",
"source_file_name": "video.mp4",
"created_on": "2026-03-25T12:00:00.000Z"
}
]
}Trigger a server-side MP4 export. The render must have status 'completed' with a composition.
Parameters
:id — The render run ID
Response
{
"render_id": "run_abc123",
"export_status": "rendering"
}Returns 400 if render is not yet completed. Export takes 1-8 minutes depending on video length. Poll GET /render/:id for export_status.
Re-run a completed render with a different style. Reuses the stored transcription — no re-transcription, no credits charged. Caption re-runs complete instantly. AI edit re-runs need a brief LLM processing step.
Parameters
:id — The original render run ID (must be completed)
Request body
{
"style_id": "beast" // new style to apply (same flow type as original)
}Response
{
"id": "run_def456",
"status": "completed", // instant for captions
"flow_type": "captions",
"style_id": "beast",
"parent_run_id": "run_abc123", // links to original
"created_on": "2026-03-25T12:00:00.000Z"
}Returns 400 if original render is not completed or has no stored transcription. Style must match the same flow type (caption styles for captions, AI edit styles for AI edits).
Styles
List all 32 available caption styles. Use the style id as the style_id parameter in POST /captions.
Response
{
"styles": [
{
"id": "holographic",
"name": "Holographic",
"description": "Cyan holographic glow with uppercase text",
"category": "animated"
}
]
}List all 32 available AI edit styles. Use the style id as the style_id parameter in POST /ai-edits.
Response
{
"styles": [
{
"id": "property_showcase",
"label": "Property Showcase",
"description": "Elegant property listing with price, features, and CTA",
"category": "real_estate"
}
]
}Caption Styles
32 caption styles across 4 categories: minimal, bold, animated, and elegant. Each controls fonts, colors, animations, and effects.
Call GET /api/v1/styles/captions for the full current list.
Example styles
"classic" — Traditional subtitles with dark background (minimal) "holographic" — Cyan holographic glow with uppercase text (animated) "beast" — Impact font with yellow box on active word (bold) "elegance" — Serif script with alternating cursive words (elegant)
AI Edit Styles
32 AI edit overlay styles organized by industry: real estate, SaaS, personal brand, trendy, podcast, news, reviews, local business, e-commerce, and finance. Each uses AI to extract relevant data from your video's transcript.
Call GET /api/v1/styles/ai-edits for the full current list.
Example styles
"property_showcase" — Property listing with price + features (real_estate) "product_demo" — SaaS product walkthrough (saas) "tiktok_title" — Trendy short-form content (trendy) "podcast_clip" — Interview clips with standout quote (podcast)
Webhooks
Register a URL to receive HTTP POST notifications when render events occur. Useful for agents and automations that want push delivery instead of polling.
Events
"render.started" — job began processing "render.completed" — composition ready (status = "completed") "render.failed" — job failed "render.export_completed" — MP4 export done, download_url available "render.export_failed" — export failed
Payload shape
{
"event": "render.completed",
"data": {
"id": "run_abc123",
"status": "completed",
"flow_type": "captions",
"style_id": "holographic",
"created_on": "2026-03-25T12:00:00.000Z"
}
}List your registered webhooks.
Response
{
"webhooks": [
{
"id": "wh_abc123",
"url": "https://your-server.com/webhook",
"events": ["render.completed", "render.failed"],
"active": true,
"created_on": "2026-03-25T12:00:00.000Z"
}
]
}Register a webhook URL. Maximum 5 webhooks per account.
Request body
{
"url": "https://your-server.com/webhook",
"events": ["render.completed", "render.export_completed", "render.failed"]
}Response
{
"id": "wh_abc123",
"url": "https://your-server.com/webhook",
"events": ["render.completed", "render.export_completed", "render.failed"],
"active": true,
"created_on": "2026-03-25T12:00:00.000Z"
}Returns 400 if URL is invalid or events list is empty. Returns 409 if you already have 5 webhooks.
Deactivate and remove a webhook.
Parameters
:id — The webhook ID
Response
{ "id": "wh_abc123", "active": false }Send a test payload to your webhook URL to verify it's reachable.
Parameters
:id — The webhook ID
Response
{ "success": true, "status_code": 200 }Returns 200 even if your server returned an error — check status_code in the response.
List the last 20 delivery attempts for a webhook — useful for debugging.
Parameters
:id — The webhook ID
Response
{
"deliveries": [
{
"id": "del_abc",
"event": "render.completed",
"success": true,
"status_code": 200,
"created_on": "2026-03-25T12:00:00.000Z"
}
]
}Account
Get your current credit balance.
Response
{
"user_id": "user_123",
"credits_remaining": 42.5
}Create a new API key. The full key is only returned once — store it securely.
Request body
{
"name": "My Production Key" // optional (default "Unnamed Key")
}Response
{
"id": "key_abc",
"key": "ck_live_abc123...",
"name": "My Production Key",
"created_on": "2026-03-25T12:00:00.000Z"
}List your API keys. Keys are masked — only the prefix is shown.
Response
{
"api_keys": [
{
"id": "key_abc",
"name": "My Production Key",
"key_prefix": "ck_live...",
"active": true,
"created_on": "2026-03-25T12:00:00.000Z"
}
]
}Revoke an API key. The key will immediately stop working.
Parameters
:id — The API key ID
Response
{
"id": "key_abc",
"active": false
}List your credit purchase history.
Response
{
"purchases": [
{
"id": "purchase_abc",
"credits": 50,
"price_cents": 500,
"created_on": "2026-03-25T12:00:00.000Z"
}
]
}Billing
List available credit packages and prices.
Response
{
"packages": [
{ "price_cents": 500, "price_display": "$5.00", "credits": 50 },
{ "price_cents": 2000, "price_display": "$20.00", "credits": 250 },
{ "price_cents": 5000, "price_display": "$50.00", "credits": 700 },
{ "price_cents": 10000, "price_display": "$100.00", "credits": 1500 }
]
}Create a Stripe checkout session for purchasing credits.
Request body
{
"price_cents": 500,
"success_url": "https://elevideo.dev/account?checkout=success",
"cancel_url": "https://elevideo.dev/account?checkout=cancel"
}Response
{
"sessionId": "cs_live_...",
"url": "https://checkout.stripe.com/..."
}Returns 400 if price_cents does not match a valid package.
Error Codes
All errors return a JSON body with error (machine-readable code) and message (human-readable description).
| HTTP | Error Code | Meaning |
|---|---|---|
| 400 | missing_video_url | No video_url in request body |
| 400 | missing_template_id | No template_id in request body |
| 400 | invalid_template | Template ID not found |
| 400 | not_ready | Render not completed (cannot export yet) |
| 400 | missing_fields | Required fields missing (checkout) |
| 400 | file_too_large | File exceeds 500MB limit |
| 400 | checkout_failed | Stripe checkout session failed |
| 401 | missing_authorization | No auth header provided |
| 401 | invalid_token | Bearer token is invalid |
| 401 | missing_api_key | No X-API-Key header |
| 401 | invalid_api_key | API key not found or inactive |
| 402 | insufficient_credits | Not enough credits for this render |
| 404 | not_found | Resource not found or not owned by you |
| 429 | rate_limited | Rate limit exceeded (100/min) |
| 500 | lambda_error | Server-side rendering failed |
| 500 | internal_error | Unexpected server error |
Rate Limits
API requests are limited to 100 requests/minute per user. If you exceed this limit you will receive a 429 response. Standard rate limit headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) are included in every response.