Skip to content
WhatIsUp.dev

Endpoints de webhook

Diga ao WhatIsUp.dev para onde entregar as notificações de evento. Um cliente pode ter múltiplos endpoints (URLs diferentes para subconjuntos diferentes de eventos). Um canal pode ser a origem de eventos para múltiplos endpoints, e um endpoint pode assinar múltiplos canais — é um relacionamento muitos-para-muitos.

Modelo conceitual

Endpoints descrevem uma assinatura: para onde enviar, quais eventos enviar, e o secret de assinatura usado no HMAC. Os registros de entrega de fato estão em Entregas de webhook.

api_key → customer ──┬── channel ◄───┐
                     │                 │
                     └── webhook_endpoint
                              │
                              └── webhook_delivery (per event)

Listar endpoints

GET/v1/webhook-endpointsBearer · API key

Retorna todos os endpoints do cliente autenticado.

Criar um endpoint

POST/v1/webhook-endpointsBearer · API key
Schema · Request body
FieldTypeRequiredNotes
urlstring · URLrequired
eventsarray<`message.received` \| `message.sent` \| `message.reaction` \| `message.status` \| `channel.connected` \| `channel.disconnected` \| `qr.updated` \| `group.created` \| `group.updated` \| `group.participant_added` \| `group.participant_removed` \| `group.admin_promoted` \| `group.admin_demoted` \| `chat.updated` \| `chat.archived` \| `chat.pinned` \| `presence.updated` \| `order.placed` \| `order.cancelled` \| `cart.updated` \| `story.viewed` \| `call.offered` \| `call.terminated` \| `contact.resolved`>required
channel_idstring · uuidoptional
signing_secretstringoptional
enabledbooleanoptional
chat_type_filter`all` \| `direct_only` \| `groups_only`optional
curl -sX POST "$WHATISUP_API/v1/webhook-endpoints" \
  -H "Authorization: Bearer $WHATISUP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://api.acme.dev/whatisup/webhook","events":["message.received","message.sent"],"channel_ids":["inst_01J..."]}'

A resposta inclui o secret de assinatura em texto puro — somente nesta chamada. Guarde-o; nunca mais mostramos. (Podemos rotacioná-lo; não conseguimos recuperá-lo.)

Schema · Response · WebhookEndpoint
FieldTypeRequiredNotes
idstring · uuidrequired
customer_idstring · uuidrequired
channel_idstring · uuidrequired · nullable
urlstring · URLrequired
eventsarray<`message.received` \| `message.sent` \| `message.reaction` \| `message.status` \| `channel.connected` \| `channel.disconnected` \| `qr.updated` \| `group.created` \| `group.updated` \| `group.participant_added` \| `group.participant_removed` \| `group.admin_promoted` \| `group.admin_demoted` \| `chat.updated` \| `chat.archived` \| `chat.pinned` \| `presence.updated` \| `order.placed` \| `order.cancelled` \| `cart.updated` \| `story.viewed` \| `call.offered` \| `call.terminated` \| `contact.resolved`>required
enabledbooleanrequired
has_custom_signing_secretbooleanrequired
chat_type_filter`all` \| `direct_only` \| `groups_only`required
created_atstring · ISO 8601required
updated_atstring · ISO 8601required

A url é validada contra SSRF no momento da criação e no momento da entrega (defesa contra DNS-rebind). IPs de loopback / link-local / RFC1918 / cloud-metadata são rejeitados com um 400. Em produção (NODE_ENV=production), apenas https:// é aceito.

Atualizar um endpoint

PATCH/v1/webhook-endpoints/:idBearer · API key
Schema · Request body
FieldTypeRequiredNotes
urlstring · URLoptional
eventsarray<`message.received` \| `message.sent` \| `message.reaction` \| `message.status` \| `channel.connected` \| `channel.disconnected` \| `qr.updated` \| `group.created` \| `group.updated` \| `group.participant_added` \| `group.participant_removed` \| `group.admin_promoted` \| `group.admin_demoted` \| `chat.updated` \| `chat.archived` \| `chat.pinned` \| `presence.updated` \| `order.placed` \| `order.cancelled` \| `cart.updated` \| `story.viewed` \| `call.offered` \| `call.terminated` \| `contact.resolved`>optional
signing_secretstring \| unknownoptional
enabledbooleanoptional
chat_type_filter`all` \| `direct_only` \| `groups_only`optional

Você pode rotacionar o secret de assinatura passando rotate_secret: true. O novo secret é retornado no corpo da resposta, exatamente uma vez. O secret antigo é invalidado imediatamente — verifique o rollout antes de virar a chave.

Excluir um endpoint

DELETE/v1/webhook-endpoints/:idBearer · API key

Retorna 204 No Content. Entregas em andamento que já foram enfileiradas vão falhar contra o endpoint agora excluído e esgotar o orçamento de retentativas normalmente.