API

Verificar firmas sin compartir el App Secret

Verificación de mensajes por número y eventos administrativos admitidos por cuenta de WhatsApp.

Revisado el 28 de septiembre de 2026 · WhatsAut

Qué pasa por WhatsAut

Meta sigue entregando al webhook de tu sistema. Si elegís verificación remota, tu receptor envía una copia de los bytes originales a WhatsAut. El servidor verifica firma y pertenencia a la conexión en memoria; no persiste el cuerpo, sus mensajes ni el destinatario.

No es verificación sin acceso al contenido: WhatsAut recibe el cuerpo para calcular HMAC. No uses esta opción si tu política exige que el contenido nunca pase por WhatsAut. No publiques la clave en el navegador ni registres el cuerpo en proxies de tu integración.

Meta no aplica overrides WABA a todos los campos: eventos de cuenta y plantillas se entregan al callback de la aplicación. Este verificador valida un cuerpo que tu sistema haya recibido; no suscribe ni reenvía eventos administrativos hacia el webhook externo.

Contrato HTTP

POST /api/runtime/v1/webhooks/verify con Content-Type: application/json, Authorization: Bearer de una clave webhooks:verify y el encabezado X-Hub-Signature-256 original. Enviá los bytes intactos, sin volver a serializar JSON. Máximo 1 MiB.

El servicio valida HMAC-SHA256 sobre el cuerpo completo. Para messages exige entry.id de la WABA y metadata.phone_number_id del número de la clave, con mensajes o estados no vacíos. Para cambios administrativos usa el contrato por WABA de la sección siguiente. Un lote mixto debe superar todas las comprobaciones; no lo dividas ni reserialices para reutilizar la firma.

curl --request POST 'https://whatsaut.com/api/runtime/v1/webhooks/verify' \
  --header "Authorization: Bearer $WHATSAUT_VERIFY_KEY" \
  --header "X-Hub-Signature-256: $META_SIGNATURE" \
  --header 'Content-Type: application/json' \
  --data-binary @evento-original.json

Eventos administrativos por WABA

account_update admite ACCOUNT_DELETED, ACCOUNT_OFFBOARDED, ACCOUNT_RECONNECTED, PARTNER_ADDED, PARTNER_REMOVED, PARTNER_APP_INSTALLED y PARTNER_APP_UNINSTALLED. Otros eventos de cuenta, campos desconocidos o estructuras no admitidas devuelven 422; no se afirma cobertura completa de Meta.

En eventos ACCOUNT_* admitidos, entry.id debe coincidir con la WABA de la conexión. En PARTNER_* el destino es value.waba_info.waba_id: entry.id puede identificar al socio y no se usa como destino alternativo. Se exige owner_business_id y se compara con el negocio Meta guardado cuando está disponible. Los eventos de instalación/desinstalación requieren partner_app_id. PARTNER_REMOVED puede incluir disconnection_info con reason e initiated_by documentados.

business_capability_update usa entry.id como WABA. Admite max_daily_conversations_per_business (entero desde -1 o TIER_250, TIER_2K, TIER_10K, TIER_100K, TIER_UNLIMITED), max_phone_numbers_per_business y max_phone_numbers_per_waba (enteros no negativos). Conserva compatibilidad con el campo antiguo max_daily_conversation_per_phone, entero desde -1. La referencia Meta mezcla niveles de texto y un ejemplo numérico; se admiten ambas formas sin convertirlas. No se aceptan booleanos, valores null ni un objeto vacío.

Estos cambios requieren entry.time entero no negativo. No necesitan phone_number_id y pueden verificar con una clave de cualquier número activo de esa WABA dentro del mismo negocio. La respuesta conserva valid, connection_id y body_sha256: connection_id identifica la clave usada, no un teléfono inferido del evento.

La verificación no guarda el evento ni aplica bajas, reconexiones, cambios de límites, alertas o envíos. Tampoco demuestra actividad del teléfono ni actualidad del estado: un evento firmado puede ser antiguo o repetido. Tu receptor debe deduplicar y evaluar la antigüedad antes de actuar.

Qué significa valid=true

La respuesta exitosa incluye valid, connection_id y body_sha256. Comprobá que el hash corresponde a los bytes que vas a procesar. Guardá o deduplicá el evento en tu receptor antes de efectos externos.

La firma no prueba que el evento sea nuevo: los reenvíos de un evento firmado pueden volver a validar. La deduplicación y la gestión de antigüedad corresponden a tu sistema. Ante error o indisponibilidad, no ejecutes acciones sin verificar.

Límites y exclusiones

Máximo 120 intentos por conexión y minuto. Firma inválida: invalid_signature (403). Otro activo: asset_mismatch (403). Evento no soportado: unsupported_event (422). Cuerpo inválido: invalid_payload (400). Servicio sin configuración: verification_unavailable (503). Los errores comunes de autenticación, tamaño y frecuencia son los de Runtime API.

Este endpoint no verifica pings sintéticos, historial, contactos ni eventos administrativos fuera del subconjunto documentado. El ping inicial y las pruebas del panel tienen una firma separada X-WhatsAut-Test-Signature-256, verificable localmente con el helper verify_test_ping y tu verify token. Una WABA compartida con otro negocio no desconectado devuelve shared_waba (409). Una conexión inactiva o clave revocada no puede verificar, incluso si el evento anuncia una baja. No desactives la autenticación para procesar casos no admitidos.

¿Necesitás ayuda? Prepará tu consulta para soporte →