API Documentation
Everything you need to integrate Editing Machine into your applications, agents, and workflows.
Quick Start
Get up and running with the Editing Machine API in under 5 minutes. Projects follow a four-step lifecycle: create a project, attach footage, execute, then poll for status. Production Credits are only applied to your available production capacity when you execute.
1. Get your API key
Log in to your Editing Machine account and navigate to Automation → API Keys. Generate a new key and store it securely.
2. Create a project
Creating a project returns a signed price_quote showing the Production Credits required — no production capacity is used yet.
curl -X POST https://api.editingmachine.com/api/v1/projects \
-H "Authorization: Bearer em_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"recipe_id": 1,
"project_name": "My Video Project",
"brand_id": 5
}'3. Attach footage
curl -X POST https://api.editingmachine.com/api/v1/projects/42/assets \
-H "Authorization: Bearer em_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/footage.mp4" }'4. Execute the project
Pass the quote_id from step 2 to lock in the capacity requirement. The quoted Production Credits are applied here.
curl -X POST https://api.editingmachine.com/api/v1/projects/42/execute \
-H "Authorization: Bearer em_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "quote_id": "eyJ...signed..." }'5. Poll for status
curl https://api.editingmachine.com/api/v1/projects/42 \ -H "Authorization: Bearer em_xxxxxxxxxxxx"
When the status reads complete, the response includes output_urls with the finished deliverables.
Authentication
All API requests require a Bearer token in the Authorization header. API keys are scoped to your account and can be revoked at any time from the dashboard.
Header format
Authorization: Bearer em_xxxxxxxxxxxx
Keys are issued in the dashboard under Automation → API Keys. All keys use the single em_* format and run against live infrastructure — there is no separate test or sandbox key.
Keep keys secure
Never expose API keys in client-side code, public repos, or logs. Use environment variables and server-side requests only.
Endpoints
Create a project. Returns a signed quote for the required Production Credits — no production capacity is used yet.
Request body
Response
{
"id": 42,
"status": "created",
"recipe": { "name": "YouTube Long-Form", "type": "purpose" },
"credits_estimated": 5,
"price_quote": {
"quote_id": "eyJ...signed...",
"credits": 5,
"fingerprint": "a1b2c3...",
"expires_at": "2026-03-25T10:15:00.000Z"
},
"created_at": "2026-03-25T10:00:00.000Z"
}For backward compatibility, the credits_estimated and price_quote.credits fields represent Production Credits.
price_quote.quote_id is a server-signed token that locks in the price shown at creation. You must pass it to /execute. Tampered, expired, or stale quotes (pricing has drifted) are rejected — re-create the project to get a fresh one.
Attach source footage to a project by URL. Returns immediately while the file imports in the background.
Request body
Response
{
"asset_id": "import-a1b2c3d4",
"filename": "footage.mp4",
"status": "importing",
"size_bytes": null
}Start the project. The quoted Production Credits are applied to your available production capacity here. Project must be in created or draft status.
Request body
Response
{
"id": 42,
"status": "queued",
"credits_deducted": 5,
"credits_remaining": 245
}The legacy credits_deducted and credits_remaining response fields report Production Credits.
Poll a project's current status, progress, and output URLs.
{
"id": 42,
"status": "processing",
"progress_percent": 65,
"output_urls": [],
"created_at": "2026-03-25T10:00:00.000Z",
"updated_at": "2026-03-25T10:30:00.000Z"
}Status values
Webhooks
Receive real-time notifications when project status changes. Register an endpoint with POST /api/v1/webhooks specifying the URL and events you want to subscribe to.
Register a webhook
{
"url": "https://your-app.example.com/webhooks/editing-machine",
"events": [
"project.started",
"project.completed",
"project.failed",
"project.awaiting_client_input"
]
}Event types
Example payload
{
"event": "project.completed",
"project_id": 42,
"timestamp": "2026-03-25T12:00:00.000Z",
"data": {
"status": "complete",
"output_urls": ["https://..."]
}
}Signature verification
Every webhook request includes a signature header so you can verify it came from Editing Machine:
X-Webhook-Signature: <hex HMAC-SHA256 of the raw request body>
The value is a raw HMAC-SHA256 hex digest of the request body using your webhook secret — no sha256= prefix. Your secret is shown in the dashboard alongside your API keys. Always verify signatures before processing webhook data.
Status Codes
Error response format
Errors are returned as a flat object with a machine-readable code and a human-readable message:
{
"error": "quote_expired",
"message": "Price quote expired. Re-create the project to get a fresh quote."
}Rate limits
Rate limits are per API key and tiered by plan. Concurrent jobs are also capped — projects beyond your limit will return 429 until one finishes.
Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.
Source of truth
The live OpenAPI spec is generated directly from server code and kept in sync by a CI drift check. If anything here disagrees with the spec, the spec is right.
Ready to start building?
Get your API key and run your first project in minutes.