Webhooks de Rastreio
Cadastre a URL no painel do time e receba cada mudança de status via HTTP POST, com assinatura HMAC, retry automático e auto-disable em falhas consecutivas.
Quando usar
Cadastre um webhook quando outro sistema da empresa (ERP, fila interna, BI) precisa saber na hora que o rastreio mudou — saiu para entrega, entregue, em devolução.
Quem pode fazer
Só dono ou admin do time criam, testam, desativam e excluem endpoints. Membros veem a tela, mas não gerenciam. Não há gate extra de plano para esta tela.
Pré-requisitos
- Uma URL HTTPS que responda 2xx aos POSTs da plataforma.
- Papel de dono ou admin na empresa.
Passo a passo (painel do time)
1. Abra Webhooks. No menu Integrações & API → Webhooks (selo Novo) você vê os endpoints da empresa. O contrato HTTP desta mesma página continua abaixo, para quem cadastra pela API.

Abrir Integrações e API → Webhooks no menu ao lado de Integrações e Chaves de API 2. Crie o endpoint. Clique em Novo webhook. Dê um nome, a URL HTTPS e marque os eventos (em curso, saiu para entrega, aguardando retirada, entregue, entre outros). O evento
defaultrecebe qualquer tipo.
Clicar em Novo webhook e informar nome, URL HTTPS e os eventos assinados 3. Copie o secret agora. O secret HMAC aparece uma vez. Guarde no cofre da empresa. Cada POST traz o header
X-SeuRastreio-Signature. A validação está na seção de autenticação abaixo — não duplicamos o schema aqui.
Copiar o secret HMAC que aparece uma única vez depois de criar o webhook 4. Teste e acompanhe as entregas. No card do endpoint, Enviar teste dispara um evento sintético. Ver entregas mostra tentativas, falhas e o último erro. Depois de falhas consecutivas o endpoint pode desligar sozinho: use Reativar. Não cole o secret em ticket.

Menu do webhook com Enviar teste, Ver entregas, Desativar e Excluir
Resultado esperado
Cada mudança do último evento do rastreio gera um POST na sua URL. Falhas entram em retry; o painel mostra o histórico. O contrato da API pública permanece nas seções seguintes.
Erros comuns (painel)
- Sem botão Novo webhook. Você está como membro. Peça a um dono ou admin.
- URL recusada. Use HTTPS. Endpoints que falham demais são desativados.
- Assinatura inválida no seu lado. Siga a seção de validação HMAC abaixo; o secret antigo deixa de valer se você rotacionar pela API.
Relacionados
Visão Geral
Webhooks disparam sempre que o último evento de um rastreio mudar, tanto para rastreios avulsos como para pedidos integrados (Loja Integrada, Nuvemshop etc.). Você cadastra endpoints HTTPs e escolhe quais tipos de evento cada endpoint assina.
Um evento pode gerar zero, um ou vários POSTs — um para cada endpoint elegível. As entregas são enfileiradas de forma durável, entregues por workers em background e reentregues com backoff em caso de falha (não bloqueiam o processamento da fila de rastreio).
Autenticação (gerenciamento via API)
Para cadastrar, listar e excluir webhooks via API, use o header Authorization: Bearer sr_live_.... Cada chave pertence a um time e só enxerga os webhooks do próprio time.
Authorization: Bearer sr_live_sua_chave_aquiTipos de evento
Ao criar um webhook você informa a lista de eventos assinados. Use default como catch-all para receber qualquer tipo.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
em_curso | evento | não | Objeto em trânsito (qualquer evento não-terminal). |
saiu_para_entrega | evento | não | Saiu para entrega ao destinatário (não inclui saída para o remetente). |
aguardando_retirada | evento | não | Objeto disponível para retirada na unidade indicada pela transportadora. |
em_devolucao | evento | não | Objeto em devolução — saiu para entrega ao remetente, não ao destinatário. |
devolvido | evento | não | Objeto entregue de volta ao remetente. |
entregue | evento | não | Entrega confirmada pelo rastreio. |
nao_postado | evento | não | Objeto postado (primeiro registro na transportadora). |
default | evento | não | Catch-all — recebe qualquer evento mesmo se os outros não estiverem na lista. |
Payload entregue
O corpo da requisição é JSON com o evento, informações do time, do rastreio e opcionalmente do pedido vinculado.
{
"id": "d1e5b8a3-...",
"event": "saiu_para_entrega",
"eventLabel": "Saiu para entrega",
"occurredAt": "2026-04-21T14:32:01.512Z",
"team": { "id": "team_abc", "slug": "minha-loja" },
"tracking": {
"codigo": "AA123456789BR",
"tipo": "normal",
"lastEventDescription": "Objeto saiu para entrega ao destinatário",
"lastEventLocation": "São Paulo/SP",
"lastEventAt": "2026-04-21T14:30:00.000Z"
},
"order": {
"orderId": "livexa_12345",
"status": "shipped",
"operationalStatus": "saiu_para_entrega"
}
}O campo order só está presente quando o evento foi disparado por uma atualização de pedido integrado.
Headers enviados
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
X-SeuRastreio-Event | string | sim | Tipo de evento (ex.: em_curso, entregue). |
X-SeuRastreio-Delivery | string | sim | Identificador único da tentativa de entrega (idempotência). |
X-SeuRastreio-Timestamp | string | sim | Unix timestamp (segundos) usado no cálculo do HMAC. |
X-SeuRastreio-Signature | string | sim | Assinatura HMAC-SHA256 no formato t=<unix_ts>,v1=<hex>. |
Verificando a assinatura (HMAC-SHA256)
Compute HMAC-SHA256(secret, `$`{timestamp}.{rawBody}$``) e compare com o valor de v1 em X-SeuRastreio-Signature. Use comparação em tempo constante (ex.: crypto.timingSafeEqual no Node).
import crypto from "node:crypto";
export function verifySeuRastreioSignature(
secret: string,
rawBody: string,
signatureHeader: string,
): boolean {
const parts = Object.fromEntries(
signatureHeader.split(",").map((p) => p.split("=") as [string, string]),
);
const ts = Number(parts.t);
const v1 = parts.v1;
if (!ts || !v1) return false;
// Rejeita requisições com mais de 5 minutos para mitigar replay.
if (Math.abs(Date.now() / 1000 - ts) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${ts}.${rawBody}`)
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(v1);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}X-SeuRastreio-Delivery como chave de idempotência no seu lado. O mesmo delivery pode ser re-tentado várias vezes em caso de timeout — processe uma vez só.Política de retry & auto-disable
Uma resposta HTTP 2xx conta como sucesso. Qualquer outro status, timeout (10s) ou erro de rede agenda nova tentativa com backoff crescente:
| Status | Significado |
|---|---|
1 | Após 1 minuto |
2 | Após 5 minutos |
3 | Após 30 minutos |
4 | Após 2 horas |
5 | Após 6 horas — se falhar, delivery marcado como failed |
Após 10 falhas consecutivas no mesmo endpoint, ele é desativado automaticamente (enabled = false). Reative pela dashboard ou enviando PATCH com enabled: true.
Endpoints REST para gerenciar webhooks
Listar webhooks do time
/api/public/webhookscurl -sS "https://seurastreio.com.br/api/public/webhooks" \
-H "Authorization: Bearer sr_live_sua_chave"Criar webhook
/api/public/webhooks| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
name | string | sim | Nome livre (máx. 120 caracteres). |
url | string | sim | URL HTTPS (HTTP permitido em dev). |
events | string[] | sim | Lista de eventos a assinar (ex.: ["em_curso","entregue"]). |
curl -sS -X POST "https://seurastreio.com.br/api/public/webhooks" \
-H "Authorization: Bearer sr_live_sua_chave" \
-H "Content-Type: application/json" \
-d '{
"name": "Integração ERP",
"url": "https://meu-erp.com/webhooks/seurastreio",
"events": ["em_curso","saiu_para_entrega","aguardando_retirada","em_devolucao","devolvido","entregue"]
}'A resposta (HTTP 201) inclui o campo secret em claro — guarde agora, pois ele não é exibido em chamadas posteriores.
Consultar webhook
/api/public/webhooks/{id}Atualizar webhook
/api/public/webhooks/{id}Aceita qualquer combinação de name, url, events e enabled. Enviar {"enabled": true} reativa um endpoint que tenha sido desabilitado automaticamente.
Excluir webhook
/api/public/webhooks/{id}Rotacionar o secret
/api/public/webhooks/{id}/rotate-secretGera um novo secret e invalida o anterior. A resposta expõe o novo secret em claro.
Disparar um evento de teste
/api/public/webhooks/{id}/testEnfileira um delivery sintético (event=default e _test: true no payload) para validar conectividade e assinatura.
Listar entregas recentes
/api/public/webhooks/{id}/deliveriesQuery opcional limit (default 50, máx 200). Retorna status, número de tentativas, último erro e nextAttemptAt.
Códigos de status (API de gerenciamento)
| Status | Significado |
|---|---|
200 | Operação bem-sucedida |
201 | Webhook criado |
202 | Delivery de teste enfileirado |
400 | Validação falhou (payload inválido) |
401 | Chave ausente ou inválida |
404 | Webhook não encontrado para o time |
500 | Erro interno |
- atualizadoEm
- superficie
- dashboard
- owner
- Technical Writer
- printsGeradosEm