# Migrare Verify da Prelude

Questa pagina mappa le API di verifica v2 di Prelude su Bird Verify. Segui la [guida principale alla migrazione](/docs/guides/verify/migrate) nell'ordine indicato e usa queste corrispondenze per i passaggi 1 e 3.

Le strutture sono simili. `POST https://api.prelude.dev/v2/verification` e `POST /v2/verification/check` di Prelude sono una coppia create-and-check con autenticazione bearer, indicizzata sul destinatario anziché su un ID di verifica, e lo stesso vale per [`POST /v1/verify/verifications`](/docs/api/reference/create-verification) e [`POST /v1/verify/verifications/check`](/docs/api/reference/create-verification-check). Richiamare create per un destinatario attivo ritenta l'invio anziché avviare una nuova verifica, su entrambe le piattaforme. Ciò che non si trasferisce è il livello di rischio: i segnali, i verdetti di instradamento e la verifica silenziosa di Prelude non hanno un equivalente nell'API di Bird Verify.

## Passa questo al tuo agente

Incolla questo in Claude Code, Cursor o Codex. L'agente lavora su questa pagina nel tuo repository, usando qualsiasi superficie Bird già disponibile: il server MCP se è connesso, il CLI se è installato e autenticato.

```text
I am moving a phone verification integration from Prelude to Bird Verify. Route through it with me.
1. Check what you already have before setting anything up. If Bird's MCP server is connected, use its tools. If the Bird CLI is installed and signed in, use that. Either one is enough, and every step below is an action you take with whichever you have. Only if neither is present, follow https://bird.com/docs/ai/set-up-your-agent.md to set one up and sign me in. Every Bird docs page serves Markdown at its own URL with `.md` appended, so fetch that rather than the HTML.
2. Read https://bird.com/docs/guides/verify/migrate/prelude.md for the create, check and status mapping, and https://bird.com/docs/guides/verify/migrate.md for the order the steps go in.
3. Find and list my Prelude usage in this repository before you change anything: the /v2/verification and /v2/verification/check call sites, anywhere I read signals or a routing verdict, and anywhere I use dispatch_id for retry safety.
4. Tell me early which of these I depend on. Bird Verify has no voice channel and no silent or network-based authentication. It generates the code itself and never returns it, so I cannot supply my own. It accepts `options.language` but no per-request template or message body. Bird can use an existing SMS Sender ID or a connected WhatsApp number with an approved authentication template, configured per channel or country rather than per request; tell me whether my current sender can be kept. Prelude's risk layer does not port either: its signals, its routing verdicts and its silent verification have no counterpart in Bird Verify, so tell me every decision my code makes on those.
5. Configure my channels and destinations following https://bird.com/docs/guides/verify/countries.md and https://bird.com/docs/guides/verify/senders.md. While you are there, disable every country I do not actually verify into. An enabled destination I never send to is not reach, it is exposure to SMS pumping, so ask me which countries I serve rather than leaving the defaults.
6. Port the create and check calls using the mapping tables on the provider page, and move my status handling to Bird's events: https://bird.com/docs/guides/verify/sending-verifications.md and https://bird.com/docs/guides/verify/events.md.
7. Cut over at the create call, not all at once, because a code issued by Prelude cannot be checked by Bird and a code issued by Bird cannot be checked by Prelude. From the moment I say go, send every NEW verification to Bird, and keep routing each check to whichever provider issued that verification. Keep both paths live for one full code lifetime plus margin, then retire the old one. Tell me how you will decide which provider issued a given verification before you write any of it.
8. Test before any real traffic. Bird Verify has no simulated recipients, so do not look for a sandbox: the thing worth testing is the code arriving. Run the integration against a phone number and a mailbox I control, on each channel I enabled, and show me what arrived on each one.
9. Stop and ask me wherever a step needs a decision. Do not start routing new verifications to Bird until I have seen those test results and replied with the words cut over to Bird. Retiring the Prelude path is a separate step: ask me again and wait for me to reply with the words retire the Prelude path, and do not retire it while any code it issued could still be checked. A reply that agrees without naming what it is authorising is not authorisation. Finish by telling me what is left that only a person can do.
```

## Mappare la chiamata create

| Funzione                  | Prelude                                                                          | Bird                                                                                                                             |
| ------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Destinatario              | `target.type` + `target.value`                                                   | `to.phone_number` o `to.email`                                                                                                   |
| Lunghezza codice          | `options.code_size`                                                              | `options.code_length`                                                                                                            |
| Preferenza canale         | `options.preferred_channel`, `options.channels`                                  | `options.channels`, altrimenti l'ordine configurato per il paese                                                                 |
| Correlazione              | `metadata.correlation_id`                                                        | `metadata`                                                                                                                       |
| Callback di consegna      | `options.callback_url`                                                           | un webhook dello spazio di lavoro iscritto ai tipi di evento verify che indichi                                                  |
| Codice personalizzato     | `options.custom_code`                                                            | nessun equivalente                                                                                                               |
| Localizzazione            | `options.locale`                                                                 | `options.language`                                                                                                               |
| Identità mittente         | `options.sender_id`                                                              | seleziona un mittente gestito da Bird o di proprietà dello spazio di lavoro per canale o paese, non per singola richiesta        |
| Template messaggio        | `options.template_id`, `options.variables`                                       | nessun equivalente per singola richiesta; seleziona un template di autenticazione WhatsApp approvato nella configurazione Verify |
| Autocompletamento Android | `options.app_realm`                                                              | nessun equivalente                                                                                                               |
| Segnali di rischio        | `signals` (IP, dispositivo, fingerprint)                                         | non accettati                                                                                                                    |
| Ritentativi sicuri        | nessuna chiave o header di idempotenza nella loro documentazione create o check  | header `Idempotency-Key`                                                                                                         |
| Correlazione segnali      | `dispatch_id`, "the identifier of the dispatch that came from the front-end SDK" | nessun equivalente: Bird non accetta segnali                                                                                     |
| Controllo fallback        | `options.max_auto_fallbacks`, `options.force_challenge`                          | il piano canali del paese                                                                                                        |

`dispatch_id` non è un meccanismo di ritentativo e non va accostato a `Idempotency-Key`. La documentazione stessa di Prelude lo definisce come "the identifier of the dispatch that came from the front-end SDK": la SDK di Signals lo restituisce da `dispatchSignals()`, e tu lo inoltri nella create perché il loro livello antifrode possa associare i segnali del browser catturati a quella verifica. Le loro documentazioni create e check descrivono l'intero set di richieste senza chiave di idempotenza e senza header personalizzato, quindi una create ripetuta non è resa sicura per te. Su Bird, l'header [`Idempotency-Key`](/docs/guides/idempotency) svolge questa funzione.

I set di canali si sovrappongono solo in parte. Bird consegna tramite email, SMS, WhatsApp e Telegram; i canali RCS, Viber, Zalo, voce e silenzioso di Prelude non hanno un equivalente Bird oggi. Un numero che Prelude raggiungeva tramite Viber o Zalo qui ricade su SMS, il che è una questione di tasso di consegna da misurare nel pilota anziché scoprire a pieno volume.

## Mappare la chiamata check

Entrambi gli endpoint check accettano il destinatario e il codice senza ID di verifica, quindi questa chiamata si trasferisce quasi così com'è. La differenza sta nella risposta:

| Prelude `status`        | Bird                                           |
| ----------------------- | ---------------------------------------------- |
| `success`               | `success: true`                                |
| `failure`               | `success: false`, `reason: incorrect_code`     |
| `expired_or_not_found`  | `success: false`, `reason: expired` o un `404` |
| (nessun valore diretto) | `success: false`, `reason: attempts_exhausted` |

Prelude unisce "wrong code" e "out of attempts" in `failure`; Bird li separa e restituisce `attempts_remaining` insieme, così puoi mostrare all'utente quanti tentativi restano. Una verifica già risolta restituisce `404` anziché uno stato, quindi salva la prima risposta definitiva invece di ripetere il check.

## Cosa succede al livello di rischio

La risposta create di Prelude riporta un verdetto di instradamento: un `status` con valore `success`, `retry`, `challenged`, `blocked` o `shadow_blocked`, con un `reason` e un `risk_factors` quando rifiuta, e un `method` che indica il canale scelto. La risposta create di Bird è la verifica stessa. Non c'è un verdetto su cui ramificare, nessun oggetto signals da inviare e nessun equivalente di un blocco ombra, quindi un'integrazione che subordina le iscrizioni al verdetto di Prelude ha bisogno di una propria decisione prima di chiamare Bird.

Ciò che Bird offre in quello spazio è più limitato e per lo più configurazione: abilitazione per paese per escludere destinazioni che non servi, i limiti di invio e check della piattaforma descritti in [Protezioni contro gli abusi](/docs/guides/verify/sending-verifications#abuse-guardrails), e il piano canali stesso. Se la protezione dal pumping era il motivo per cui hai scelto Prelude, dimensiona quel divario prima di pianificare la migrazione.

## Spostare i callback

Prelude invia lo stato di consegna alla `callback_url` impostata per ogni verifica. Bird consegna agli endpoint registrati dal tuo spazio di lavoro, ciascuno sottoscritto ai tipi di evento desiderati, quindi l'URL esce dal corpo della richiesta. Indica i tipi di evento che il tuo handler vuole ricevere: `verify.verification.created`, `verify.verification.verified` e `verify.verification.failed` per la sessione, e `verify.attempt.sent`, `verify.attempt.delivered` e `verify.attempt.undelivered` per ogni invio del codice di verifica. Non esiste un wildcard che li sostituisca. Verifica le firme secondo [Standard Webhooks](https://www.standardwebhooks.com). I payload sono documentati in [Eventi Verify](/docs/guides/verify/events).

## Effettuare il cutover

La [regola di cutover](/docs/guides/verify/migrate#5-cut-over-one-code-lifetime-at-a-time) della guida principale si applica invariata: un codice emesso da Prelude non può essere verificato da Bird, quindi commuta alla chiamata create e instrada ogni check verso il provider che ha emesso quella verifica, fino alla scadenza dell'ultima. Poiché entrambe le API si indicizzano sul destinatario, il ramo è un singolo condizionale attorno ai tuoi punti di chiamata esistenti, non una riscrittura.

Monitora la conversione durante il pilota insieme alla consegna. Prelude instrada per richiesta su un set di canali più ampio; Bird instrada secondo l'ordine canali impostato per paese. Se la conversione di un mercato cala, riordina i canali di quel paese prima di trarre conclusioni sulla migrazione.

## Passaggi successivi

- [Invio delle verifiche](/docs/guides/verify/sending-verifications): il contratto completo per entrambe le chiamate, stati e limiti
- [Configurazione per paese](/docs/guides/verify/countries): ordine e disponibilità dei canali per paese
- [Mittenti e branding](/docs/guides/verify/senders): cosa vede il destinatario su ogni canale
- [Eventi Verify](/docs/guides/verify/events): gli eventi a cui migra il tuo consumer di callback

## Related resources

- [Verify phone numbers at signup](/learn/series/verify-phone-numbers-at-signup) (video)
- [What does OTP mean? One-time passwords explained](/explained/verify/what-does-otp-mean) (answer)
- [Customer verification](/verify-api) (product)
- [Build your first integration](/learn/paths/integration) (course)

[Get an implementation brief](/learn/workspace?topic=verify)
