Invio delle verifiche
Verificare un utente richiede due chiamate. POST /v1/verify/verifications invia un codice di verifica a un indirizzo email o a un numero di telefono. POST /v1/verify/verifications/check invia il valore digitato dall'utente e indica se corrisponde. Bird genera il codice, non lo restituisce nella risposta API, e applica la scadenza e i limiti di tentativi.
Inviare un codice
La richiesta valida più semplice è un destinatario to:
const verification = await bird.verify.verifications.create({
to: { phone_number: "+15551234567" },
});
console.log(verification.id, verification.status);verification = client.verify.verifications.create(to={"phone_number": "+15551234567"})
print(verification.id, verification.status)verification, err := client.Verify.Verifications.Create(context.Background(), bird.VerifyVerificationsCreateParams{
To: bird.VerificationTo{PhoneNumber: bird.String("+15551234567")},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(verification.Id, *verification.Status)$verification = $bird->verify->verifications->create(
(new VerificationCreateRequest())->setTo((new VerificationTo())->setPhoneNumber('+15551234567')),
);
echo $verification->getId(), ' ', $verification->getStatus();bird verify verifications create --body-file - <<'JSON'
{
"to": {
"phone_number": "+15551234567"
},
"metadata": {
"correlation_id": "signup-7f3a"
}
}
JSONcurl -X POST https://us1.platform.bird.com/v1/verify/verifications \
-H "Authorization: Bearer bk_us1_..." \
-H "Content-Type: application/json" \
-d '{
"to": { "phone_number": "+15551234567" }
}'Usa il tuo host regionale (https://us1.platform.bird.com o https://eu1.platform.bird.com) con una chiave bk_{region}_... corrispondente.
Destinatario
to identifica il destinatario con un email, un phone_number in formato E.164, o entrambi. Un indirizzo email abilita la consegna via email. Un numero di telefono si risolve nei canali disponibili nel paese di destinazione, nell'ordine stabilito dalla configurazione paese. La maggior parte dei paesi prova WhatsApp prima di SMS, mentre alcuni provano SMS per primo; Telegram segue entrambi nell'ordine di fallback della piattaforma. Quando fornisci entrambi gli indirizzi, un tentativo fallito può passare a un altro canale disponibile.
Opzioni
options sovrascrive le impostazioni solo per questa richiesta:
code_length: lunghezza del codice di verifica per questa verifica, da 4 a 8 cifre, in sostituzione del valore predefinito.channels: riordina o restringe i canali di consegna per questa richiesta. Elenca i nomi dei canali (sms,whatsapp,email,telegram) nell'ordine in cui provarli; un canale che ometti non viene usato, e un nome non presente nel piano risolto del destinatario viene ignorato. Non puoi aggiungere un canale in questo modo, solo ridurre o riordinare quelli già consentiti dal destinatario e dalla configurazione paese; una lista che non lascia alcun canale utilizzabile fa fallire la richiesta con422.language: un tag BCP 47 comefropt-BRche seleziona quale traduzione integrata usa il messaggio con il codice. Se lo ometti, la lingua segue il numero di telefono del destinatario; vedi Lingua del messaggio.
Metadati
metadata è un oggetto a formato libero restituito a ogni lettura; usalo per portare il tuo user ID o riferimento di sessione. Le scelte sul mittente e le impostazioni di verifica non viaggiano nella richiesta: provengono dalla configurazione del tuo spazio di lavoro, gestita nella dashboard (vedi Impostazioni di verifica).
La risposta
{
"id": "vrf_01ky7q1fdze3695yvyz7z9nm3a",
"status": "pending",
"reason": null,
"to": { "phone_number": "+15551234567" },
"channels": [{ "channel": "whatsapp" }, { "channel": "sms" }],
"last_channel": "whatsapp",
"expires_at": "2026-07-23T14:55:58Z",
"verified_at": null,
"created_at": "2026-07-23T14:45:58Z",
"updated_at": "2026-07-23T14:45:58Z"
}channels è il piano di consegna ordinato a cui questa verifica si è risolta (un destinatario telefonico elenca i suoi canali telefonici in ordine di tentativo), e last_channel indica dove è stato inviato il codice più recente. expires_at indica quando la verifica scade se non arriva un codice corretto; i reinvii non la estendono.
Lingua del messaggio
I messaggi SMS, email e WhatsApp condivisi di Bird sono disponibili in 40 traduzioni integrate. Un mittente WhatsApp personalizzato usa le lingue approvate del template di autenticazione selezionato. Telegram compone un proprio messaggio, quindi l'impostazione non ha effetto su quel canale.
Senza options.language, la lingua deriva dal numero di telefono del destinatario. Un numero francese riceve il messaggio in francese e un numero giapponese in giapponese, senza che tu lo richieda. Una verifica senza numero di telefono invia in inglese, come una il cui paese non ha traduzione.
Imposta options.language per scegliere tu stesso, ad esempio per usare la lingua selezionata dall'utente nella tua app invece del paese del suo numero:
{
"to": { "phone_number": "+15551234567" },
"options": { "language": "es" }
}Un tag privo di traduzione integrata ricade sulla lingua base, poi sull'inglese: en-GB invia in inglese, pt-BR invia in portoghese. Solo un tag malformato viene rifiutato, con 422. Queste sono le traduzioni integrate disponibili, tutte utilizzabili su SMS ed email, e tutte tranne il mongolo sul mittente WhatsApp condiviso di Bird:
| Lingua | Tag |
|---|---|
| Arabo | ar |
| Bulgaro | bg |
| Cinese (semplificato) | zh |
| Cinese (tradizionale) | zh-TW |
| Croato | hr |
| Ceco | cs |
| Danese | da |
| Olandese | nl |
| Inglese | en |
| Finlandese | fi |
| Francese | fr |
| Tedesco | de |
| Greco | el |
| Ebraico | he |
| Hindi | hi |
| Ungherese | hu |
| Indonesiano | id |
| Italiano | it |
| Giapponese | ja |
| Coreano | ko |
| Lettone | lv |
| Lituano | lt |
| Macedone | mk |
| Malese | ms |
| Mongolo | mn |
| Norvegese | no |
| Norvegese Bokmål | nb-NO |
| Polacco | pl |
| Portoghese | pt |
| Rumeno | ro |
| Russo | ru |
| Serbo | sr |
| Slovacco | sk |
| Sloveno | sl |
| Spagnolo | es |
| Svedese | sv |
| Thailandese | th |
| Turco | tr |
| Ucraino | uk |
| Vietnamita | vi |
Il reference di create-verification è la lista autorevole.
La lingua viene fissata quando la verifica viene creata, quindi un reinvio o un passaggio a un altro canale arriva nella stessa lingua del primo messaggio. Chiamare di nuovo create per lo stesso destinatario con un language diverso riutilizza la verifica in corso e non la modifica.
La traduzione effettivamente usata nell'invio può differire dal tag inviato, se è intervenuto un fallback. Apri la verifica nella pagina Verifications per controllare: ogni tentativo mostra la lingua renderizzata come tag Template. Il mittente WhatsApp condiviso di Bird non ha un template per il mongolo (mn), quindi invia in inglese per quella lingua, mentre SMS ed email mantengono il mongolo. Il tuo template WhatsApp personalizzato segue le lingue approvate e la relativa policy linguistica; una lingua che non può inviare può far fallire il tentativo WhatsApp.
Puoi selezionare una lingua per ogni richiesta, ma non puoi inviare il testo del messaggio con quella richiesta. Un mittente WhatsApp personalizzato usa il testo del template di autenticazione selezionato. Senders and branding illustra le opzioni di mittente e il testo del messaggio di Bird.
Controllare il codice
Invia qualsiasi cosa l'utente abbia digitato a POST /v1/verify/verifications/check, identificando con lo stesso destinatario; non serve l'ID della verifica. Fornisci esattamente il set to con cui hai creato la verifica: una creata con entrambi gli indirizzi non viene trovata con uno solo dei due.
const result = await bird.verify.verifications.check({
to: { phone_number: "+15551234567" },
code: "123456",
});
console.log(result.success);result = client.verify.verifications.check(
to={"phone_number": "+15551234567"}, code="123456"
)
print(result.success)result, err := client.Verify.Verifications.Check(context.Background(), bird.VerifyVerificationsCheckParams{
To: bird.VerificationTo{PhoneNumber: bird.String("+15551234567")},
Code: "123456",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(*result.Success)$result = $bird->verify->verifications->check(
(new VerificationCheckRequest())
->setTo((new VerificationTo())->setPhoneNumber('+15551234567'))
->setCode('123456'),
);
echo $result->getSuccess() ? 'verified' : 'failed';bird verify verifications check 123456 --phone-number +15551234567curl -X POST https://us1.platform.bird.com/v1/verify/verifications/check \
-H "Authorization: Bearer bk_us1_..." \
-H "Content-Type: application/json" \
-d '{
"to": { "phone_number": "+15551234567" },
"code": "123456"
}'La risposta indica se il codice corrisponde:
{
"success": false,
"reason": "incorrect_code",
"attempts_remaining": 4,
"verification": {
"id": "vrf_01ky7q1fdze3695yvyz7z9nm3a",
"status": "pending",
"reason": null,
"to": { "phone_number": "+15551234567" },
"channels": [{ "channel": "whatsapp" }, { "channel": "sms" }],
"last_channel": "whatsapp",
"expires_at": "2026-07-23T14:55:58Z",
"verified_at": null,
"created_at": "2026-07-23T14:45:58Z",
"updated_at": "2026-07-23T14:46:38Z"
}
}Gestisci questi due comportamenti della risposta:
- Un codice errato restituisce
200. Trattasuccess: falsecon unreason(incorrect_code,expired,attempts_exhausted) come una risposta normale.attempts_remainingindica quanti tentativi restano. Riserva la gestione degli errori ai fallimenti della richiesta. - Una verifica in stato finale non può essere controllata di nuovo. Dopo che una verifica raggiunge uno stato finale, ulteriori controlli restituiscono
404. Conserva il primo risultato definitivo invece di controllare di nuovo.
Se l'utente chiede un nuovo codice, chiama di nuovo l'endpoint create con lo stesso destinatario: la verifica in corso viene riutilizzata, non sostituita. Trascorso il cooldown di reinvio (60 secondi per impostazione predefinita) viene inviato un nuovo codice; entro il cooldown la chiamata restituisce la verifica attiva senza inviare di nuovo. Ogni codice inviato per la verifica attiva resta valido finché non si risolve o scade, quindi l'utente può inserire qualunque codice sia arrivato.
Inviare il codice su un altro canale
Quando l'utente segnala che il codice non è arrivato, POST /v1/verify/verifications/next-channel fa avanzare la verifica al canale successivo nel piano e invia lì un nuovo codice. È l'endpoint dietro un pulsante "I didn't receive my code": la tua app decide di cambiare canale anziché attendere un segnale sullo stato di consegna.
Identificalo con lo stesso destinatario con cui hai creato la verifica, come per un controllo:
const verification = await bird.verify.verifications.nextChannel({
to: { phone_number: "+15551234567" },
});
console.log(verification.last_channel);verification = client.verify.verifications.next_channel(
to={"phone_number": "+15551234567"}
)
print(verification.last_channel)verification, err := client.Verify.Verifications.NextChannel(context.Background(), bird.VerifyVerificationsNextChannelParams{
To: bird.VerificationTo{PhoneNumber: bird.String("+15551234567")},
})
if err != nil {
log.Fatal(err)
}
if verification.LastChannel != nil {
fmt.Println(*verification.LastChannel)
}$verification = $bird->verify->verifications->nextChannel(
(new VerificationNextChannelRequest())->setTo((new VerificationTo())->setPhoneNumber('+15551234567')),
);
echo $verification->getLastChannel();bird verify verifications next-channel --phone-number +15551234567curl -X POST "https://{region}.platform.bird.com/v1/verify/verifications/next-channel" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": {
"phone_number": "+15551234567"
}
}'La risposta è la verifica, con last_channel che indica il canale a cui è stato inviato il nuovo codice. Ogni codice già inviato resta valido, quindi un messaggio arrivato in ritardo può ancora essere controllato.
Due aspetti lo distinguono da un reinvio:
- Il cooldown di reinvio non si applica. Un cambio di canale deliberato è un'azione diversa dal richiedere lo stesso canale, quindi l'invio parte immediatamente.
- Solo il canale avanza. La scadenza, il budget di tentativi e l'ID della verifica restano invariati.
Usa un reinvio quando l'utente vuole riprovare su un canale che funziona, e questo endpoint quando il canale stesso sembra essere il problema. Un numero di telefono il cui piano è WhatsApp poi SMS avanza a SMS; un destinatario con un solo canale utilizzabile non ha dove andare.
Quattro risposte richiedono una gestione specifica anziché un semplice riprovare:
| Stato | Cosa è successo | Cosa fare |
|---|---|---|
404 | Nessuna verifica in corso per quel destinatario | Creane una |
422 NoNextChannel | Il piano non ha altri canali a cui avanzare | Reinvia sul canale corrente chiamando di nuovo create |
422 NoAvailableChannel | Tutti i canali rimanenti non sono riusciti a inviare | Mostra il fallimento all'utente; la verifica non può essere consegnata |
429 | Gli invii per l'account vengono richiesti troppo rapidamente | Attendi per il periodo indicato nell'header Retry-After |
Ogni codice inviato da questo endpoint viene fatturato come qualsiasi altro invio Verify; vedi Costi e fatturazione.
Stati
Una verifica è pending finché non si risolve in uno stato finale, con reason che ne indica il motivo:
| Stato | Significato | Motivo |
|---|---|---|
verified | Un codice corretto è arrivato in tempo | nessuno |
failed | Troppi tentativi errati, oppure il piano di consegna si è esaurito con errori che indicano che nessun codice di verifica è stato inviato | attempts_exhausted, undeliverable |
expired | La finestra temporale è scaduta prima dell'arrivo di un codice corretto | ttl_elapsed |
reason è un enum aperto. Conserva un valore non riconosciuto invece di trattare la risposta come non valida.
Un bounce, un rifiuto dell'operatore o un timeout di consegna possono lasciare la sessione in sospeso perché il destinatario potrebbe ancora avere un codice valido. L'esaurimento del piano di consegna da solo non significa che la sessione sia fallita. Consulta Eventi di Verify per le condizioni di fallimento.
Monitorare le verifiche nella dashboard
La pagina Verifications elenca ogni verifica creata dallo spazio di lavoro, filtrabile per stato. Ogni riga mostra il destinatario, il piano dei canali, l'ultimo canale utilizzato, i tempi di scadenza e verifica e i metadati. Il codice generato non è mostrato.

Impostazioni di verifica
La pagina Configure imposta il ciclo di verifica dello spazio di lavoro. Ogni campo mostra il valore effettivo: la tua personalizzazione dove ne hai impostata una, altrimenti il valore predefinito della piattaforma di Bird.
- Duration: per quanto tempo un codice resta valido. Predefinito 10 minuti; da 1 minuto a 999 minuti.
- Maximum Retries: quanti tentativi di verifica prima che la verifica fallisca con
attempts_exhausted. Predefinito 5; da 1 a 10. - Retry Delay: il tempo di attesa prima che un nuovo codice possa essere inviato allo stesso destinatario. Predefinito 60 secondi; da 0 a 3600.

La lunghezza del codice non è un campo in questa pagina: i codici sono predefiniti a 6 cifre, numerici, e options.code_length imposta da 4 a 8 cifre per richiesta.
Protezioni contro gli abusi
Indipendentemente dalle tue impostazioni, Verify applica limiti di piattaforma per impedire che il traffico OTP venga usato come arma, sia contro il tuo portafoglio (pumping SMS) sia contro la casella di posta di una vittima:
- 5 invii per indirizzo per ora mobile, tra avvio e reinvio di verifiche. Quando
tocontiene entrambi gli indirizzi, ciascuno ha il proprio budget. - 10 controlli per set di indirizzi destinatario al minuto, in aggiunta al limite di tentativi della verifica.
Il piano dei canali, non il limite orario, vincola i cambi di canale. Ogni chiamata avanza rigorosamente in avanti, quindi una verifica invia al massimo una volta per canale rimanente.
Raggiungere un limite restituisce 429; attendi e riprova dopo il periodo indicato nell'header Retry-After. I limiti complessivi di richiesta del tuo account sono separati e proporzionati al piano; consulta Limiti di frequenza.
Riprovare in sicurezza
Tutti e tre gli endpoint accettano l'header Idempotency-Key. Invia un valore univoco per ogni richiesta logica. Dopo un timeout o una connessione interrotta, riprovare con la stessa chiave riproduce la risposta originale. Un replay non invia un altro codice né consuma un altro tentativo di verifica, e include un header Idempotency-Replay. Consulta Idempotenza per il formato della chiave e la sua conservazione.
Costi e fatturazione
La fatturazione si applica a ogni codice inviato. Ogni codice inviato viene addebitato sul tuo portafoglio alla tariffa del canale per la destinazione. Un reinvio o un fallback su un altro canale aggiunge un addebito per invio. La commissione di Bird viene trattenuta durante l'elaborazione dell'invio e resta valida indipendentemente dall'arrivo del codice; su SMS e WhatsApp una commissione di terze parti segue quando il messaggio viene consegnato. Le rotte gratuite e i controlli non costano nulla; un invio rifiutato prima della fatturazione non viene addebitato. Metodi di pagamento e portafoglio tratta saldo e ricariche.
Telegram fattura in un punto diverso dell'invio. Prima che un messaggio parta, a Telegram viene chiesto se il numero può riceverne uno; l'addebito scatta quando la risposta è sì, a una tariffa fissa mondiale, e un numero non raggiungibile è gratuito e avanza al canale successivo senza alcun addebito. Quindi un addebito Telegram significa che il messaggio è stato accettato per la consegna, non che è arrivato: un codice che poi non viene consegnato resta addebitato, e la verifica paga di nuovo per il canale su cui prosegue. Se non vuoi quel secondo addebito, rimuovi Telegram dall'ordine dei canali per quei paesi nella pagina Countries.
Prossimi passi
| Pagina | Cosa tratta |
|---|---|
| Mittenti e branding | Come appaiono i messaggi con il codice e come inviare dal tuo dominio |
| Configurazione per paese | Ordine dei canali per paese, abilitazione e override dei mittenti |
| Eventi | Il ciclo di vita della verifica e gli eventi di consegna, con i relativi payload webhook |
| Idempotenza | Riprovare in sicurezza con l'header Idempotency-Key |
| Riferimento API: creare una verifica | Schema dell'endpoint di invio e dettagli sugli errori |
| Riferimento API: controllare un codice | Schema dell'endpoint di controllo e dettagli sugli errori |
| Riferimento API: avanzare al canale successivo | Schema dell'endpoint next-channel e dettagli sugli errori |
Risorse correlate
Continua con la documentazione, le guide e gli esempi per questo argomento.