Ir para o conteúdo

Webhooks

Assine eventos do XID e receba payloads HTTP assinados quando usuários, sessões e organizações forem alterados.

Ver como Markdown

Nomenclatura de eventos

Os eventos seguem o padrão <object>.<action>. Cada evento carrega um nome de tipo estável, um svix-id único e um timestamp ISO 8601.

Objeto Ações
user created, updated, deleted
session created, ended, removed, revoked
organization created, updated, deleted
organizationMembership created, updated, deleted
organizationInvitation created, accepted, revoked
organizationDomain created, updated, deleted, verified, verification_failed
authentication password_succeeded, password_failed, passkey_succeeded, passkey_failed, mfa_succeeded, mfa_failed, oauth_succeeded, oauth_failed, sso_succeeded, sso_failed, magic_auth_succeeded, magic_auth_failed, email_verification_succeeded, email_verification_failed, radar_risk_detected
connection activated, deactivated, deleted, saml_certificate_renewed, renewal_required
dsync activated, deleted, user.created, user.updated, user.deleted, group.created, group.updated, group.deleted, group.user_added, group.user_removed
role created, updated, deleted
permission created, updated, deleted
email created (disparado quando o desenvolvedor assume o envio)
sms created (disparado quando o desenvolvedor assume o envio)
billing subscription.created, subscription.updated, paymentAttempt.succeeded, paymentAttempt.failed

Estrutura do payload

Cada entrega de webhook é um HTTP POST com Content-Type: application/json. O corpo contém type, data e cabeçalhos de metadados de nível superior.

{
  "type": "user.created",
  "data": {
    "id": "usr_01abc",
    "email_addresses": [{ "email_address": "alice@example.com" }],
    "created_at": 1700000000000
  }
}

Verificação de assinatura

O XID assina cada entrega com HMAC-SHA256. Verifique a assinatura antes de processar o payload. Rejeite entregas com mais de 5 minutos para evitar ataques de replay.

Cabeçalho Descrição
svix-id ID de mensagem único. Use para deduplicar entregas repetidas.
svix-timestamp Segundos Unix em que a mensagem foi enviada.
svix-signature HMAC-SHA256 codificado em Base64 de ${svix-id}.${svix-timestamp}.${raw-body} usando o segredo de assinatura do endpoint.
// Node.js / Cloudflare Workers example
async function verifyWebhook(request, secret) {
  const svixId = request.headers.get('svix-id')
  const svixTimestamp = request.headers.get('svix-timestamp')
  const svixSignature = request.headers.get('svix-signature')
  const body = await request.text()

  // Reject messages older than 5 minutes
  const ts = Number(svixTimestamp)
  if (Math.abs(Date.now() / 1000 - ts) > 300) {
    throw new Error('webhook timestamp out of tolerance')
  }

  const signedContent = `${svixId}.${svixTimestamp}.${body}`
  const keyData = Uint8Array.from(atob(secret), c => c.charCodeAt(0))
  const key = await crypto.subtle.importKey(
    'raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']
  )
  const msgData = new TextEncoder().encode(signedContent)

  // svix-signature may contain multiple comma-separated values
  for (const sig of svixSignature.split(' ')) {
    const prefix = 'v1,'
    if (!sig.startsWith(prefix)) continue
    const sigBytes = Uint8Array.from(atob(sig.slice(prefix.length)), c => c.charCodeAt(0))
    const valid = await crypto.subtle.verify('HMAC', key, sigBytes, msgData)
    if (valid) return JSON.parse(body)
  }
  throw new Error('invalid webhook signature')
}

Tentativas e dead letters

  • Entregas com falha são repetidas com backoff exponencial. Após o número máximo de tentativas, a mensagem é gravada no armazenamento de dead-letter no D1 para inspeção manual.
  • A entrega é desacoplada do caminho de autenticação via Cloudflare Queues. Um endpoint lento ou indisponível não afeta a latência de login.
  • Use o cabeçalho svix-id para deduplicar entregas no seu lado. As tentativas carregam o mesmo svix-id da tentativa original.
flowchart LR
  XID --> Queue
  Queue -->|HTTPS| Endpoint
  Endpoint -->|2xx| ACK
  Endpoint -->|non-2xx| Retry
  Retry --> Queue
  Retry -->|max_retries| dlq["D1 DLQ"]

Repetição manual

Use POST /v1/webhooks/:endpointId/replay para repetir eventos por ID de mensagem ou intervalo de tempo. Eventos repetidos carregam novos valores de svix-id, mas preservam o type e os data originais.

# Replay events from the last hour
curl -X POST https://xid.dev/v1/webhooks/whe_xxx/replay \
  -H 'Authorization: Bearer sk_live_xxx' \
  -H 'Content-Type: application/json' \
  -d '{ "since": "2024-01-01T00:00:00Z", "until": "2024-01-01T01:00:00Z" }'

API de eventos

Além dos webhooks push, o XID expõe um fluxo de eventos ordenado e imutável com paginação por cursor em GET /v1/events. Consuma o fluxo para criar sincronização confiável sem perder eventos entre tentativas de webhook.

curl 'https://xid.dev/v1/events?limit=100&after=evt_xxx' \
  -H 'Authorization: Bearer sk_live_xxx'
Navegação

Digite para pesquisar...

Use as teclas de seta para navegarPressione Enter para selecionarPressione Escape para fechar