Envoyer des vérifications
Vérifier un utilisateur nécessite deux appels. POST /v1/verify/verifications envoie un code de vérification à une adresse e-mail ou un numéro de téléphone. POST /v1/verify/verifications/check soumet la valeur saisie par l'utilisateur et indique si elle correspondait. Bird génère le code, ne le renvoie pas dans une réponse API, et applique les limites d'expiration et de tentatives.
Envoyer un code
La requête valide minimale est un destinataire 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" }
}'Utilisez votre hôte régional (https://us1.platform.bird.com ou https://eu1.platform.bird.com) avec une clé bk_{region}_... correspondante.
Destinataire
to identifie le destinataire avec un email, un phone_number au format E.164, ou les deux. Une adresse e-mail active la livraison par e-mail. Un numéro de téléphone est résolu vers les canaux disponibles dans son pays de destination, dans l'ordre défini par la configuration par pays. La plupart des pays essaient WhatsApp avant SMS, tandis que certains essaient SMS en premier ; Telegram suit les deux dans l'ordre de repli de la plateforme. Lorsque vous fournissez les deux adresses, une tentative échouée peut passer à un autre canal disponible.
Options
options remplace les paramètres pour cette requête uniquement :
code_length: longueur du code de vérification pour cette vérification, de 4 à 8 chiffres, remplaçant la valeur par défaut.channels: réordonnez ou restreignez les canaux de livraison pour cette requête. Listez les noms de canaux (sms,whatsapp,email,telegram) dans l'ordre dans lequel les essayer ; un canal omis n'est pas utilisé, et un nom absent du plan résolu du destinataire est ignoré. Vous ne pouvez pas ajouter un canal de cette façon, seulement réduire ou réordonner ce que le destinataire et la configuration par pays autorisent déjà, et une liste qui ne laisse aucun canal utilisable fait échouer la requête avec422.language: une balise BCP 47 telle quefroupt-BRqui détermine quelle traduction intégrée le message de code utilise. Omettez-la et la langue suit le numéro de téléphone du destinataire ; voir Langue du message.
Métadonnées
metadata est un objet libre renvoyé à chaque lecture ; utilisez-le pour transporter votre propre identifiant utilisateur ou référence de session. Les choix d'expéditeur et les paramètres de vérification ne sont pas portés par la requête : ils proviennent de la configuration de votre espace de travail, gérée dans le tableau de bord (voir Paramètres de vérification).
La réponse
{
"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 est le plan de livraison ordonné résolu pour cette vérification (un destinataire téléphonique liste ses canaux téléphoniques dans l'ordre des tentatives), et last_channel indique où le dernier code a été envoyé. expires_at est le moment où la vérification expire si aucun code correct n'arrive ; les renvois ne prolongent pas ce délai.
Langue du message
Les messages SMS, e-mail et WhatsApp partagés de Bird sont disponibles en 40 traductions intégrées. Un expéditeur WhatsApp personnalisé utilise les langues approuvées de son modèle d'authentification sélectionné. Telegram rédige son propre message, donc ce paramètre n'a aucun effet sur ce canal.
Sans options.language, la langue est déduite du numéro de téléphone du destinataire. Un numéro français reçoit le message en français et un numéro japonais en japonais, sans que vous ayez à le demander. Une vérification sans numéro de téléphone envoie en anglais, de même qu'une vérification dont le pays n'a pas de traduction.
Définissez options.language pour choisir vous-même, par exemple pour correspondre à la langue choisie par votre utilisateur dans votre application plutôt qu'au pays de son numéro :
{
"to": { "phone_number": "+15551234567" },
"options": { "language": "es" }
}Une balise sans traduction intégrée propre se rabat sur sa langue de base, puis sur l'anglais : en-GB envoie en anglais, pt-BR envoie en portugais. Seule une balise mal formée est rejetée, avec 422. Voici les traductions intégrées disponibles, toutes proposées sur SMS et par e-mail, et toutes sauf le mongol sur l'expéditeur SMS partagé de Bird (WhatsApp) :
| Langue | Balise |
|---|---|
| Arabe | ar |
| Bulgare | bg |
| Chinois (simplifié) | zh |
| Chinois (traditionnel) | zh-TW |
| Croate | hr |
| Tchèque | cs |
| Danois | da |
| Néerlandais | nl |
| Anglais | en |
| Finnois | fi |
| Français | fr |
| Allemand | de |
| Grec | el |
| Hébreu | he |
| Hindi | hi |
| Hongrois | hu |
| Indonésien | id |
| Italien | it |
| Japonais | ja |
| Coréen | ko |
| Letton | lv |
| Lituanien | lt |
| Macédonien | mk |
| Malais | ms |
| Mongol | mn |
| Norvégien | no |
| Norvégien bokmål | nb-NO |
| Polonais | pl |
| Portugais | pt |
| Roumain | ro |
| Russe | ru |
| Serbe | sr |
| Slovaque | sk |
| Slovène | sl |
| Espagnol | es |
| Suédois | sv |
| Thaï | th |
| Turc | tr |
| Ukrainien | uk |
| Vietnamien | vi |
La référence create-verification est la liste faisant autorité.
La langue est fixée à la création de la vérification, donc un renvoi ou un changement de canal arrive dans la même langue que le premier message. Appeler create à nouveau pour le même destinataire avec un language différent réutilise la vérification en cours sans la modifier.
La traduction utilisée lors de l'envoi peut différer de la balise transmise si un repli a eu lieu. Ouvrez la vérification sur la page Verifications pour le confirmer : chaque tentative affiche la langue effectivement rendue sous forme de balise Template. L'expéditeur SMS partagé de Bird (WhatsApp) n'a pas de modèle mongol (mn), il envoie donc en anglais pour cette langue, tandis que SMS et l'e-mail conservent le mongol. Votre propre modèle WhatsApp suit ses langues approuvées et sa politique linguistique ; une langue qu'il ne peut pas envoyer peut faire échouer la tentative WhatsApp.
Vous pouvez choisir une langue par requête, mais vous ne pouvez pas transmettre le contenu du message avec cette requête. Un expéditeur WhatsApp personnalisé utilise le contenu du modèle d'authentification sélectionné. Senders and branding présente les choix d'expéditeur et le texte du message Bird.
Vérifier le code
Soumettez ce que l'utilisateur a saisi à POST /v1/verify/verifications/check, identifié par le même destinataire ; aucun identifiant de vérification n'est nécessaire. Fournissez exactement le jeu to avec lequel vous avez créé la vérification : une vérification créée avec les deux adresses n'est pas trouvée par l'une ou l'autre seule.
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 réponse indique si le code correspondait :
{
"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"
}
}Gérez ces deux comportements de réponse :
- Un code incorrect renvoie
200. Traitezsuccess: falseavec unreason(incorrect_code,expired,attempts_exhausted) comme une réponse normale.attempts_remainingvous indique combien de tentatives il reste. Réservez la gestion d'erreurs aux échecs de requête. - Une vérification finale ne peut pas être vérifiée à nouveau. Après qu'une vérification atteint un état final, les vérifications suivantes renvoient
404. Enregistrez le premier résultat définitif au lieu de vérifier à nouveau.
Si l'utilisateur a demandé un nouveau code, appelez à nouveau le endpoint create avec le même destinataire : la vérification en cours est réutilisée plutôt que remplacée. Une fois le délai de renvoi écoulé (60 secondes par défaut), un nouveau code est envoyé ; pendant le délai, l'appel renvoie la vérification active sans nouvel envoi. Chaque code envoyé pour la vérification active reste valide jusqu'à sa résolution ou son expiration, l'utilisateur peut donc saisir celui qui est arrivé.
Envoyer le code sur un autre canal
Lorsque l'utilisateur signale qu'aucun code n'est arrivé, POST /v1/verify/verifications/next-channel fait passer la vérification au canal suivant dans son plan et y envoie un nouveau code. C'est le endpoint derrière un bouton "I didn't receive my code" : votre application décide de changer de canal plutôt que d'attendre un signal de statut de livraison.
Identifiez-le par le même destinataire avec lequel vous avez créé la vérification, comme pour une vérification de code :
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 réponse est la vérification, avec last_channel indiquant le canal vers lequel le nouveau code a été envoyé. Chaque code déjà envoyé reste valide, un message arrivé en retard peut donc encore être vérifié.
Deux éléments distinguent ceci d'un renvoi :
- Le délai de renvoi ne s'applique pas. Un changement de canal délibéré est un acte différent d'une demande de renvoi sur le même canal, donc l'envoi part immédiatement.
- Seul le canal avance. L'expiration, le budget de tentatives et l'identifiant de vérification restent inchangés.
Utilisez un renvoi quand l'utilisateur veut un nouvel essai sur un canal qui fonctionne, et ce endpoint quand le canal lui-même semble être le problème. Un numéro de téléphone dont le plan est WhatsApp puis SMS passe à SMS ; un destinataire avec un seul canal utilisable n'a nulle part où aller.
Quatre réponses nécessitent un traitement spécifique plutôt qu'un simple réessai :
| Statut | Ce qui s'est passé | Action à entreprendre |
|---|---|---|
404 | Aucune vérification en cours pour ce destinataire | En créer une |
422 NoNextChannel | Le plan n'a plus de canal suivant disponible | Renvoyer sur le canal actuel en appelant create à nouveau |
422 NoAvailableChannel | Tous les canaux restants ont échoué à l'envoi | Signaler l'échec à l'utilisateur ; la vérification ne peut pas être livrée |
429 | Les envois pour le compte sont demandés trop rapidement | Patientez pendant la durée indiquée dans l'en-tête Retry-After |
Chaque code envoyé par ce endpoint est facturé comme tout autre envoi Verify ; voir Coûts et facturation.
Statuts
Une vérification est pending jusqu'à ce qu'elle atteigne un état final, avec reason indiquant la raison :
| Statut | Signification | Raison |
|---|---|---|
verified | Un code correct est arrivé dans les délais | aucune |
failed | Trop de tentatives incorrectes, ou le plan de livraison s'est terminé par des échecs indiquant qu'aucun code de vérification n'a été envoyé | attempts_exhausted, undeliverable |
expired | La fenêtre a expiré avant la réception d'un code correct | ttl_elapsed |
reason est un enum ouvert. Conservez une valeur non reconnue au lieu de traiter la réponse comme invalide.
Un rebond, un rejet par l'opérateur ou un délai de livraison dépassé peuvent laisser la session en attente, car le destinataire dispose peut-être encore d'un code valide. L'épuisement du plan de livraison ne signifie pas à lui seul que la session a échoué. Consultez Événements Verify pour les conditions d'échec.
Suivre les vérifications dans le tableau de bord
La page Verifications répertorie toutes les vérifications créées par l'espace de travail, filtrables par statut. Chaque ligne affiche le destinataire, le plan de canaux, le dernier canal utilisé, les dates d'expiration et de vérification, et les métadonnées. Le code généré n'est pas affiché.

Paramètres de vérification
La page Configure définit le cycle de vérification de l'espace de travail. Chaque champ affiche la valeur effective : votre remplacement si vous en avez défini un, sinon la valeur par défaut de la plateforme Bird.
- Duration : durée de validité d'un code. Par défaut 10 minutes ; de 1 minute à 999 minutes.
- Maximum Retries : nombre de tentatives de vérification avant que la vérification échoue avec
attempts_exhausted. Par défaut 5 ; de 1 à 10. - Retry Delay : délai de récupération avant qu'un nouveau code puisse être envoyé au même destinataire. Par défaut 60 secondes ; de 0 à 3 600.

La longueur du code n'est pas un champ sur cette page : les codes ont par défaut 6 chiffres, numériques, et options.code_length définit de 4 à 8 chiffres par requête.
Protections contre les abus
Indépendamment de vos paramètres, Verify applique des plafonds de plateforme pour empêcher que le trafic OTP soit détourné, que ce soit contre votre portefeuille (pompage SMS) ou contre la boîte de réception d'une victime :
- 5 envois par adresse par heure glissante, en comptant les créations et les renvois de vérifications. Lorsque
tocontient les deux adresses, chacune dispose de son propre budget. - 10 vérifications de code par ensemble d'adresses destinataire par minute, en plus de la limite de tentatives de la vérification.
C'est le plan de canaux, et non le plafond horaire, qui limite les changements de canal. Chaque appel avance strictement, de sorte qu'une vérification envoie au plus une fois par canal restant.
Atteindre un plafond renvoie 429 ; patientez puis réessayez après la période indiquée dans l'en-tête Retry-After. Les limites globales de requêtes de votre compte sont distinctes et proportionnelles à votre forfait ; consultez Limites de débit.
Réessayer en toute sécurité
Les trois endpoints acceptent l'en-tête Idempotency-Key. Envoyez une valeur unique par requête logique. Après un délai d'attente dépassé ou une connexion interrompue, réessayer avec la même clé rejoue la réponse originale. Un rejeu n'envoie pas de nouveau code et ne consomme pas de tentative de vérification supplémentaire, et inclut un en-tête Idempotency-Replay. Consultez idempotency pour le format de clé et la durée de rétention.
Coût et facturation
La facturation s'applique à chaque code envoyé. Chaque code envoyé est débité de votre portefeuille au tarif du canal pour la destination. Un renvoi ou un repli vers un autre canal ajoute un débit par envoi. Les frais propres à Bird sont prélevés pendant le traitement de l'envoi et restent dus que le code arrive ou non ; sur SMS et WhatsApp, des frais tiers s'ajoutent lorsque le message est livré. Les routes gratuites et les vérifications de code ne coûtent rien ; un envoi rejeté avant facturation n'est pas débité. Méthodes de paiement et portefeuille couvre le solde et les rechargements.
Telegram facture à un moment différent de l'envoi. Avant qu'un message ne parte, Telegram vérifie si le numéro peut en recevoir un ; le débit intervient lorsque la réponse est oui, à un tarif fixe mondial, et un numéro injoignable est gratuit et passe au canal suivant sans facturation. Un débit Telegram signifie donc que le message a été accepté pour livraison, pas qu'il est arrivé : un code non livré reste facturé, et la vérification paie à nouveau pour le canal vers lequel elle bascule. Si vous ne souhaitez pas ce second débit, retirez Telegram de l'ordre des canaux pour ces pays sur la page Countries.
Étapes suivantes
| Page | Contenu couvert |
|---|---|
| Expéditeurs et image de marque | Apparence des messages de code et envoi depuis votre propre domaine |
| Configuration par pays | Ordre des canaux par pays, activation et remplacement d'expéditeur |
| Événements | Cycle de vie de la vérification, événements de livraison et payloads webhook |
| Idempotency | Réessais sûrs avec l'en-tête Idempotency-Key |
| Référence API : créer une vérification | Schéma du endpoint d'envoi et détails des erreurs |
| Référence API : vérifier un code | Schéma du endpoint de vérification et détails des erreurs |
| Référence API : passer au canal suivant | Schéma du endpoint de canal suivant et détails des erreurs |
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet.