waiaconnect

Documentazione / Completo

I 21 tipi di evento con il loro payload

Markdown

20 tipi a cui iscriversi + webhook.test (non iscrivibile). Un endpoint con una lista di events esplicita riceve SOLO quei tipi; lista vuota/omessa = tutti (quelli nuovi entrano da soli). Il data di ciascuno:

TipoSottoscrivibileDescrizione
message.received✓Un cliente ti ha scritto. data.message = oggetto messaggio di WhatsApp (testo/immagine/audio/…); data.contacts[] identifica il mittente.
message.echo✓🌟 Il punto di forza di Coexistence: un messaggio che il TITOLARE ha mandato DAL TELEFONO, con il suo contenuto. origin='device' (non consuma il piano). from = il tuo numero aziendale.
message.status✓Conferma di un messaggio che hai mandato tramite /v1. origin (api|device) distingue il tuo invio da quello fatto a mano dal telefono. Una conferma 'device' NON ha dietro un tuo messaggio — è previsto. Dal 29/09/2026 arriva anche quando Meta rifiuta il NOSTRO invio dopo il 202: status 'failed', stage 'send' (campo opzionale), failureCode (lo stesso catalogo di lastErrorCode) e messageId = il tuo msg_… (Meta non gli ha mai assegnato un wamid). Una sola volta per messaggio.
connection.created✓Si è collegato un numero nuovo (pannello od onboarding ospitato). Il tuo externalId viaggia nella busta → attiva il cliente finale nel tuo sistema.
connection.status_changed✓È cambiato lo stato di una connessione (es. status='disconnected'). Manda un avviso o metti in pausa gli invii a quel numero.
connection.usage_threshold_reached✓Il limite di UN numero (il suo monthlyMessageLimit) ha raggiunto il 70/90/100%. Viene emesso UNA volta per (numero, periodo, soglia). Quello commerciale: avvisa quel cliente finale o alzagli il tetto.
usage.threshold_reached✓La quota dell'ACCOUNT (somma di tutti i numeri) ha raggiunto una soglia. Esiste solo con un piano su misura con quota concordata: i piani pubblici non hanno tetto e non lo emettono. connection arriva a null, sequence 0.
history.synced✓(Coexistence) riepilogo di ogni blocco della cronologia che Meta sincronizza al collegamento: quante conversazioni e quanti messaggi, la fase e l'avanzamento (progress 100 = Meta ha finito). shared:false = il titolare non ha condiviso la sua cronologia nell'app. I messaggi arrivano in history.batch solo se si è scelto di riceverli prima di collegare.
history.batch✓(Coexistence) i messaggi della cronologia —fino a 6 mesi, entrambe le parti, senza gruppi—, se il titolare ha scelto di riceverla prima di collegare. Fino a 500 per evento, nel formato di Meta (message), con contact e direction. Deduplica per batchId: un blocco può arrivare due volte. Passa da una coda separata che non rallenta gli eventi in tempo reale. Con il tuo 2xx lo cancelliamo; altrimenti, dopo 7 giorni.
history.completed✓(Coexistence) non resta più niente della cronologia di quel numero da consegnare: quanti messaggi sono stati consegnati (via webhook o via API), quanti sono scaduti e quanti non è stato possibile salvare. Arriva una volta.
history.dropped✓(Coexistence) non siamo riusciti a salvare la cronologia di quel numero per consegnartela (reason: storage_limit, o disabled). Quello già salvato viene consegnato comunque. La cronologia resta sul telefono. Arriva una volta.
template.status_changed✓È cambiato lo stato di un modello su Meta (approvato, rifiutato, in pausa, disattivato, qualità o categoria). Porta il nuovo stato e il motivo del rifiuto tradotto. Arriva tramite una sincronizzazione periodica: con qualche minuto di ritardo.
template.draft_submitted✓Il tuo cliente finale ha proposto un modello da un link di proposta. La bozza NON è su Meta: arriva a Meta solo quando la approvi.
account.trial_warning✓La prova gratuita dell'account finisce presto (data.days = 7, 3 o 1). connection=null.
account.trial_expired✓La prova gratuita è finita: l'invio viene bloccato. La ricezione si interrompe 30 giorni dopo il blocco, con un avviso 7 giorni prima. connection=null.
subscription.activated✓(Fatturazione) il primo pagamento è stato confermato e l'account del cliente del rivenditore è diventato attivo. connection=null. Reagisci attivando il suo servizio.
subscription.cancelled✓(Fatturazione) disdetta dell'abbonamento. Continua a funzionare fino ad accessUntil; poi l'invio viene bloccato, e la ricezione si interrompe 30 giorni dopo il blocco (con un avviso 7 giorni prima). connection=null.
billing.payment_failed✓(Fatturazione) un addebito ricorrente non è andato a buon fine. Entra in avviso/periodo di tolleranza (non interrompe ancora niente). Sollecita il tuo cliente PRIMA dell'interruzione. connection=null.
billing.payment_recovered✓(Fatturazione) il pagamento è stato regolarizzato e l'account si è riattivato da solo. connection=null.
billing.amount_updated✓(Fatturazione) è cambiato l'importo del tuo prossimo rinnovo. Puoi mostrare l'importo al tuo cliente prima che venga addebitato. connection=null. ⚠ Con la tariffa fissa il cambiamento dipende dal PIANO o dal tasso di cambio: overageArs e overageMessages arrivano a 0 (solo un piano su misura con quota concordata li muove).
webhook.test—L'evento del pulsante 'Prova' del pannello. NON è sottoscrivibile: viene consegnato SEMPRE a quell'endpoint (anche se ha un elenco di eventi esplicito) per verificare connettività + firma. connection=null, data.test=true. Non trattarlo mai come traffico reale.
message.received — data
{
  "message": {
    "id": "wamid.HBgL…",
    "from": "5493511234567",
    "type": "text",
    "text": {
      "body": "hola"
    }
  },
  "contacts": [
    {
      "wa_id": "5493511234567",
      "profile": {
        "name": "Ana"
      }
    }
  ]
}
message.echo — data
{
  "origin": "device",
  "message": {
    "id": "wamid.HBgL…",
    "from": "5493516516690",
    "to": "5493511234567",
    "type": "text",
    "timestamp": "1754531482",
    "text": {
      "body": "te confirmo el turno para mañana 10hs"
    }
  }
}
message.status — data
{
  "messageId": "wamid.HBgL…",
  "status": "read",
  "origin": "device",
  "recipient": "5493511234567",
  "timestamp": "2026-08-06T00:31:25.000Z"
}
connection.created — data
{
  "status": "connected"
}
connection.status_changed — data
{
  "status": "disconnected",
  "previousStatus": "connected"
}
connection.usage_threshold_reached — data
{
  "scope": "connection",
  "threshold": 90,
  "used": 900,
  "limit": 1000,
  "period": "2026-08",
  "connection": {
    "id": "conn_4eede070e5a84d1590bdce2ea1d837bc",
    "label": "Farmacia López",
    "externalId": "farmacia-lopez"
  }
}
usage.threshold_reached — data
{
  "scope": "account",
  "threshold": 90,
  "used": 22610,
  "limit": 25000,
  "period": "2026-08"
}
history.synced — data
{
  "conversations": 34,
  "messages": 512,
  "shared": true,
  "phase": 0,
  "chunkOrder": 1,
  "progress": 55
}
history.batch — data
{
  "batchId": "hb_3c1f0a9b8e7d4c2b9a1f0e3d2c1b0a9f",
  "seq": 1,
  "phase": 1,
  "chunkOrder": 3,
  "progress": 40,
  "count": 2,
  "expiresAt": "2026-10-11T03:00:00.000Z",
  "messages": [
    {
      "contact": "5493511234567",
      "direction": "in",
      "message": {
        "id": "wamid.HBgL…",
        "from": "5493511234567",
        "timestamp": "1739230970",
        "type": "text",
        "text": {
          "body": "¿Tienen turno el lunes?"
        },
        "history_context": {
          "status": "READ"
        }
      }
    },
    {
      "contact": "5493511234567",
      "direction": "out",
      "message": {
        "id": "wamid.HBgM…",
        "from": "5493510000000",
        "timestamp": "1739231001",
        "type": "text",
        "text": {
          "body": "Sí, a las 10."
        },
        "history_context": {
          "status": "DELIVERED"
        }
      }
    }
  ]
}
history.completed — data
{
  "batches": 12,
  "delivered": 5480,
  "deliveredByWebhook": 5480,
  "deliveredByApi": 0,
  "expired": 0,
  "dropped": 0
}
history.dropped — data
{
  "reason": "storage_limit",
  "messages": 500
}
template.status_changed — data
{
  "template": {
    "name": "turno_confirmado",
    "language": "es_AR"
  },
  "event": "message_template_status_update",
  "status": "APPROVED",
  "category": "UTILITY",
  "qualityScore": null,
  "reason": null,
  "rejection": null
}
template.draft_submitted — data
{
  "draft": {
    "id": "tpl_…",
    "name": "promo_octubre",
    "language": "es_AR",
    "suggestedCategory": "MARKETING"
  },
  "proposedVia": {
    "linkId": "onb_…",
    "label": "Farmacia Centro"
  },
  "clientNotes": null,
  "precheck": {
    "warnings": []
  }
}
account.trial_warning — data
{
  "days": 3,
  "trialEndsAt": "2026-09-13T00:00:00.000Z"
}
account.trial_expired — data
{
  "trialEndsAt": "2026-09-13T00:00:00.000Z"
}
subscription.activated — data
{
  "planCode": "growth",
  "periodEnd": "2026-09-13T00:00:00.000Z"
}
subscription.cancelled — data
{
  "accessUntil": "2026-09-13T00:00:00.000Z"
}
billing.payment_failed — data
{
  "paymentId": "123456789",
  "amount": 59000,
  "currency": "ARS"
}
billing.payment_recovered — data
{
  "planCode": "growth",
  "paymentId": "123456789"
}
billing.amount_updated — data
{
  "totalArs": 52500,
  "baseArs": 52500,
  "overageArs": 0,
  "overageMessages": 0
}
webhook.test — data
{
  "type": "test",
  "test": true,
  "message": "WAIA Connect test event — your endpoint is reachable and verifying signatures. This is NOT real traffic."
}