Web Editor
← Back to docs

WizCut API

Programmatically upload, process, and render multicam podcast edits with the WizCut API.

The WizCut API lets you automate multicam podcast editing. Upload your camera angles, let WizCut detect speakers and generate cuts, optionally review them in a hosted editor, and get a rendered video back via webhook.

Authentication

Create an API key at wizcut.com/settings. Include it in every request:

Authorization: Bearer wc_live_your_key_here

Keys can be revoked at any time from the settings page.

Create a job

POST /api/jobs
{
  "sources": [
    { "label": "Camera 1", "kind": "video", "ext": "mp4" },
    { "label": "Camera 2", "kind": "video", "ext": "mp4" }
  ],
  "tracks": [
    { "sourceId": "auto", "speakers": [] }
  ],
  "callbackUrl": "https://your-server.com/webhook",
  "review": true
}

Fields:

FieldTypeDescription
sourcesarrayCamera angles or audio files. Each has label, optional kind ("video" or "audio", default "video"), optional ext (default "mp4").
tracksarraySpeaker-to-source mappings. Pass empty speakers [] to let WizCut auto-assign after analysis.
callbackUrlstringURL to receive webhook notifications on status changes.
reviewbooleanDefault true. When true, the job pauses at “ready” for human review of cuts before rendering. When false, rendering starts automatically after speaker mapping is submitted.

Response:

{
  "jobId": "uuid",
  "uploadUrls": {
    "source-uuid-1": "https://presigned-upload-url...",
    "source-uuid-2": "https://presigned-upload-url..."
  }
}

Upload files

PUT your video files to each presigned URL from the response. No auth header needed — the URL is self-authenticating.

curl -X PUT -T camera1.mp4 "https://presigned-upload-url..."
curl -X PUT -T camera2.mp4 "https://presigned-upload-url..."

Start processing

POST /api/jobs/{jobId}/process

This kicks off the pipeline: audio sync, speaker detection, cut generation, and proxy rendering. The request returns immediately — processing happens asynchronously.

Response:

{ "jobId": "uuid", "status": "syncing" }

Get job status

GET /api/jobs/{jobId}

Returns the full job object including current status, sources, turns, and cuts.

Status values:

StatusMeaning
createdJob created, waiting for uploads
syncingAligning audio across sources
diarizingDetecting speakers
mappingNeeds speaker-to-source mapping
readyCuts generated, ready for review or rendering
renderingFinal render in progress
completeRender done, output_url available
approvedHuman approved the output
failedSomething went wrong, see error_message

Webhooks

When you provide a callbackUrl, WizCut sends POST requests on status transitions:

“mapping” webhook (speakers detected, needs human mapping):

{
  "jobId": "uuid",
  "status": "mapping",
  "reviewUrl": "https://wizcut.com/jobs/uuid/edit?reviewToken=..."
}

Send a human to the reviewUrl to map speakers to camera sources and review cuts.

“ready” webhook (speaker mapping complete, cuts generated):

{
  "jobId": "uuid",
  "status": "ready",
  "reviewUrl": "https://wizcut.com/jobs/uuid/edit?reviewToken=..."
}

“complete” webhook (render finished):

{
  "jobId": "uuid",
  "status": "complete",
  "outputUrl": "https://presigned-download-url..."
}

“approved” webhook (human approved via review UI):

{
  "jobId": "uuid",
  "status": "approved",
  "outputUrl": "https://presigned-download-url..."
}

“failed” webhook:

{
  "jobId": "uuid",
  "status": "failed",
  "error": "description of what went wrong"
}

Speaker mapping and review (human-in-the-loop)

After speaker detection, the job enters “mapping” status. A human must map the detected speakers to camera sources — diarization identifies when someone speaks but not which camera they’re on.

The “mapping” webhook includes a reviewUrl — a signed link to the WizCut editor. Send a human there. In the editor, they:

  1. Map each detected speaker to a camera source
  2. Preview and edit the auto-generated cuts
  3. Click “Render” when satisfied (if review: true, the default)
  4. Optionally click “Approve” after reviewing the rendered output

With review: false, rendering starts automatically as soon as the speaker mapping is submitted — the human doesn’t get to review cuts before rendering.

Advanced: programmatic cut control

For fully automated pipelines that skip the UI entirely, you can manage cuts and rendering via API:

Update cuts:

PATCH /api/jobs/{jobId}/cuts
{
  "cuts": [
    { "startMs": 0, "endMs": 5000, "sourceId": "source-uuid-1" },
    { "startMs": 5000, "endMs": 12000, "sourceId": "source-uuid-2" }
  ]
}

Trigger render:

POST /api/jobs/{jobId}/render

Approve output:

POST /api/jobs/{jobId}/approve

Error responses

All endpoints return errors in this format:

{ "error": "Description of what went wrong" }

Common HTTP status codes:

CodeMeaning
401Missing or invalid API key
403Quota exceeded
404Job not found or not owned by you
409Invalid status transition (e.g. rendering a job that isn’t ready)
500Server error
503Service not available

Complete flow

Here’s the full happy path for an AI agent or automation:

# 1. Create a job with two cameras
JOB=$(curl -s -X POST https://wizcut.com/api/jobs \
  -H "Authorization: Bearer wc_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [
      {"label": "Camera 1", "kind": "video"},
      {"label": "Camera 2", "kind": "video"}
    ],
    "callbackUrl": "https://your-server.com/webhook"
  }')

JOB_ID=$(echo $JOB | jq -r '.jobId')

# 2. Upload video files to the presigned URLs
curl -X PUT -T camera1.mp4 "$(echo $JOB | jq -r '.uploadUrls | to_entries[0].value')"
curl -X PUT -T camera2.mp4 "$(echo $JOB | jq -r '.uploadUrls | to_entries[1].value')"

# 3. Start processing
curl -s -X POST "https://wizcut.com/api/jobs/$JOB_ID/process" \
  -H "Authorization: Bearer wc_live_your_key"

# 4. Wait for webhook: { status: "mapping", reviewUrl: "..." }
#    Send a human to reviewUrl to map speakers and review cuts

# 5. Human maps speakers → edits cuts → clicks Render in the editor
#    Wait for webhook: { status: "complete", outputUrl: "..." }

# 6. Download the rendered video from outputUrl

With auto-render after mapping (review: false):

# Same as above, but add "review": false to step 1
# Human still maps speakers at the reviewUrl (step 4)
# But rendering starts automatically after mapping — no cut review step
# You'll get: { status: "complete", outputUrl: "..." }
WizCut API – WizCut Docs