WizCut API
Envie, processe e renderize edições de podcasts multicam de forma programática com a WizCut API.
A WizCut API deixa você automatizar a edição de podcasts multicam. Envie os ângulos de câmera, deixa o WizCut detectar os participantes, descobrir quem tá em qual câmera e gerar os cortes, opcionalmente revise tudo num editor hospedado, e receba o vídeo renderizado de volta via webhook.
Autenticação
Crie uma API key em wizcut.com/settings. Coloca ela em toda requisição:
Authorization: Bearer wc_live_your_key_here
As keys podem ser revogadas a qualquer momento pela página de configurações.
Criar um job
POST /api/jobs
{
"sources": [
{ "label": "Camera 1", "kind": "video", "ext": "mp4", "fileSize": 2147483648 },
{ "label": "Camera 2", "kind": "video", "ext": "mp4", "fileSize": 1932735283 },
{ "label": "Mic mix", "kind": "audio", "ext": "wav" }
],
"callbackUrl": "https://your-server.com/webhook",
"review": true,
"autoMap": "confident",
"silence": { "mode": "tighten" }
}
Campos:
| Campo | Tipo | Descrição |
|---|---|---|
sources | array | Ângulos de câmera ou arquivos de áudio, até 12 por job. Um job precisa de pelo menos duas fontes de vídeo antes de poder ser processado. Cada um tem label, kind opcional ("video" ou "audio", padrão "video"), ext opcional (mp4, mov, webm, mkv, wav, mp3, m4a ou aac; padrão "mp4" pra vídeo, "wav" pra áudio) e fileSize opcional em bytes. |
callbackUrl | string | Opcional. URL pra receber notificações via webhook, veja Webhooks. |
review | boolean | Padrão true. Quando true, o job pausa no status “ready” pra revisão humana dos cortes antes de renderizar. Quando false, a renderização começa automaticamente assim que o mapeamento de participantes é enviado, seja por uma pessoa, pelo seu código ou pelo próprio WizCut. |
autoMap | string | Padrão "confident". Define se o WizCut pode decidir sozinho quem tá em qual câmera: "off", "confident" ou "always". Veja Mapeamento automático de câmeras. |
silence | object | Opcional. Remoção automática de pausas, veja Remoção de silêncio. Omitido significa desligado. |
Não dá pra passar o mapeamento de participantes (tracks) aqui: os IDs das fontes só existem depois que o job é criado, então ainda não tem a que associar um participante. Uma lista tracks com participantes é rejeitada com 400 e "code": "TRACKS_ON_CREATE". Use autoMap ou mapeie os participantes via API quando a detecção terminar.
Passe fileSize pra todo arquivo que você souber o tamanho. Arquivos acima de 100 MB aí ganham upload multipart: dá pra enviar as partes em paralelo, repetir só a parte que falhou, e é o único jeito de enviar arquivos maiores que 5 GB. Sem fileSize, todo arquivo recebe um PUT presigned único.
Resposta:
{
"jobId": "uuid",
"uploads": {
"source-uuid-1": {
"method": "multipart",
"uploadId": "...",
"key": "sources/uuid/source-uuid-1.mp4",
"partSize": 52428800,
"partCount": 41,
"urls": ["https://presigned-part-1-url...", "https://presigned-part-2-url...", "..."]
},
"source-uuid-3": {
"method": "put",
"url": "https://presigned-upload-url..."
}
},
"audioUploads": { "...": "..." }
}
uploads é indexado pelos IDs de fonte que o WizCut atribuiu, na mesma ordem do seu array sources. Pode ignorar audioUploads: ele é usado pelos apps do WizCut, que enviam uma faixa de áudio extraída antes do vídeo.
Fazer upload dos arquivos
Não precisa de header de autenticação pras URLs presigned, elas já se autenticam sozinhas.
"method": "put": envie o arquivo inteiro via PUT pra url dentro de uma hora.
curl -X PUT -T mic-mix.wav "https://presigned-upload-url..."
"method": "multipart": divida o arquivo em pedaços de partSize bytes (o último é menor) e envie o pedaço n via PUT pra URL da parte n.
-
urlstraz as URLs das primeiras partes (urls[0]é a parte 1). Peça mais conforme for avançando, até 16 por requisição:POST /api/jobs/{jobId}/sources/{sourceId}/parts{ "uploadId": "...", "partNumbers": [5, 6, 7, 8] }A resposta mapeia números de parte pra URLs:
{ "urls": { "5": "https://...", "6": "https://..." } }. As URLs de parte valem por duas horas, então busque elas pouco antes de usar. -
Depois que todas as partes forem enviadas, finalize o upload:
POST /api/uploads/complete{ "key": "sources/uuid/source-uuid-1.mp4", "uploadId": "..." }
Pra desistir de um upload, mande o mesmo corpo pra POST /api/uploads/abort.
Iniciar o processamento
POST /api/jobs/{jobId}/process
Chame isso assim que todos os arquivos forem enviados. Isso dispara o pipeline: sincronização de áudio, detecção de participantes, render do proxy, mapeamento de câmeras e geração de cortes. A requisição retorna imediatamente, o processamento acontece de forma assíncrona.
Corpo opcional:
{ "diarizeSourceIds": ["source-uuid-3"] }
diarizeSourceIds escolhe quais fontes o WizCut escuta pra detecção de participantes. Se você não passar, o WizCut usa suas fontes audio, ou a primeira fonte se não tiver nenhuma. Escolha as fontes com o áudio mais limpo de todo mundo falando: uma câmera com microfone mudo ou distante faz o job sair sem nenhum corte.
Resposta:
{ "jobId": "uuid", "status": "syncing" }
Listar jobs
GET /api/jobs
Retorna { "jobs": [...] } com seus 50 jobs mais recentes, do mais novo pro mais antigo. Cada um traz id, title, status, created_at e updated_at.
Consultar o status do job
GET /api/jobs/{jobId}
Resposta:
{
"job": {
"id": "uuid",
"status": "complete",
"sources": [...],
"tracks": [...],
"turns": [...],
"cuts": [...],
"removed_ranges": [...],
"camera_map": {...},
"output_url": "https://presigned-download-url...",
"error_message": null
},
"sourceUrls": { "source-uuid-1": "https://..." },
"audioUrl": "https://..."
}
O job em si fica dentro de job. As URLs assinadas na resposta (output_url, sourceUrls, audioUrl) são assinadas na hora a cada requisição, então busque o job de novo em vez de guardar elas.
camera_map é a proposta do WizCut de quem tá em qual câmera, veja O mapa de câmeras. Ele é null até ser calculado.
Valores de status:
| Status | Significado |
|---|---|
created | Job criado, aguardando uploads |
uploading | Aguardando os arquivos terminarem de subir (ex.: depois que um job com falha é reaberto) |
syncing | Alinhando o áudio entre as fontes |
diarizing | Detectando os participantes |
mapping | Participantes detectados. O WizCut ainda tá descobrindo quem tá em qual câmera, ou uma pessoa (ou o seu agente) precisa confirmar |
ready | Cortes gerados, pronto pra revisão ou renderização |
rendering | Render final em andamento |
complete | Render concluído, output_url disponível |
approved | Output aprovado por uma pessoa |
failed | Algo deu errado, veja error_message |
Excluir um job
DELETE /api/jobs/{jobId}
Exclui o job e todos os arquivos dele: uploads, proxies, o áudio da detecção de falantes e o render. Funciona em qualquer status; se uma etapa ainda estiver rodando, o que ela gerar é limpo quando terminar. Minutos já usados não voltam. Retorna { "ok": true }, ou 404 se o job não existir ou não for seu.
Webhooks
Quando você fornece um callbackUrl, o WizCut manda uma requisição POST em JSON sempre que um job chega em um dos status abaixo. O WizCut tenta cada entrega até três vezes e espera até 10 segundos pela resposta do seu endpoint.
Os webhooks ainda não são assinados, então trate cada um como um sinal pra buscar o job com GET /api/jobs/{jobId} em vez de confiar no conteúdo dele. Faça polling como plano B também, caso alguma entrega se perca.
Webhook “mapping” (uma pessoa precisa confirmar quem tá em qual câmera):
{
"jobId": "uuid",
"status": "mapping",
"reviewUrl": "https://wizcut.com/jobs/uuid/edit?reviewToken=...",
"speakers": ["SPEAKER_00", "SPEAKER_01"],
"cameraMap": {
"version": 1,
"speakers": ["SPEAKER_00", "SPEAKER_01"],
"unassignedSpeakers": ["SPEAKER_01"],
"droppedSpeakers": [],
"cameras": [
{ "sourceId": "source-uuid-1", "kind": "closeup", "confidence": "high", "speakers": ["SPEAKER_00"], "...": "..." },
{ "sourceId": "source-uuid-2", "kind": "closeup", "confidence": "low", "speakers": ["SPEAKER_01"], "...": "..." }
]
}
}
Manda uma pessoa pra reviewUrl pra mapear os participantes nas fontes de câmera e revisar os cortes, ou mapeia eles via API. Os links de revisão valem por 72 horas. speakers lista os participantes detectados, do que mais fala pro que menos fala.
cameraMap é a proposta do WizCut, no mesmo formato do camera_map do job, veja O mapa de câmeras. Ele não vem quando ainda não tem proposta.
Quando esse webhook chega depende do autoMap:
"confident"ou"always": o job espera em “mapping” sem mandar webhook enquanto o WizCut descobre as câmeras, o que leva alguns minutos depois que os proxies ficam prontos. Aí ele ou mapeia as câmeras sozinho, e o próximo webhook que você recebe é o “ready”, ou manda “mapping” com a proposta anexada. Se o WizCut não conseguir calcular uma proposta (por exemplo, porque um proxy falhou), o “mapping” vai semcameraMap, no máximo uns 30 minutos depois da detecção de participantes."off": o “mapping” é enviado logo depois da detecção de participantes, normalmente semcameraMap. A proposta aparece noGET /api/jobs/{jobId}alguns minutos depois.
Webhook “ready” (mapeamento de participantes enviado, por uma pessoa, pelo seu código ou pelo WizCut, e cortes gerados):
{
"jobId": "uuid",
"status": "ready",
"reviewUrl": "https://wizcut.com/jobs/uuid/edit?reviewToken=..."
}
Webhook “complete” (render finalizado):
{
"jobId": "uuid",
"status": "complete",
"outputUrl": "https://presigned-download-url..."
}
Webhook “approved” (output aprovado via interface de revisão):
{
"jobId": "uuid",
"status": "approved",
"outputUrl": "https://presigned-download-url..."
}
Webhook “failed” (o job falhou, em qualquer etapa):
{
"jobId": "uuid",
"status": "failed",
"error": "description of what went wrong",
"failedAtStatus": "syncing"
}
error traz a mesma mensagem que o GET /api/jobs/{jobId} retorna em error_message, e failedAtStatus diz em qual etapa deu erro, tipo syncing, diarizing ou rendering. Na maioria das falhas de sincronização, detecção de participantes e render, o WizCut já tenta de novo uma vez sozinho: se esse webhook chegou, é porque a segunda tentativa também não deu certo.
O outputUrl nos webhooks “complete” e “approved” vale por sete dias depois que o render termina. O GET /api/jobs/{jobId} sempre retorna um output_url assinado na hora.
Mapeamento de participantes e revisão (human-in-the-loop)
Depois da detecção de participantes, o job entra no status “mapping”. Os participantes detectados precisam ser mapeados pras fontes de câmera: essa detecção identifica quando alguém fala, mas não em qual câmera essa pessoa aparece.
O WizCut tenta resolver isso por você. As pessoas se mexem quando falam: gesticulam, balançam a cabeça, se inclinam. Então o WizCut compara a fala de cada participante com o movimento de cada câmera e propõe quem tá em qual. O quanto ele decide sozinho é com você, via autoMap.
Quando precisa de uma pessoa, o WizCut manda o webhook “mapping”. Ele inclui uma reviewUrl, um link assinado pro editor do WizCut. Manda uma pessoa pra lá. No editor, ela vai:
- Conferir qual participante tá em qual câmera (as câmeras de que o WizCut tem certeza já vêm selecionadas)
- Visualizar e editar os cortes gerados automaticamente
- Clicar em “Render” quando estiver satisfeita (se
review: true, que é o padrão) - Opcionalmente clicar em “Approve” depois de revisar o output renderizado
Com review: false, a renderização começa automaticamente assim que o mapeamento de participantes é enviado, a pessoa não tem a chance de revisar os cortes antes de renderizar.
Mapeamento automático de câmeras
Defina autoMap quando criar o job:
| Modo | O que o WizCut faz | Escolha quando |
|---|---|---|
"off" | Nunca mapeia as câmeras sozinho. Manda “mapping” logo depois da detecção de participantes; a proposta aparece no job alguns minutos depois, pra uma pessoa ou o seu agente usar. | Uma pessoa sempre revisa o mapeamento de qualquer jeito. |
"confident" | Padrão. Mapeia as câmeras sozinho quando tem certeza de que achou um close de cada participante e depois segue pra “ready”. Senão, manda “mapping” com a proposta anexada. Uma câmera wide ou de dois planos é usada na edição, mas nunca conta como a câmera própria de um participante. | A maioria das integrações. Você só ouve falar do WizCut quando ele precisa de ajuda. |
"always" | Não espera por ninguém. Usa as respostas de que tem certeza, depois as prováveis, e coloca quem sobrar nas câmeras que restam por tempo de fala. Só manda “mapping” se não conseguir calcular nenhuma proposta (por exemplo, porque um proxy falhou). | Pipelines totalmente sem supervisão, que preferem receber uma edição no chute a um job parado. |
“Ter certeza de todo participante” quer dizer: todo mundo com pelo menos um minuto de fala tá numa câmera que o WizCut respondeu com confiança high. Câmeras de que ele não tem certeza ficam sem participantes, então a edição não corta pra elas. Se quiser que sejam usadas, ajuste isso no editor.
Conte com o “confident” chamar uma pessoa com certa frequência. Ele fica de pé atrás com material em que o movimento não acompanha um participante só: estúdios de TV com feeds alternados, eventos, câmeras na mão ou operadas. Ele também precisa de uns 20 minutos de conversa pra ter certeza, então clipes curtos normalmente acabam em “mapping”. Nos nossos testes até agora, o WizCut nunca colocou um participante na câmera errada quando disse que tinha certeza, mas a amostra ainda é pequena.
Combinados com review: false, "confident" e "always" significam que um job pode ser renderizado sem ninguém olhar. Esse é o objetivo em pipelines sem supervisão; se você quer que uma pessoa veja cada edição, mantenha review: true.
O mapa de câmeras
A proposta fica no job como camera_map (e no webhook “mapping” como cameraMap). Ela é null até ser calculada, o que leva alguns minutos depois que os proxies ficam prontos. Aqui vai um exemplo de um programa com duas pessoas, um close de cada uma e um plano aberto com as duas:
{
"version": 1,
"computedAt": "2026-10-01T09:42:17.000Z",
"speakers": ["SPEAKER_00", "SPEAKER_01"],
"unassignedSpeakers": [],
"droppedSpeakers": ["SPEAKER_02"],
"cameras": [
{
"sourceId": "source-uuid-1",
"kind": "closeup",
"confidence": "high",
"speakers": ["SPEAKER_00"],
"z": { "SPEAKER_00": 11.5, "SPEAKER_01": 0.9 },
"lagErrorS": { "SPEAKER_00": 0.1, "SPEAKER_01": 41.6 }
},
{
"sourceId": "source-uuid-2",
"kind": "closeup",
"confidence": "high",
"speakers": ["SPEAKER_01"],
"z": { "SPEAKER_01": 12.4, "SPEAKER_00": 1.3 },
"lagErrorS": { "SPEAKER_01": 0.2, "SPEAKER_00": 63.0 }
},
{
"sourceId": "source-uuid-3",
"kind": "twoshot",
"confidence": "high",
"speakers": ["SPEAKER_01", "SPEAKER_00"],
"positions": { "left": "SPEAKER_01", "right": "SPEAKER_00" },
"z": { "SPEAKER_00": 6.8, "SPEAKER_01": 5.2 },
"lagErrorS": { "SPEAKER_00": 0.3, "SPEAKER_01": 0.4 }
}
]
}
Por câmera:
| Campo | Descrição |
|---|---|
sourceId | Uma das fontes de vídeo do job. |
kind | O que a câmera mostra: closeup (uma pessoa), twoshot (duas pessoas lado a lado), wide (três pessoas), multi (várias pessoas, uma de cada vez, geralmente uma câmera operada ou com feed alternado) ou unknown. |
confidence | high (o WizCut tem certeza), low (uma resposta provável, mas sem certeza) ou none (sem resposta). |
speakers | Quem a câmera mostra. Vazio quando confidence é none. Em dois planos e wides, da esquerda pra direita. |
positions | Só em dois planos e wides: quem tá na left, no middle e na right do quadro. |
reason | Vem como no_motion quando não deu pra analisar a câmera de jeito nenhum. |
z, lagErrorS | Números de diagnóstico por participante: o quanto o movimento da câmera acompanha a fala dessa pessoa, e quantos segundos de diferença deu o melhor encaixe. Úteis pra depurar, mas não pra construir em cima. |
Nível superior:
| Campo | Descrição |
|---|---|
speakers | Os participantes que o WizCut avaliou: todo mundo com pelo menos um minuto de fala. |
unassignedSpeakers | Participantes avaliados que não estão em nenhuma câmera high. Se não estiver vazio, o “confident” deixa a decisão pra uma pessoa. |
droppedSpeakers | Participantes com fala curta demais pra avaliar, normalmente um rótulo perdido ou uma interjeição rápida. O WizCut não coloca eles numa câmera. |
Pra aceitar a proposta do jeito que tá, transforme cada câmera em que você confia num track (o sourceId e os speakers dela) e envie.
Mapear participantes via API
Se você já sabe quem senta na frente de qual câmera, ou o seu agente já conferiu a proposta, envie o mapeamento você mesmo enquanto o job estiver no status “mapping”:
POST /api/jobs/{jobId}/tracks
{
"tracks": [
{ "sourceId": "source-uuid-1", "speakers": ["SPEAKER_00"] },
{ "sourceId": "source-uuid-2", "speakers": ["SPEAKER_01"] }
]
}
Use os nomes de participante do webhook “mapping” (ou os turns do GET /api/jobs/{jobId}) e os IDs das suas fontes de vídeo. Uma câmera pode mostrar mais de um participante. Aí o WizCut gera os cortes, move o job pra “ready”, manda o webhook “ready” e, com review: false, começa o render. A resposta traz os novos cuts.
Todo sourceId precisa ser uma das fontes de vídeo do job; qualquer outro gera um 400 com "code": "UNKNOWN_SOURCE". Dá pra enviar enquanto o WizCut ainda tá descobrindo as câmeras: vale quem chegar primeiro. Se o mapeamento já foi enviado, por exemplo automaticamente, você recebe um 409 com "code": "INVALID_STATUS".
Avançado: corrigir um mapeamento depois que os cortes existem. Quando o job tá “ready” ou “complete”, o mesmo endpoint ainda consegue mudar o mapeamento, mas não gera mais os cortes por você: envie os cuts corrigidos junto com os tracks (e opcionalmente removedRanges), ou você recebe um 400 com "code": "CUTS_REQUIRED". O WizCut salva os dois juntos, então um recut posterior usa o mapeamento corrigido. Não manda webhook nem inicia render: dispare um se precisar de um novo output. O editor do WizCut faz tudo isso por você quando alguém corrige um mapeamento lá.
Remoção de silêncio
O WizCut consegue encurtar ou remover pausas longas automaticamente antes de gerar os cortes. Isso acontece primeiro, então a troca de câmera é decidida em cima da conversa já apertada, você nunca tem um corte pra uma câmera que perde a maior parte do seu tempo de tela pra uma pausa removida logo em seguida.
Ative com o campo silence na criação do job:
{ "silence": { "mode": "tighten" } }
Modos:
| Modo | Comportamento |
|---|---|
off | Mantém todas as pausas como gravadas (padrão quando silence é omitido). |
tighten | Encurta pausas longas pra um ritmo natural (~0,7 s). Recomendado: mantém a conversa soando humana. |
remove | Corta as pausas longas quase por completo, deixando só o padding necessário pra não cortar palavras. |
Ajustes finos opcionais (os padrões funcionam bem pra maioria das gravações):
| Campo | Padrão | Faixa | Descrição |
|---|---|---|---|
minPauseSec | 1.5 | 0.3–10 | Só pausas mais longas que isso são mexidas. |
keepPauseSec | 0.7 | 0–3 | O ritmo deixado no lugar de uma pausa apertada (só no modo tighten). |
paddingSec | 0.25 | 0–1 | Margem de segurança mantida em volta da fala em cada trecho removido. |
A detecção é conservadora: uma pausa só é removida onde a detecção de falantes e uma análise de energia do áudio concordam que tá quieto, então risadas e outros momentos que não são fala sobrevivem.
O objeto do job (GET /api/jobs/{jobId}) inclui removed_ranges: os trechos removidos em tempo da fonte como { startMs, endMs }, junto com cuts. O render final pula esses trechos; o editor de revisão mostra eles como seções restauráveis com hachura.
Mude isso depois do processamento com o endpoint de recut:
POST /api/jobs/{jobId}/recut
{ "silence": { "mode": "remove", "minPauseSec": 1.0 } }
O recut regenera os cortes e os trechos removidos a partir dos participantes já detectados, sem reprocessar, então retorna na hora com os novos cuts, removedRanges e savedMs (quanto mais curto o resultado fica). Passe { "mode": "off" } pra desligar a remoção de silêncio de novo; omita silence inteiramente pra manter a configuração salva do job.
Nota sobre cobrança: o uso é medido em minutos de entrada (o material que você envia), então a remoção de silêncio não muda o custo do job, só deixa o resultado mais enxuto.
Avançado: controle programático dos cortes
Pra pipelines totalmente automatizados que pulam a interface, deixa o WizCut mapear as câmeras ou mapeia os participantes via API e depois gerencie os cortes e a renderização você mesmo. Esses endpoints funcionam enquanto o job está “ready” ou “complete”:
Atualizar cortes:
PATCH /api/jobs/{jobId}/cuts
{
"cuts": [
{ "startMs": 0, "endMs": 5000, "sourceId": "source-uuid-1" },
{ "startMs": 5000, "endMs": 12000, "sourceId": "source-uuid-2" }
]
}
O mesmo endpoint também aceita removedRanges (array de { startMs, endMs }) pra editar diretamente os trechos de remoção de silêncio, por exemplo, pra restaurar uma pausa que a passada automática removeu. Você pode enviar cuts, removedRanges, ou os dois.
Acionar renderização:
POST /api/jobs/{jobId}/render
Funciona a partir de “ready”, ou de “complete” pra renderizar de novo depois de editar os cortes. Retorna { "jobId": "uuid", "status": "rendering" }, ou um 409 com "code": "NO_CUTS" se o job não tiver cortes pra renderizar.
Aprovar output:
POST /api/jobs/{jobId}/approve
Só funciona quando o job já está “complete”. Move ele pra “approved” e manda o webhook “approved”.
Respostas de erro
Todos os endpoints retornam erros neste formato:
{ "error": "Description of what went wrong" }
Alguns erros também trazem um code que dá pra ler por máquina:
| Code | HTTP | Significado |
|---|---|---|
TRACKS_ON_CREATE | 400 | O POST /api/jobs recebeu um mapeamento de participantes. Deixe tracks de fora e use autoMap, ou defina o mapeamento depois. |
UNKNOWN_SOURCE | 400 | Um track cita um sourceId que não é uma das fontes de vídeo do job. |
CUTS_REQUIRED | 400 | Mudar o mapeamento depois que os cortes existem exige também os cuts atualizados. |
NOT_ENOUGH_VIDEOS | 400 | O job precisa de pelo menos duas fontes de vídeo pra ser processado. |
QUOTA_EXCEEDED | 403 | Seus minutos acabaram. |
INVALID_STATUS | 409 | O job não tá num status que permite isso, por exemplo, o mapeamento dele já foi enviado. |
NO_CUTS | 409 | Não tem cortes pra renderizar. |
Códigos HTTP comuns:
| Código | Significado |
|---|---|
| 400 | Requisição inválida (ex.: menos de duas fontes de vídeo ao processar) |
| 401 | API key ausente ou inválida |
| 403 | Cota excedida |
| 404 | Job não encontrado ou não pertence a você |
| 409 | Transição de status inválida (ex.: renderizar um job que ainda não tá pronto) |
| 500 | Erro no servidor |
| 502 | Um serviço de processamento rejeitou o job ou falhou ao iniciar |
| 503 | Serviço indisponível |
Fluxo completo
O caminho feliz completo pra um agente de IA ou automação:
# 1. Criar um job com duas câmeras (arquivos de até 5 GB cada, passe
# fileSize pra ganhar upload multipart em arquivos maiores)
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. Enviar os vídeos pras URLs presigned
curl -X PUT -T camera1.mp4 "$(echo $JOB | jq -r '.uploads | to_entries[0].value.url')"
curl -X PUT -T camera2.mp4 "$(echo $JOB | jq -r '.uploads | to_entries[1].value.url')"
# 3. Iniciar o processamento
curl -s -X POST "https://wizcut.com/api/jobs/$JOB_ID/process" \
-H "Authorization: Bearer wc_live_your_key"
# 4. Esperar o próximo webhook. Com o autoMap padrão ("confident"):
# - { status: "ready", reviewUrl: "..." } — o WizCut mapeou as câmeras sozinho
# - { status: "mapping", reviewUrl: "...", speakers: [...], cameraMap: {...} }
# — ele não teve certeza. Mandar uma pessoa pra reviewUrl confirmar as câmeras
# (ou enviar o mapeamento você mesmo via POST pra /api/jobs/$JOB_ID/tracks)
# 5. A pessoa revisa e edita os cortes → clica em Render no editor
# Esperar o webhook: { status: "complete", outputUrl: "..." }
# 6. Baixar o vídeo renderizado da outputUrl
Totalmente sem supervisão (autoMap: "always", review: false):
# Igual acima, mas com "autoMap": "always" e "review": false no passo 1
# O WizCut mapeia as câmeras sozinho, mesmo quando não tem certeza,
# e começa a renderizar logo em seguida, sem nenhuma pessoa envolvida
# Você recebe: { status: "ready", ... } e depois { status: "complete", outputUrl: "..." }
Integrações
Prefere não escrever código? Você consegue usar a WizCut API direto de plataformas de automação, sem precisar montar nenhuma das requisições acima.
n8n
A gente mantém uma integração oficial com n8n, o community node verificado @wizcut/n8n-nodes-wizcut. Instale pelo Settings → Community Nodes dentro do n8n (já é verificado, então funciona no n8n Cloud também).
O node vem com dois blocos:
- WizCut: ações para Create Job, Get Job, Start Processing, Start Render e Approve.
- WizCut Trigger: um webhook trigger que inicia o seu workflow sempre que um job muda de status (mapping, ready, complete, approved).
Aponta a URL do trigger pro callbackUrl do job e você tem um pipeline totalmente orientado a eventos. Por exemplo: avisa no Slack quando o WizCut precisa que alguém confirme quem tá em qual câmera, começa o render automaticamente quando os cortes ficam prontos e posta o link de download quando o episódio tá finalizado. Os dois nodes também funcionam como ferramentas pra agentes de IA do n8n.
Quer sair com vantagem? Pega o template pronto: Notify and manage podcast edit status with WizCut and Slack.
Mais plataformas
As integrações com Make.com e Zapier estão no roadmap. Usando uma plataforma diferente ou precisa de um template de workflow pro seu setup específico? Fala com o suporte do WizCut, pedidos de novas funcionalidades são bem-vindos.