Sign inGet Started

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);

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 con 422.
  • language: un tag BCP 47 come fr o pt-BR che 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

Esempio di codice
{
  "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:

Esempio di codice
{
  "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:

LinguaTag
Araboar
Bulgarobg
Cinese (semplificato)zh
Cinese (tradizionale)zh-TW
Croatohr
Cecocs
Daneseda
Olandesenl
Ingleseen
Finlandesefi
Francesefr
Tedescode
Grecoel
Ebraicohe
Hindihi
Ungheresehu
Indonesianoid
Italianoit
Giapponeseja
Coreanoko
Lettonelv
Lituanolt
Macedonemk
Malesems
Mongolomn
Norvegeseno
Norvegese Bokmålnb-NO
Polaccopl
Portoghesept
Rumenoro
Russoru
Serbosr
Slovaccosk
Slovenosl
Spagnoloes
Svedesesv
Thailandeseth
Turcotr
Ucrainouk
Vietnamitavi

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);

La risposta indica se il codice corrisponde:

Esempio di codice
{
  "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. Tratta success: false con un reason (incorrect_code, expired, attempts_exhausted) come una risposta normale. attempts_remaining indica 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);

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:

StatoCosa è successoCosa fare
404Nessuna verifica in corso per quel destinatarioCreane una
422 NoNextChannelIl piano non ha altri canali a cui avanzareReinvia sul canale corrente chiamando di nuovo create
422 NoAvailableChannelTutti i canali rimanenti non sono riusciti a inviareMostra il fallimento all'utente; la verifica non può essere consegnata
429Gli invii per l'account vengono richiesti troppo rapidamenteAttendi 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:

StatoSignificatoMotivo
verifiedUn codice corretto è arrivato in temponessuno
failedTroppi tentativi errati, oppure il piano di consegna si è esaurito con errori che indicano che nessun codice di verifica è stato inviatoattempts_exhausted, undeliverable
expiredLa finestra temporale è scaduta prima dell'arrivo di un codice correttottl_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.

La pagina Verifications che elenca le verifiche con colonne per stato, destinatario, canale e data di creazione

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 scheda General della pagina Configure con i campi Duration, Maximum Retries e Retry Delay

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 to contiene 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

PaginaCosa tratta
Mittenti e brandingCome appaiono i messaggi con il codice e come inviare dal tuo dominio
Configurazione per paeseOrdine dei canali per paese, abilitazione e override dei mittenti
EventiIl ciclo di vita della verifica e gli eventi di consegna, con i relativi payload webhook
IdempotenzaRiprovare in sicurezza con l'header Idempotency-Key
Riferimento API: creare una verificaSchema dell'endpoint di invio e dettagli sugli errori
Riferimento API: controllare un codiceSchema dell'endpoint di controllo e dettagli sugli errori
Riferimento API: avanzare al canale successivoSchema dell'endpoint next-channel e dettagli sugli errori