# wapp-api — callback Em vez de você consultar de tempos em tempos, **nós avisamos**: fazemos um `POST` numa URL sua. Peça a ativação informando a URL — precisa ser `https`. Dois eventos saem pela mesma URL, distinguidos pela chave `evento`: | `evento` | Quando | Ativado | |---|---|---| | `status` | mudou o estado de uma mensagem que você mandou | por padrão | | `mensagem_recebida` | alguém mandou mensagem para a sua instância | sob pedido | **Sempre ramifique pelo `evento`.** Podem entrar eventos novos no futuro; um receptor que assume um formato só quebra quando isso acontecer. ## evento `status` ```json POST https://seu-sistema.com.br/wapp/callback Content-Type: application/json; charset=utf-8 X-Wapp-Signature: 9f2b...c41e { "evento": "status", "id": 42, "status": "entregue", "numero_destino": "5547999998888", "instancia": "principal", "id_mensagem_wa": "3EB0F7BA9660A3BF84D92D", "erro": null, "em": "2026-08-28T17:10:00" } ``` | Campo | O que é | |---|---| | `id` | o mesmo id que o `POST /api/mensagens` devolveu | | `status` | `enviado`, `entregue`, `lido` ou `falhou` | | `numero_destino` | destino já normalizado | | `instancia` | o nome que você deu à instância | | `id_mensagem_wa` | id da mensagem no WhatsApp | | `erro` | preenchido só quando `status` é `falhou` | | `em` | quando a mudança foi registrada | Uma mensagem gera **vários** avisos ao longo da vida — normalmente `entregue` e depois `lido`. Trate cada um como uma atualização do mesmo `id`, não como mensagens diferentes. ## evento `mensagem_recebida` Chega quando alguém manda mensagem para a sua instância. Formato dos campos e cuidados de atendimento automático em `docs/api-entrada.md`; assinatura, retentativa e idempotência valem igual para os dois eventos. ## Confira a assinatura O corpo vai assinado com **HMAC-SHA256** usando um segredo que só você e nós temos, no header `X-Wapp-Signature`. Sem conferir, qualquer um que descubra a URL do seu sistema poderia forjar um "foi entregue". Assine os **bytes crus** do corpo, antes de qualquer parse: ```python import hashlib, hmac def valido(corpo_bytes, assinatura_recebida, segredo): esperada = hmac.new(segredo.encode(), corpo_bytes, hashlib.sha256).hexdigest() # compare_digest e não ==: comparação comum vaza tempo return hmac.compare_digest(esperada, assinatura_recebida or '') ``` ```php