Os mesmos webhooks do painel, gerenciados com a sua chave de API em /v1/webhooks: criar (POST /v1/webhooks), listar (GET /v1/webhooks), ver um (GET /v1/webhooks/:id), alterar (PATCH /v1/webhooks/:id), apagar (DELETE /v1/webhooks/:id), testar (POST /v1/webhooks/:id/test, um evento assinado enviado na hora) e trocar o segredo (POST /v1/webhooks/:id/rotate-secret). Um webhook sem connectionId é da conta; com ele, recebe só os eventos desse número e substitui o da conta para esse número. O número é indicado pelo conn_… ou pelo seu externalId, e assim volta em cada resposta (com o externalId ao lado): nunca um id interno. O segredo de assinatura (whsec_…) e o token de cabeçalho, se você pediu com headerToken: true, aparecem uma única vez.
O webhook que nasce com o cadastro. Se você integra com links de cadastro, mande webhook: { url, events } em POST /v1/onboarding-links: validamos ao criar o link e devolvemos o segredo nesse momento. Quando o seu cliente termina, o número nasce com o seu webhook, assinado com ESSE segredo, e antes de connection.created: esse evento já chega nele. Depois você o encontra com GET /v1/webhooks?externalId=….
# 1) onboarding link + the webhook of the number it will connect
curl -X POST https://api.waiaconnect.com/v1/onboarding-links \
-H "Authorization: Bearer wc_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"externalId": "pharmacy-42", "webhook": {"url": "https://api.yourcompany.com/hooks/connect", "events": ["connection.created", "message.received", "message.status"]}}'
# → { "url": "https://…/c/<token>", "publicId": "onb_…",
# "webhook": { "secret": "whsec_…", "createdOnCompletion": true, … } } ← store the secret NOW
# 2) after your customer connects: the number's webhooks, by your externalId
curl "https://api.waiaconnect.com/v1/webhooks?externalId=pharmacy-42" -H "Authorization: Bearer wc_live_YOUR_API_KEY"
# → { "webhooks": [ { "id": "wh_…", "connectionId": "conn_…", "externalId": "pharmacy-42", … } ] }
# 3) create one directly (connectionId = conn_… or your externalId; omit = account-wide)
curl -X POST https://api.waiaconnect.com/v1/webhooks \
-H "Authorization: Bearer wc_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://api.yourcompany.com/hooks/connect-2", "connectionId": "pharmacy-42"}'
# rotate the secret (the old one stops verifying at once)
curl -X POST https://api.waiaconnect.com/v1/webhooks/wh_…/rotate-secret -H "Authorization: Bearer wc_live_YOUR_API_KEY"Limite: 2 webhooks por número (um ativo e outro para migrar sem corte), 2 × os seus números para todos os de número juntos, e 5 da conta; os desligados também contam. Passar dele ao criar ou ao mover um para um número → 422 WEBHOOK_LIMIT_REACHED com details.scope, used e limit. Os que você já tinha acima continuam funcionando: dá para editar, testar, trocar o segredo e apagar.
Filtros da lista: ?connectionId=conn_… (ou o seu externalId), ?connectionId=none (só os da conta) ou ?externalId= (vazia se esse número ainda não existe). Um wh_… ou um número de outra conta dá o mesmo 404 que um que não existe.
Reconectar o mesmo número com um link que traz a mesma URL não soma outro webhook: atualiza esse, com o segredo do link novo. Se o cadastro falhar, não fica nenhum webhook.
Trocar o segredo vale na hora: a partir daí assinamos com o novo e o antigo deixa de verificar. Atualize no seu sistema em seguida.