Guias principais
API de gerenciamento de Webhooks
Configure notificações de tarefas através do Dashboard, API ou MCP, verifique assinaturas e solucione problemas de entrega.
Webhooks notificam seu aplicativo quando uma tarefa assíncrona é concluída, falha ou atinge o tempo limite. Configure-os em Dashboard → API → Webhooks, através da API de Gerenciamento ou através do perfil full do TokenLab MCP. Eles compartilham os mesmos endpoints de workspace e histórico de entrega.
Qual credencial usar
| Credencial | Propósito | Onde é usada |
|---|---|---|
Management Token mt-… | Criar, listar, atualizar, excluir, testar e rotacionar webhooks | Authorization: Bearer mt-… em /v1/management/webhooks* |
API key sk-… | Enviar solicitações de modelo e consultar o status da tarefa | APIs de Modelo e /v1/tasks/{id} |
Signing secret whsec_… | Verificar se uma notificação recebida é autêntica | Seu receptor; nunca use como um token Bearer de API |
Crie um Management Token em Dashboard → API → Management Tokens. Os tokens são vinculados ao workspace: escolha o mesmo workspace da API key que envia as tarefas. Um token não pode ler ou modificar os endpoints de outro workspace. API keys e signing secrets são rejeitados pela API de Gerenciamento. A configuração do Dashboard usa sua sessão de administrador do workspace logado.
Armazene mt-… e whsec_… em seu backend. Não os incorpore em códigos de navegador, prompts, arquivos de repositório ou URLs. Os Management Tokens também autorizam outras operações de gerenciamento de workspace; eles não são credenciais exclusivas para webhooks.
Configurar um endpoint
export TOKENLAB_MANAGEMENT_TOKEN="mt-your-management-token"
curl https://api.tokenlab.sh/v1/management/webhooks \
-H "Authorization: Bearer $TOKENLAB_MANAGEMENT_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"url":"https://your-app.example/webhooks/tokenlab","events":["task.completed","task.failed","task.timeout"],"description":"Production task results"}'A resposta 201 inclui um id e um secret de uso único que começa com whsec_. Armazene o secret antes de sair desta etapa. As respostas de listar/obter/atualizar nunca o expõem. Até 10 endpoints podem ser configurados por workspace. As URLs devem usar HTTPS público e não podem conter credenciais, query strings ou fragmentos. Redirecionamentos não são seguidos.
| Operação | Endpoint |
|---|---|
| Listar / Criar | GET / POST /v1/management/webhooks |
| Obter / Atualizar / Excluir | GET / PATCH / DELETE /v1/management/webhooks/{webhookId} |
| Rotacionar signing secret | POST /v1/management/webhooks/{webhookId}/rotate-secret |
| Enviar teste | POST /v1/management/webhooks/{webhookId}/test |
| Histórico de entrega | GET /v1/management/webhooks/{webhookId}/deliveries?page=1&limit=50 |
Pause com PATCH {"is_active":false}; retome com PATCH {"is_active":true}. Retomar redefine a contagem de falhas consecutivas. A rotação retorna um novo secret uma única vez; configure-o em seu receptor imediatamente. Solicitações já em trânsito podem ainda carregar a assinatura anterior, portanto, aceite brevemente ambos os secrets durante a rotação. A rotação não é reversível.
Eventos e payloads
As assinaturas cobrem futuros eventos de tarefas assíncronas terminais; resultados síncronos e tarefas históricas não são reproduzidos. Receba todas as tarefas do workspace para os tipos de evento selecionados e combine data.taskId com o ID retornado quando você criou a tarefa. Os campos de callback usam camelCase; os campos de resposta de gerenciamento usam snake_case.
{
"id": "event-unique-id",
"type": "task.completed",
"created": 1790000000,
"data": {
"taskType": "video",
"taskId": "ldtask_0123456789abcdef0123456789abcdef",
"model": "your-selected-model",
"durationMs": 42000,
"resultUrls": ["https://api.tokenlab.sh/v1/media-results/7c9e6679-7425-40de-944b-e07fc1f90ae7.mp4?token=…"],
"settledCost": 0.12
}
}| Evento | Dados |
|---|---|
task.completed | taskType, taskId, model opcional, durationMs, resultUrls, settledCost |
task.failed | taskType, taskId, error, errorCode, retryable, refundOutcome |
task.timeout | taskType, taskId, expectedTimeoutMs, actualWaitMs, refundIssued, resolutionSource, refundOutcome |
webhook.test | Mensagem de teste e assinaturas configuradas; enviado apenas pela operação de teste |
Cada entrada de resultUrls é uma URL de resultado de mídia do TokenLab válida por 30 dias. Consulte Retenção de dados.
Para task.timeout, expectedTimeoutMs é o limite de tempo configurado e actualWaitMs é o tempo de espera decorrido, ambos em milissegundos. refundIssued: true significa que o reembolso foi bem-sucedido ou já havia sido emitido; false não descarta um reembolso posterior. refundOutcome descreve o resultado do processamento do reembolso. Eventos de timeout não contêm durationMs.
Os campos dependem da tarefa e podem estar ausentes. Use GET /v1/tasks/{id} com a chave sk-… do workspace original para obter o resultado oficial e o status de cobrança. O campo retryable de um evento descreve a falha na geração; não é uma instrução para consultar uma tarefa terminal indefinidamente ou enviar automaticamente uma nova tarefa cobrável. Em task.failed, error, errorCode e retryable são o error_details.message, code e retryable públicos da tarefa, os mesmos valores que uma leitura de status retorna.
Verifique antes de processar
Cada POST inclui X-Webhook-ID, X-Webhook-Timestamp (segundos Unix) e X-Webhook-Signature (sha256=<hex>). Calcule o HMAC-SHA256 sobre a string de timestamp exata, um ponto e os bytes brutos do corpo da solicitação, usando o secret whsec_… completo. Não analise e reserialize o JSON antes da verificação.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyWebhook(rawBody, headers, secrets) {
const timestamp = headers['x-webhook-timestamp'];
const signature = headers['x-webhook-signature'];
if (typeof timestamp !== 'string' || !/^\d+$/.test(timestamp)) return false;
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
if (typeof signature !== 'string' || !/^sha256=[a-f0-9]{64}$/.test(signature)) return false;
const received = Buffer.from(signature.slice(7), 'hex');
return secrets.some(secret => {
const expected = createHmac('sha256', secret).update(timestamp + '.').update(rawBody).digest();
return timingSafeEqual(expected, received);
});
}Após a verificação, verifique se o id do corpo corresponde ao X-Webhook-ID, persista o ID do evento com seu item de trabalho atomicamente e retorne 2xx rapidamente. Processe trabalhos pesados a partir de sua própria fila. Desduplique pelo ID do evento dentro do endpoint receptor: as entregas podem se repetir e a ordem não é garantida. Uma tolerância de timestamp de cinco minutos limita a idade da reprodução; a desduplicação por ID evita o processamento repetido dentro dessa janela.
Retentativas e recuperação
Cada ciclo de entrega faz até três tentativas, aguardando 1 segundo e depois 4 segundos. Cada tentativa HTTP tem um timeout de 10 segundos e um novo timestamp/assinatura. Falhas de rede, 429 e 5xx são passíveis de retentativa. Outros 4xx, redirecionamentos e destinos de rede inválidos interrompem esse ciclo sem tentar novamente. Falhas transitórias podem acionar retentativas de eventos posteriores com o mesmo ID de entrega. Dez ciclos de falha consecutivos pausam automaticamente o endpoint.
Use a operação de teste e o histórico de entrega para ver outcome, http_status, attempts e delivered_at. Uma resposta de API de teste bem-sucedida (200) significa apenas que a tentativa foi registrada: verifique outcome == "delivered". Corrija o receptor, retome o endpoint e envie outro teste. O histórico contém metadados de entrega, não payloads; a reprodução manual de eventos antigos não está disponível. Mantenha os IDs das tarefas e reconcilie com o status da tarefa se o seu receptor estiver pausado ou indisponível.
Configuração do MCP
As ferramentas de gerenciamento de webhook estão disponíveis no perfil full. A credencial de gerenciamento é separada da chave de inferência; o catálogo e o gerenciamento de webhook podem funcionar sem uma chave de inferência.
{
"mcpServers": {
"tokenlab": {
"command": "npx",
"args": ["-y", "@tokenlabai/mcp-server@latest"],
"env": {
"TOKENLAB_MCP_TOOL_PROFILE": "full",
"TOKENLAB_MANAGEMENT_TOKEN": "mt-your-management-token",
"TOKENLAB_API_KEY": "sk-your-inference-key"
}
}
}
}Ferramentas: list_webhooks, create_webhook, get_webhook, update_webhook, delete_webhook, rotate_webhook_secret, test_webhook, list_webhook_deliveries. Nunca cole credenciais em um argumento de ferramenta. Conceda acesso de gerenciamento apenas a clientes MCP confiáveis.
Fallback de polling
Os webhooks não removem o acesso à consulta de status nem impõem um novo limite de polling. Se você fizer polling, use a poll_url da resposta de criação, aguarde enquanto estiver pendente e pare em estados terminais. Pare em 401, 403, 404 ou error.retryable == false; tente novamente falhas transitórias 503 async_task_owner_unavailable com backoff. Uma tarefa ausente ou expirada retorna 404 async_task_not_found. Consultar repetidamente uma tarefa ausente não pode recriá-la.
A callback_url da API de compatibilidade Seedance /api-reference/video/create-volc-compatible-seedance-task é um contrato de callback separado por solicitação. Ela pode ser definida ao criar essa tarefa; ela não usa esses payloads de evento de workspace ou cabeçalhos HMAC.