Webhooks
Em vez de consultar a API repetidamente (polling), você pode registrar uma URL e receber uma requisição POST sempre que um evento relevante ocorrer — início de jogo, gol, encerramento, escalação, e mais.
Cada entrega é assinada (HMAC-SHA256) para que você confirme que a requisição veio da Dados Futebol e não foi adulterada.
Webhooks estão disponíveis em todos os planos, com cota de endpoints ativos e de entregas mensais por plano. Configure-os no painel em https://dadosfutebol.com.br/webhooks ou via API.
Catálogo de eventos
| Evento | Quando dispara |
|---|
partida.criada | Uma nova partida é cadastrada |
partida.ao_vivo | A partida entra em andamento |
partida.placar_atualizado | O placar muda |
partida.encerrada | A partida é encerrada |
partida.escalacao_publicada | A escalação é confirmada |
partida.estatisticas_atualizadas | As estatísticas ficam disponíveis |
rodada.encerrada | Uma rodada é concluída |
fase.finalizada | Uma fase de mata-mata é concluída |
Ao criar um webhook você escolhe quais eventos quer receber. O plano free recebe eventos apenas dos campeonatos aos quais tem acesso.
O corpo é sempre um JSON com este envelope:
{
"evento": "partida.encerrada",
"gerado_em": "2026-05-27T20:15:00-03:00",
"dados": {
"id": 1234,
"campeonato_id": 4,
"rodada_numero": 12,
"status": "encerrado",
"placar_mandante": 2,
"placar_visitante": 1,
"time_mandante": { "id": 1, "nome": "Flamengo", "sigla": "FLA" },
"time_visitante": { "id": 2, "nome": "Palmeiras", "sigla": "PAL" },
"estadio": "Maracanã"
}
}
O objeto em dados espelha o recurso correspondente da API (partida, rodada ou fase). Use o id/campeonato_id para buscar detalhes completos nos endpoints GET /v1/... quando precisar.
| Header | Descrição |
|---|
X-DF-Evento | Nome do evento (ex.: partida.encerrada) |
X-DF-Entrega | ID único da entrega — use para idempotência |
X-DF-Timestamp | Unix timestamp usado na assinatura |
X-DF-Assinatura | sha256=<hmac> do corpo (ver abaixo) |
Verificação da assinatura
Calcule o HMAC-SHA256 de "{X-DF-Timestamp}.{corpo_bruto}" usando o secret do seu webhook e compare, em tempo constante, com o header X-DF-Assinatura.
Use o corpo bruto da requisição (raw body), não o JSON já parseado e re-serializado — a ordem das chaves precisa ser idêntica à recebida.
import crypto from "crypto";
// req.body deve ser o corpo BRUTO (ex.: express.raw)
function verificar(req, secret) {
const assinatura = req.header("X-DF-Assinatura");
const timestamp = req.header("X-DF-Timestamp");
const corpo = req.body.toString("utf8");
const esperado = "sha256=" + crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${corpo}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(assinatura), Buffer.from(esperado));
}
Responda rapidamente com 2xx. Processe o evento de forma assíncrona se necessário — respostas lentas contam como falha.
Entrega e retentativas
- O seu endpoint deve responder com status
2xx. Qualquer outro status (ou timeout) é tratado como falha.
- Falhas são reenviadas com backoff crescente (segundos → minutos → 1 hora) por algumas tentativas.
- Após muitas falhas consecutivas o webhook é desativado automaticamente. Reative-o no painel após corrigir o endpoint.
- Cada entrega traz um
X-DF-Entrega único — armazene-o e ignore duplicatas (a entrega é at-least-once; a ordem não é garantida).
- A URL precisa usar HTTPS e apontar para um host público.
Cota de entregas
Cada plano inclui uma cota mensal de entregas bem-sucedidas (respostas 2xx). A contagem:
- Conta apenas entregas com resposta
2xx — retentativas por falha do seu endpoint não consomem a cota.
- É compartilhada entre todos os seus webhooks (somada por conta) e reseta no dia 1º de cada mês (UTC).
- Eventos de gerenciamento via API (criar, listar, testar etc.) usam a cota de requisições normal, não a de entregas.
Quando a cota mensal se esgota, novos eventos deixam de ser entregues até o reset: a entrega é registrada com status descartada (motivo Cota mensal de entregas excedida) e fica visível em GET /v1/webhooks/{id}/entregas. Nenhum POST é enviado ao seu endpoint.
Acompanhe o consumo no meta de GET /v1/webhooks:
{
"meta": {
"entregas_mes_usadas": 1240,
"entregas_mes_limite": 20000,
"entregas_referencia": "202605"
}
}
entregas_mes_limite retorna null quando ilimitado.
Gerenciamento via API
Além do painel, você pode gerenciar webhooks pela API (autenticada por API Key):
| Método | Rota | Descrição |
|---|
GET | /v1/webhooks | Lista seus webhooks |
POST | /v1/webhooks | Cria um webhook (retorna o secret uma única vez) |
GET | /v1/webhooks/{id} | Detalhe de um webhook |
PATCH | /v1/webhooks/{id} | Atualiza URL, eventos ou status |
DELETE | /v1/webhooks/{id} | Remove um webhook |
POST | /v1/webhooks/{id}/rotacionar-segredo | Gera um novo secret |
POST | /v1/webhooks/{id}/testar | Enfileira uma entrega de teste |
GET | /v1/webhooks/{id}/entregas | Histórico recente de entregas |
Criar um webhook
curl -X POST https://api.dadosfutebol.com.br/v1/webhooks \
-H "Authorization: Bearer SUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"nome": "Produção",
"url": "https://seu-dominio.com/webhook",
"eventos": ["partida.ao_vivo", "partida.placar_atualizado", "partida.encerrada"]
}'
{
"data": {
"id": 10,
"nome": "Produção",
"url": "https://seu-dominio.com/webhook",
"eventos": ["partida.ao_vivo", "partida.placar_atualizado", "partida.encerrada"],
"ativo": true,
"secret": "a1b2c3...«guarde com segurança»"
},
"mensagem": "Guarde o secret com segurança — ele não será exibido novamente."
}
O secret só aparece na criação e ao rotacionar. Se perdê-lo, gere um novo em POST /v1/webhooks/{id}/rotacionar-segredo.
Omita eventos (ou envie todos) para receber o catálogo completo.
Cotas por plano
| Plano | Webhooks ativos | Entregas / mês |
|---|
| Free | 1 | 500 |
| Pro | 5 | 20.000 |
| Enterprise | Sob demanda | 200.000 (ajustável) |
Exceder a cota de endpoints ativos retorna HTTP 422 na criação:
{
"erro": "Limite do plano",
"mensagem": "Seu plano permite no máximo 1 webhook(s) ativo(s). Faça upgrade ou desative um existente."
}