Verificaties versturen
Een gebruiker verifiëren kost twee calls. POST /v1/verify/verifications stuurt een verificatiecode naar een e-mailadres of telefoonnummer. POST /v1/verify/verifications/check verstuurt de waarde die de gebruiker heeft ingevoerd en meldt of deze overeenkomt. Bird genereert de code, geeft deze niet terug in een API-respons en handhaaft verloop- en pogingslimieten.
Een code versturen
Het kleinste geldige verzoek is een to-ontvanger:
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" }
}'Gebruik je regionale host (https://us1.platform.bird.com of https://eu1.platform.bird.com) met een bijbehorende bk_{region}_...-sleutel.
Ontvanger
to identificeert de ontvanger met een email, een phone_number in E.164-formaat, of beide. Een e-mailadres maakt e-mailbezorging mogelijk. Een telefoonnummer wordt omgezet naar de kanalen die beschikbaar zijn in het bestemmingsland, in de volgorde die is ingesteld via de landconfiguratie. De meeste landen proberen WhatsApp vóór SMS, terwijl sommige SMS eerst proberen; Telegram volgt op beide in de fallbackvolgorde van het platform. Wanneer je beide adressen opgeeft, kan een mislukte poging doorgaan naar een ander beschikbaar kanaal.
Opties
options overschrijft instellingen alleen voor dit verzoek:
code_length: lengte van de verificatiecode voor deze verificatie, 4 tot 8 cijfers, overschrijft de standaardwaarde.channels: herorden of beperk de bezorgkanalen voor dit verzoek. Geef kanaalnamen op (sms,whatsapp,email,telegram) in de volgorde waarin ze geprobeerd moeten worden; een kanaal dat je weglaat wordt niet gebruikt, en een naam die niet in het opgeloste plan van de ontvanger staat wordt genegeerd. Je kunt op deze manier geen kanaal toevoegen, alleen inkorten of herordenen wat de ontvanger en landconfiguratie al toestaan, en een lijst die geen bruikbaar kanaal overlaat laat het verzoek falen met422.language: een BCP 47-tag zoalsfrofpt-BRdie bepaalt welke ingebouwde vertaling het codebericht gebruikt. Laat je het weg, dan volgt de taal het telefoonnummer van de ontvanger; zie Berichttaal.
Metadata
metadata is een vrij-vormobject dat bij elke leesactie wordt teruggegeven; gebruik het om je eigen gebruikers-ID of sessiereferentie mee te geven. Afzenderkeuzes en verificatie-instellingen worden niet in het verzoek meegegeven: ze komen uit de configuratie van je werkruimte, beheerd in het dashboard (zie Verificatie-instellingen).
De respons
{
"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 is het geordende bezorgplan waarnaar deze verificatie is opgelost (een telefoon-ontvanger toont de telefoonkanalen in pogingsvolgorde), en last_channel is waar de meest recente code naartoe is gegaan. expires_at is het moment waarop de verificatie vervalt als er geen juiste code binnenkomt; opnieuw versturen verlengt dit niet.
Berichttaal
De SMS-, e-mail- en gedeelde WhatsApp-berichten van Bird worden geleverd met 40 ingebouwde vertalingen. Een aangepaste WhatsApp-afzender gebruikt de goedgekeurde talen van het geselecteerde authenticatietemplate. Telegram schrijft zijn eigen bericht, dus de instelling heeft daar geen effect.
Zonder options.language komt de taal van het telefoonnummer van de ontvanger. Een Frans nummer krijgt Frans en een Japans nummer krijgt Japans, zonder dat je erom hoeft te vragen. Een verificatie zonder telefoonnummer verstuurt Engels, net als een verificatie waarvan het land geen vertaling heeft.
Stel options.language in om zelf te kiezen, bijvoorbeeld om de taal te matchen die je gebruiker in je app heeft gekozen in plaats van het land van het nummer:
{
"to": { "phone_number": "+15551234567" },
"options": { "language": "es" }
}Een tag zonder eigen ingebouwde vertaling valt terug op de basistaal en daarna op Engels: en-GB stuurt Engels, pt-BR stuurt Portugees. Alleen een ongeldig geformatteerde tag wordt geweigerd, met 422. Dit zijn de ingebouwde vertalingen die je kunt aanvragen, allemaal beschikbaar op SMS en e-mail, en allemaal behalve Mongools op de gedeelde WhatsApp-afzender van Bird:
| Taal | Tag |
|---|---|
| Arabisch | ar |
| Bulgaars | bg |
| Chinees (vereenvoudigd) | zh |
| Chinees (traditioneel) | zh-TW |
| Kroatisch | hr |
| Tsjechisch | cs |
| Deens | da |
| Nederlands | nl |
| Engels | en |
| Fins | fi |
| Frans | fr |
| Duits | de |
| Grieks | el |
| Hebreeuws | he |
| Hindi | hi |
| Hongaars | hu |
| Indonesisch | id |
| Italiaans | it |
| Japans | ja |
| Koreaans | ko |
| Lets | lv |
| Litouws | lt |
| Macedonisch | mk |
| Maleis | ms |
| Mongools | mn |
| Noors | no |
| Noors Bokmål | nb-NO |
| Pools | pl |
| Portugees | pt |
| Roemeens | ro |
| Russisch | ru |
| Servisch | sr |
| Slowaaks | sk |
| Sloveens | sl |
| Spaans | es |
| Zweeds | sv |
| Thai | th |
| Turks | tr |
| Oekraïens | uk |
| Vietnamees | vi |
De referentie voor het aanmaken van verificaties is de gezaghebbende lijst.
De taal wordt vastgelegd wanneer de verificatie wordt aangemaakt, dus een opnieuw verstuurde code of een overschakeling naar een ander kanaal komt in dezelfde taal aan als het eerste bericht. Opnieuw create aanroepen voor dezelfde ontvanger met een andere language hergebruikt de lopende verificatie en wijzigt deze niet.
De vertaling die bij een verzending is gebruikt, kan afwijken van de tag die je hebt gestuurd wanneer er een terugval plaatsvond. Open de verificatie op de Verifications-pagina om dit te controleren: elke poging toont de gebruikte taal als een Template-tag. De gedeelde WhatsApp-afzender van Bird heeft geen Mongools (mn) template, dus stuurt Engels voor die taal, terwijl SMS en e-mail Mongools behouden. Je eigen WhatsApp-template volgt de goedgekeurde talen en het taalbeleid; een taal die het niet kan verzenden kan de WhatsApp-poging laten mislukken.
Je kunt per verzoek een taal kiezen, maar kunt geen berichtinhoud meesturen met dat verzoek. Een aangepaste WhatsApp-afzender gebruikt de bewoordingen van het geselecteerde authenticatietemplate. Afzenders en huisstijl toont de afzenderopties en de berichttekst van Bird.
De code controleren
Stuur wat de gebruiker heeft ingetypt naar POST /v1/verify/verifications/check, gekoppeld aan dezelfde ontvanger; geen verificatie-ID nodig. Geef exact de to-set op waarmee je de verificatie hebt aangemaakt: een verificatie die met beide adressen is aangemaakt wordt niet gevonden met één adres alleen.
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"
}'De respons geeft aan of de code overeenkomt:
{
"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"
}
}Behandel deze twee responsgedragingen:
- Een verkeerde code retourneert
200. Behandelsuccess: falsemet eenreason(incorrect_code,expired,attempts_exhausted) als een normaal antwoord.attempts_remainingvertelt je hoeveel pogingen er over zijn. Reserveer foutafhandeling voor mislukte verzoeken. - Een afgeronde verificatie kan niet opnieuw worden gecontroleerd. Nadat een verificatie een definitieve status heeft bereikt, retourneren verdere checks
404. Sla het eerste definitieve resultaat op in plaats van opnieuw te controleren.
Als de gebruiker om een nieuwe code heeft gevraagd, roep je het create-endpoint opnieuw aan met dezelfde ontvanger: de lopende verificatie wordt hergebruikt in plaats van vervangen. Zodra de cooldown voor opnieuw versturen is verstreken (standaard 60 seconden) gaat er een nieuwe code uit; binnen de cooldown retourneert de call de actieve verificatie zonder opnieuw te versturen. Elke code die voor de actieve verificatie is verstuurd blijft geldig totdat deze wordt opgelost of verloopt, dus de gebruiker kan elke code invoeren die is aangekomen.
De code via een ander kanaal versturen
Wanneer de gebruiker meldt dat er helemaal geen code is aangekomen, schakelt POST /v1/verify/verifications/next-channel de verificatie door naar het volgende kanaal in het plan en verstuurt daar een nieuwe code. Dit is het endpoint achter een "I didn't receive my code"-knop: je app besluit om van kanaal te wisselen in plaats van te wachten op een bezorgstatussignaal.
Koppel het aan dezelfde ontvanger waarmee je de verificatie hebt aangemaakt, net als bij een check:
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"
}
}'De respons is de verificatie, waarbij last_channel het kanaal aangeeft waarnaar de nieuwe code is gegaan. Elke eerder verstuurde code blijft geldig, dus een bericht dat laat aankomt kan nog steeds worden gecontroleerd.
Twee dingen onderscheiden dit van opnieuw versturen:
- De cooldown voor opnieuw versturen is niet van toepassing. Een bewuste kanaalwissel is een andere actie dan hetzelfde kanaal opnieuw aanvragen, dus de verzending gaat direct uit.
- Alleen het kanaal gaat vooruit. Het verloop, pogingsbudget en verificatie-ID blijven ongewijzigd.
Gebruik opnieuw versturen wanneer de gebruiker nog een poging wil op een kanaal dat werkt, en dit endpoint wanneer het kanaal zelf het probleem lijkt. Een telefoonnummer waarvan het plan WhatsApp dan SMS is, gaat door naar SMS; een ontvanger met slechts één bruikbaar kanaal heeft nergens om naartoe te gaan.
Vier responsen vereisen afhandeling in plaats van simpelweg opnieuw proberen:
| Status | Wat er is gebeurd | Wat te doen |
|---|---|---|
404 | Er loopt geen verificatie voor die ontvanger | Maak er een aan |
422 NoNextChannel | Het plan heeft geen volgend kanaal om naar door te schakelen | Verstuur opnieuw op het huidige kanaal door create opnieuw aan te roepen |
422 NoAvailableChannel | Elk resterend kanaal kon niet verzenden | Toon de fout aan de gebruiker; de verificatie kan niet worden bezorgd |
429 | Verzendingen voor het account worden te snel aangevraagd | Wacht de periode in de Retry-After-header af |
Elke code die dit endpoint verstuurt wordt gefactureerd als elke andere Verify-verzending; zie Kosten en facturering.
Statussen
Een verificatie is pending totdat deze wordt opgelost in een definitieve status, waarbij reason de reden aangeeft:
| Status | Betekenis | Reden |
|---|---|---|
verified | Er is op tijd een juiste code ontvangen | geen |
failed | Te veel onjuiste pogingen, of het afleverplan eindigde met fouten die aangeven dat er geen verificatiecode is verzonden | attempts_exhausted, undeliverable |
expired | Het tijdvenster verstreek voordat er een juiste code binnenkwam | ttl_elapsed |
reason is een open enum. Bewaar een niet-herkende waarde in plaats van de respons als ongeldig te behandelen.
Een bounce, afwijzing door de carrier of een aflevertime-out kan de sessie in de status pending laten staan, omdat de ontvanger mogelijk nog een geldige code heeft. Uitputting van het afleverplan alleen betekent niet dat de sessie is mislukt. Zie Verify-events voor de faalcondities.
Verificaties volgen in het dashboard
De pagina Verifications toont alle verificaties die de werkruimte heeft aangemaakt, filterbaar op status. Elke rij opent de ontvanger, het kanaalplan, het laatste kanaal, de verloop- en verificatietijden, en metadata. De gegenereerde code wordt niet getoond.

Verificatie-instellingen
De pagina Configure stelt de verificatiecyclus van de werkruimte in. Elk veld toont de effectieve waarde: jouw overschrijving als je er een hebt ingesteld, anders de platformstandaard van Bird.
- Duration: hoe lang een code geldig blijft. Standaard 10 minuten; 1 minuut tot 999 minuten.
- Maximum Retries: hoeveel check-pogingen voordat de verificatie mislukt met
attempts_exhausted. Standaard 5; 1 tot 10. - Retry Delay: de wachttijd voordat een nieuwe code naar dezelfde ontvanger kan worden gestuurd. Standaard 60 seconden; 0 tot 3.600.

Codelengte is geen veld op deze pagina: codes zijn standaard 6 cijfers, numeriek, en options.code_length stelt 4 tot 8 cijfers per verzoek in.
Bescherming tegen misbruik
Onafhankelijk van jouw instellingen handhaaft Verify platformlimieten om te voorkomen dat OTP-verkeer als wapen wordt ingezet, of dat nu tegen je wallet is (SMS-pumping) of tegen de inbox van een slachtoffer:
- 5 verzendingen per adres per rollend uur, over het starten en opnieuw verzenden van verificaties heen. Wanneer
tobeide adressen bevat, heeft elk adres een eigen budget. - 10 checks per set ontvangeradressen per minuut, bovenop de pogingenlimiet van de verificatie.
Het kanaalplan, niet de uurlimiet, begrenst kanaalwisselingen. Elke aanroep gaat strikt vooruit, dus één verificatie verstuurt maximaal één keer per resterend kanaal.
Het bereiken van een limiet retourneert 429; wacht en probeer opnieuw na de periode in de Retry-After-header. De algemene verzoeklimieten van je account zijn apart en schalen met je plan; zie Rate limits.
Veilig opnieuw proberen
Alle drie de endpoints accepteren de Idempotency-Key-header. Stuur een unieke waarde per logisch verzoek. Na een time-out of verbroken verbinding speelt opnieuw proberen met dezelfde sleutel het oorspronkelijke antwoord opnieuw af. Een replay verstuurt geen nieuwe code en verbruikt geen extra check-poging, en bevat een Idempotency-Replay-header. Zie idempotency voor sleutelformaat en bewaartermijn.
Kosten en facturering
Facturering geldt per verzonden code. Elke verzonden code wordt in rekening gebracht op je wallet tegen het kanaaltarief voor de bestemming. Een hernieuwde verzending of fallback naar een ander kanaal voegt één kosten per verzending toe. De eigen vergoeding van Bird wordt afgehouden terwijl de verzending wordt verwerkt en blijft staan ongeacht of de code aankomt; bij SMS en WhatsApp volgt er een vergoeding van een derde partij wanneer het bericht is afgeleverd. Gratis routes en checks kosten niets; een verzending die vóór facturering is geweigerd, wordt niet in rekening gebracht. Payment methods and wallet behandelt saldo en opwaarderingen.
Telegram factureert op een ander punt in de verzending. Voordat een bericht wordt verstuurd, wordt aan Telegram gevraagd of het nummer er een kan ontvangen; de kosten worden gekoppeld wanneer dat antwoord ja is, tegen een vast tarief wereldwijd, en een nummer dat niet bereikbaar is kost niets en gaat door naar het volgende kanaal zonder dat er iets wordt gefactureerd. Een Telegram-kosten betekent dus dat het bericht is geaccepteerd voor aflevering, niet dat het is aangekomen: een code die vervolgens niet wordt afgeleverd, blijft in rekening gebracht, en de verificatie betaalt opnieuw voor het kanaal waar die op terugvalt. Als je die tweede kosten niet wilt, haal je Telegram uit de kanaalvolgorde voor die landen op de pagina Countries.
Volgende stappen
| Pagina | Wat het behandelt |
|---|---|
| Afzenders en branding | Hoe de codeberichten eruitzien en hoe je vanaf je eigen domein verstuurt |
| Landconfiguratie | Kanaalvolgorde per land, activering en afzenderoverschrijvingen |
| Events | De verificatielevenscyclus en afleverevents, en hun webhook-payloads |
| Idempotency | Veilig opnieuw proberen met de Idempotency-Key-header |
| API-referentie: een verificatie aanmaken | Schema en foutdetails van het verzendendpoint |
| API-referentie: een code controleren | Schema en foutdetails van het check-endpoint |
| API-referentie: doorgaan naar het volgende kanaal | Schema en foutdetails van het next-channel-endpoint |
Gerelateerde bronnen
Ga verder met de documentatie, handleidingen en voorbeelden voor dit onderwerp.