Eventi SMS
Ogni messaggio attraversa un ciclo di vita e Bird emette un evento a ogni passaggio. Questa pagina è il vocabolario completo degli eventi; la consegna degli eventi al tuo endpoint (firme, ripetizioni, replay) è trattata nella guida ai Webhook.
Il ciclo di vita della consegna, come percorso attraverso i tipi di evento:
- sms.accepted: Bird ha il messaggio e si sta preparando a passarlo a un operatore.
- sms.sent: Bird ha passato il messaggio all'operatore ed è in attesa di una ricevuta di consegna.
- Un evento terminale:
- sms.delivered: l'operatore ha confermato la consegna al dispositivo.
- sms.undelivered: l'operatore ha segnalato una mancata consegna temporanea, ad esempio un dispositivo non raggiungibile.
- sms.failed: un errore permanente ha impedito la consegna.
- sms.expired: l'operatore ha smesso di riprovare e ha segnalato il messaggio come scaduto.
Gli eventi terminali espongono la ricevuta di consegna dell'operatore, ciò che le piattaforme SMS chiamano delivery report o DLR.
L'eccezione è sms.rejected: il messaggio è stato rifiutato (da un controllo di policy, da un addebito non andato a buon fine o da un operatore che lo ha respinto) anziché tentato e perso. Un messaggio rifiutato durante l'elaborazione porta sms.rejected come unico evento.
Bird riceve anche le risposte. Quando un destinatario invia un SMS a uno dei tuoi numeri, Bird salva il messaggio ed emette sms.received, così puoi agire senza polling. Il payload contiene il corpo, la suddivisione in segmenti, entrambi i numeri e l'operatore quando il carrier lo comunica.
Bird valuta la risposta rispetto alle regole keyword di quel numero. Una keyword di stop supportata come STOP registra una soppressione mittente-destinatario e continua a emettere sms.received.
L'evento type è un enum aperto: Bird può aggiungere nuovi tipi di evento nel tempo, quindi tratta un type non riconosciuto come un evento futuro e non come un errore. Gestisci i tipi che ti servono e ignora il resto.
L'envelope dell'evento
Gli eventi arrivano al tuo endpoint webhook nell'envelope annidato Standard Webhooks descritto nella guida ai Webhook: tre campi, type, timestamp e un oggetto data specifico per tipo. L'identità dell'evento non è nel body: si trova nell'header webhook-id HTTP, che è stabile tra i tentativi di consegna dello stesso evento ed è la tua chiave di deduplicazione.
| Campo | Descrizione |
|---|---|
| type | Uno dei tipi di evento di questa pagina, ad esempio sms.delivered |
| timestamp | Quando si è verificato l'evento (RFC 3339); ordina per questo campo, mai per ordine di arrivo, perché le consegne non sono ordinate |
| data | Payload specifico dell'evento |
Il data di ogni evento SMS contiene sms_id, workspace_id e gli indirizzi to e from. Riporta anche tags e metadata dell'invio, così puoi instradare e correlare gli eventi senza un'altra ricerca. Ciascuno è null quando l'invio non ne conteneva.
Lo stesso oggetto contiene cost, il costo del messaggio a quel punto, suddiviso in transaction_amount e passthrough_amount con la somma in amount. È null su un evento che non ha calcolato alcun prezzo. Poiché le consegne non sono ordinate, unisci cost un componente alla volta invece di sostituire l'intero oggetto: per ogni componente, conserva il valore dall'evento con il timestamp più recente. Un amount somma solo i componenti nel proprio payload, quindi leggilo come il costo accumulato finora e non come un totale definitivo. Costi e fatturazione spiega il significato di ogni componente.
Esempio di codice
{
"type": "sms.delivered",
"timestamp": "2026-06-10T14:30:00Z",
"data": {
"sms_id": "sms_01krdgeqcxet5s7t44vh8rt9mg",
"workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
"to": "+15551234567",
"from": "+12025550188",
"carrier": "Example Wireless",
"mcc_mnc": "310260",
"cost": {
"amount": "0.00990",
"currency_code": "USD",
"transaction_amount": "0.00790",
"passthrough_amount": "0.00200"
},
"tags": [{ "name": "campaign", "value": "spring-2026" }],
"metadata": { "order_id": "ord_123" }
}
}Eventi del ciclo di vita
sms.accepted
Si attiva quando Bird accetta l'invio e inizia a prepararlo per passarlo a un operatore. Il payload aggiunge segments, la suddivisione Bird calcolata al momento dell'accettazione; il suo count è ciò su cui viene fatturato l'invio.
sms.sent
Si attiva quando Bird ha passato il messaggio all'operatore ed è in attesa di una ricevuta di consegna. Il payload aggiunge carrier e mcc_mnc (la rete di gestione e il relativo codice paese/rete mobile). Ciascuno è assente anziché null quando l'operatore non lo comunica. Per misurare la latenza di elaborazione, confronta il timestamp di questo evento con quello di sms.accepted.
sms.delivered
L'operatore ha confermato che il messaggio ha raggiunto il dispositivo. Il payload aggiunge carrier e mcc_mnc, ciascuno assente quando la ricevuta non li ha identificati.
Eventi di errore
Il payload di ogni evento di errore aggiunge un oggetto error: un code stabile tra Bird (ad esempio unreachable o blocked_by_carrier), un description leggibile, il carrier_error_code grezzo quando fornito, e occurred_at.
sms.undelivered
Una mancata consegna non permanente: il dispositivo era spento o non raggiungibile.
sms.failed
Un errore permanente di consegna ha bloccato il messaggio.
sms.rejected
Il messaggio è stato rifiutato dai controlli di Bird durante l'elaborazione, da un addebito non andato a buon fine o da un operatore che lo ha respinto. Un rifiuto blocca il messaggio prima che un tentativo di consegna riesca. Un wallet esaurito finisce qui con il codice di errore insufficient_balance, e un messaggio il cui addebito non è andato a buon fine non viene fatturato.
sms.expired
L'operatore ha smesso di tentare la consegna e ha segnalato il messaggio come scaduto. La scadenza proviene dalla ricevuta di consegna dell'operatore: Bird non imposta alcuna finestra di validità propria e non esegue alcun timer che termini un messaggio. Il error descrive perché il messaggio era ancora non consegnato quando l'operatore ha rinunciato, di solito unreachable: il dispositivo è rimasto spento o fuori copertura per tutto il tempo.
Eventi di soppressione
Oltre al ciclo di vita per messaggio, un evento segnala una modifica alla lista di soppressione dello spazio di lavoro: sms_suppression.created si attiva quando si apre una soppressione, che un destinatario abbia inviato una keyword di stop, che l'operatore abbia segnalato un opt-out o che qualcuno ne abbia aggiunta una manualmente. Il payload contiene il suppression_id, il numero del destinatario come destination, il originator a cui è legato il blocco (una soppressione SMS è la coppia esatta mittente-destinatario), il reason e il workspace_id, così il tuo sistema può replicare la lista senza polling:
Esempio di codice
{
"type": "sms_suppression.created",
"timestamp": "2026-08-25T14:52:03.192524705Z",
"data": {
"suppression_id": "ssu_01krdgeqcxet5s7t44vh8rt9mg",
"destination": "+15550001234",
"originator": "+15557654321",
"reason": "keyword_stop",
"workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf"
}
}Un opt-out a livello di spazio di lavoro registrato nella scheda Preferenze è una preferenza dichiarata e non una soppressione, e non attiva questo evento.
Leggere la timeline di un messaggio
I webhook consegnano gli eventi ai tuoi sistemi. Per una verifica una tantum, il log SMS visualizza lo stesso flusso come timeline con timestamp, dettagli dell'operatore ed errori. Per recuperare la timeline in modo programmatico, chiama GET /v1/sms/messages/{message_id}/events. Per leggere solo lo stato più recente, chiama GET /v1/sms/messages/{message_id}.
Passaggi successivi
- Webhook ed eventi: configura un endpoint, verifica le firme e gestisci i tentativi e il replay.
- Log SMS: ispeziona la timeline per messaggio generata da questi eventi.
- Invio SMS: imposta tags e metadata riportati su ogni evento.
Risorse correlate
Prosegui con la documentazione, le guide e gli esempi per questo argomento. Le risorse sono in inglese.
Comprendi il concettoOne-way and two-way SMSEsplora la funzionalitàTwo-way SMSSegui il percorso di apprendimentoBuild your first integration
Ottieni un brief di implementazione