API de WizCut
Subí, procesá y renderizá ediciones de podcasts multicam de forma programática con la API de WizCut.
La API de WizCut te permite automatizar la edición de podcasts multicam. Subís los ángulos de cámara, WizCut detecta los speakers y genera los cortes, opcionalmente los revisás en un editor online, y recibís el video renderizado por webhook.
Autenticación
Creá una API key en wizcut.com/settings. Incluila en cada request:
Authorization: Bearer wc_live_your_key_here
Las keys se pueden revocar en cualquier momento desde la página de configuración.
Crear un 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
}
Campos:
| Campo | Tipo | Descripción |
|---|---|---|
sources | array | Ángulos de cámara o archivos de audio. Cada uno tiene label, kind opcional ("video" o "audio", por defecto "video"), y ext opcional (por defecto "mp4"). |
tracks | array | Mapeo de speakers a fuentes. Pasá speakers vacíos [] para que WizCut los asigne automáticamente después del análisis. |
callbackUrl | string | URL que recibe las notificaciones webhook en los cambios de estado. |
review | boolean | Por defecto true. Con true, el job se pausa en “ready” para que un humano revise los cortes antes del render. Con false, el render arranca automáticamente después de que se envía el mapeo de speakers. |
Respuesta:
{
"jobId": "uuid",
"uploadUrls": {
"source-uuid-1": "https://presigned-upload-url...",
"source-uuid-2": "https://presigned-upload-url..."
}
}
Subir archivos
Hacé PUT de los archivos de video a cada URL prefirmada que devuelve la respuesta. No necesitás header de autenticación — la URL ya trae la autenticación incorporada.
curl -X PUT -T camera1.mp4 "https://presigned-upload-url..."
curl -X PUT -T camera2.mp4 "https://presigned-upload-url..."
Iniciar el procesamiento
POST /api/jobs/{jobId}/process
Esto arranca el pipeline: sincronización de audio, detección de speakers, generación de cortes y render de proxy. El request devuelve inmediatamente — el procesamiento ocurre de forma asincrónica.
Respuesta:
{ "jobId": "uuid", "status": "syncing" }
Ver el estado del job
GET /api/jobs/{jobId}
Devuelve el objeto completo del job, incluyendo el estado actual, fuentes, turnos y cortes.
Valores de estado:
| Estado | Significado |
|---|---|
created | Job creado, esperando las subidas |
syncing | Alineando audio entre las fuentes |
diarizing | Detectando speakers |
mapping | Necesita mapeo de speaker a fuente |
ready | Cortes generados, listo para revisión o render |
rendering | Render final en progreso |
complete | Render terminado, output_url disponible |
approved | Un humano aprobó el resultado |
failed | Algo salió mal, revisá error_message |
Webhooks
Cuando proporcionás una callbackUrl, WizCut envía requests POST en cada transición de estado:
Webhook “mapping” (speakers detectados, necesita mapeo humano):
{
"jobId": "uuid",
"status": "mapping",
"reviewUrl": "https://wizcut.com/jobs/uuid/edit?reviewToken=..."
}
Mandá a alguien a la reviewUrl para mapear los speakers a las fuentes de cámara y revisar los cortes.
Webhook “ready” (mapeo de speakers completo, cortes generados):
{
"jobId": "uuid",
"status": "ready",
"reviewUrl": "https://wizcut.com/jobs/uuid/edit?reviewToken=..."
}
Webhook “complete” (render terminado):
{
"jobId": "uuid",
"status": "complete",
"outputUrl": "https://presigned-download-url..."
}
Webhook “approved” (humano aprobó desde la UI de revisión):
{
"jobId": "uuid",
"status": "approved",
"outputUrl": "https://presigned-download-url..."
}
Webhook “failed”:
{
"jobId": "uuid",
"status": "failed",
"error": "description of what went wrong"
}
Mapeo de speakers y revisión (human-in-the-loop)
Después de la detección de speakers, el job pasa al estado “mapping”. Un humano tiene que mapear los speakers detectados a las fuentes de cámara — la diarization identifica cuándo habla alguien, pero no en qué cámara está.
El webhook “mapping” incluye una reviewUrl — un link firmado al editor de WizCut. Mandá a alguien ahí. En el editor, la persona:
- Mapea cada speaker detectado a una fuente de cámara
- Previsualiza y edita los cortes generados automáticamente
- Hace clic en “Render” cuando está listo (si
review: true, que es el valor por defecto) - Opcionalmente hace clic en “Approve” después de revisar el resultado renderizado
Con review: false, el render arranca automáticamente en cuanto se envía el mapeo de speakers — la persona no tiene la opción de revisar los cortes antes del render.
Avanzado: control programático de cortes
Para pipelines completamente automatizados que saltean la UI por completo, podés gestionar los cortes y el render por API:
Actualizar cortes:
PATCH /api/jobs/{jobId}/cuts
{
"cuts": [
{ "startMs": 0, "endMs": 5000, "sourceId": "source-uuid-1" },
{ "startMs": 5000, "endMs": 12000, "sourceId": "source-uuid-2" }
]
}
Disparar el render:
POST /api/jobs/{jobId}/render
Aprobar el resultado:
POST /api/jobs/{jobId}/approve
Respuestas de error
Todos los endpoints devuelven errores en este formato:
{ "error": "Description of what went wrong" }
Códigos de estado HTTP más comunes:
| Código | Significado |
|---|---|
| 401 | API key faltante o inválida |
| 403 | Cuota superada |
| 404 | Job no encontrado o no te pertenece |
| 409 | Transición de estado inválida (ej. renderizar un job que no está listo) |
| 500 | Error del servidor |
| 503 | Servicio no disponible |
Flujo completo
Acá está el camino feliz completo para un agente de IA o una automatización:
# 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
Con render automático después del mapeo (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: "..." }