Twilio to Prelude Migration

Migrating From Twilio to Prelude: A Technical Guide

A step-by-step technical guide for replacing Twilio Messaging & Twilio Verify with Prelude’s Verify API

Quentin Le Bras

CPO

Summary

Prelude offers a unified API for the entire OTP lifecycle, including fraud detection and multi-channel routing, with built-in ML-based fraud prevention. The guide provides a mapping of Twilio concepts to Prelude equivalents, including authentication, sending and checking OTPs, handling retries, and configuring channels and webhooks.

Remplacer votre fournisseur d'OTP ne doit pas nécessairement être un projet multi-sprint. L'API Verify unifiée de Prelude se calque directement sur les concepts de Twilio Verify. Prelude fournit un point de terminaison REST unique qui gère l'ensemble du cycle de vie des OTP, de la détection de la fraude au routage multi-canal. La plupart des équipes déploient une solution de remplacement fonctionnelle en un seul sprint.

Pourquoi migrer ? Les entreprises qui passent à Prelude constatent généralement des taux de conversion de 20 à 30 % plus élevés et des coûts de SMS mensuels de 30 à 40 % inférieurs, en plus d'une prévention de la fraude intégrée basée sur le ML qui ne requiert aucun outil personnalisé.

Ce qui change

À haut niveau, vous remplacez deux interfaces Twilio : Programmable Messaging et Twilio Verify par une seule API Prelude. Le tableau ci-dessous associe chaque concept Twilio à son équivalent Prelude.

Concept

Twilio Verify

Prelude Verify

Catégorie de service

Twilio Programmable Messaging + Twilio Verify

API Prelude Verify (service unique)

URL de base de l'API

api.twilio.com/2010-04-01/Accounts/{SID}

api.prelude.dev

Authentification

HTTP Basic (AccountSID:AuthToken)

Jeton Bearer dans l'en-tête Authorization

Envoyer un OTP

POST /Services/{ServiceSID}/Verifications

POST /v2/verification

Vérifier un OTP

POST /Services/{ServiceSID}/VerificationChecks

POST /v2/verification/check

Ressaisir l'OTP

POST /Services/{ServiceSID}/Verifications (répéter)

POST /v2/verification (même numéro, dans la fenêtre de temps)

Statut de la vérification

pending / approved / canceled

success / retry / blocked / challenged

Service / espace de noms

Verify Service (ServiceSID)

Implicite par clé API (configurée dans le Dashboard)

Prévention de la fraude

Twilio Fraud Guard (add-on)

ML intégré, activé par défaut

Canaux

SMS, WhatsApp, appel, e-mail

SMS, WhatsApp, Viber, Zalo, RCS, voix, e-mail

Expéditeur / marque

Service de messagerie ou numéro de téléphone

Configuré en contactant le support client (Sender ID)

Numéros de test

Numéros magiques par service Verify

Numéros de test dans le Dashboard (Verify > Configure > Numbers)

Webhooks

URL StatusCallback par requête

callback_url par requête ; signature via RSASSA-PSS

SDKs

twilio-node, twilio-python, etc.

npm @prelude.so/sdk, pip prelude_python_sdk, go-sdk, Java, Ruby

Authentification

Twilio (avant)

Twilio utilise l'authentification HTTP Basic avec votre SID de compte comme identifiant et votre jeton de sécurité comme mot de passe.

# Twilio HTTP Basic Auth

curl -X POST https://verify.twilio.com/v2/Services/{ServiceSID}/Verifications \

  -u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN \

  -d 'To=+14155552671' \

  -d 'Channel=sms'
# Twilio HTTP Basic Auth

curl -X POST https://verify.twilio.com/v2/Services/{ServiceSID}/Verifications \

  -u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN \

  -d 'To=+14155552671' \

  -d 'Channel=sms'

Prelude (après)

Prelude utilise un jeton Bearer. Générez une clé API dans le Dashboard sous Settings > API Keys.

# Prelude Bearer Token

curl -X POST https://api.prelude.dev/v2/verification \

  -H “Authorization: Bearer $PRELUDE_API_KEY” \

  -H 'Content-Type: application/json' \

  -d '{"target": {"type": "phone_number", "value": "+14155552671"}}'
# Prelude Bearer Token

curl -X POST https://api.prelude.dev/v2/verification \

  -H “Authorization: Bearer $PRELUDE_API_KEY” \

  -H 'Content-Type: application/json' \

  -d '{"target": {"type": "phone_number", "value": "+14155552671"}}'

Action requise :  Stockez votre clé API Prelude dans une variable d'environnement (ex: PRELUDE_API_KEY). Ne la soumettez jamais dans votre gestionnaire de version. Supprimez TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, et VERIFY_SERVICE_SID une fois la migration terminée.

Envoi d'une vérification (OTP)

Twilio Verify – avant

// Node.js – Twilio Verify

const client = require('twilio')(accountSid, authToken);



const verification = await client.verify.v2

  .services(verifySid)

  .verifications

  .create({ to: '+14155552671', channel: 'sms' });



console.log(verification.status); // 'pending'
// Node.js – Twilio Verify

const client = require('twilio')(accountSid, authToken);



const verification = await client.verify.v2

  .services(verifySid)

  .verifications

  .create({ to: '+14155552671', channel: 'sms' });



console.log(verification.status); // 'pending'

Prelude – après

// Node.js – Prelude SDK

import Prelude from '@prelude.so/sdk';



const client = new Prelude({ apiToken: process.env.PRELUDE_API_KEY });



const verification = await client.verification.create({

  target: { type: 'phone_number', value: '+14155552671' },

  // Optionnel : transmettre des signaux digitaux pour mieux contrer la fraude

  signals: {

    ip: '203.0.113.42',          // IP publique de l'utilisateur final

    device_id: 'abc123-unique',   // identifiant unique et stable du périphérique

    device_platform: 'ios',

    device_model: 'iPhone 15',

  },

});



console.log(verification.id);     // 'vrf_01...'

console.log(verification.status); // 'success' | 'blocked' | 'challenged'
// Node.js – Prelude SDK

import Prelude from '@prelude.so/sdk';



const client = new Prelude({ apiToken: process.env.PRELUDE_API_KEY });



const verification = await client.verification.create({

  target: { type: 'phone_number', value: '+14155552671' },

  // Optionnel : transmettre des signaux digitaux pour mieux contrer la fraude

  signals: {

    ip: '203.0.113.42',          // IP publique de l'utilisateur final

    device_id: 'abc123-unique',   // identifiant unique et stable du périphérique

    device_platform: 'ios',

    device_model: 'iPhone 15',

  },

});



console.log(verification.id);     // 'vrf_01...'

console.log(verification.status); // 'success' | 'blocked' | 'challenged'

Valeurs de statut

Prelude renvoie un ensemble de statuts plus riche lors du lancement d'une vérification :

Statut

Signification

success

Nouvelle fenêtre de vérification ouverte ; code envoyé à l'utilisateur.

retry

Même numéro de téléphone sollicité à nouveau à l'intérieur de la fenêtre de tir ; nouvelle tentative envoyée.

blocked

Requête identifiée comme frauduleuse ; aucun code envoyé, pas de facturation d'envoi de message.

challenged

Trafic suspect ; livraison limitée aux canaux alternatifs hors SMS (doit être activé par le support Prelude).

Vérification d'un code de validation

Twilio Verify – avant

// Node.js – Twilio Verify check

const check = await client.verify.v2

  .services(verifySid)

  .verificationChecks

  .create({ to: '+14155552671', code: '123456' });




if (check.status === 'approved') {

  // accorder l'accès

}
// Node.js – Twilio Verify check

const check = await client.verify.v2

  .services(verifySid)

  .verificationChecks

  .create({ to: '+14155552671', code: '123456' });




if (check.status === 'approved') {

  // accorder l'accès

}

Prelude – après

// Node.js – Prelude check

const check = await client.verification.check({

  target: { type: 'phone_number', value: '+14155552671' },

  code: '123456',

});




if (check.status === 'success') {

  // accorder l'accès

}




// Statuts possibles : 'success' | 'failure' | ‘expired_or_not_found’
// Node.js – Prelude check

const check = await client.verification.check({

  target: { type: 'phone_number', value: '+14155552671' },

  code: '123456',

});




if (check.status === 'success') {

  // accorder l'accès

}




// Statuts possibles : 'success' | 'failure' | ‘expired_or_not_found’

Gestion des nouvelles tentatives (Retries)

Dans Twilio Verify, vous lancez une nouvelle tentative en créant une nouvelle vérification pour le même numéro de téléphone au cours de la fenêtre temporelle de retry définie dans le service. Prelude fonctionne de la même manière : appelez à nouveau POST /v2/verification avec le même numéro de téléphone et Prelude détectera la fenêtre de vérification ouverte pour émettre une nouvelle tentative plutôt qu'une toute nouvelle session.

// Prelude – retry (même appel que pour la création)

const retry = await client.verification.create({

  target: { type: 'phone_number', value: '+14155552671' },

});




// retry.status === 'retry' lorsque l'on est dans la fenêtre temporelle

// Renvoie 429 Too Many Requests si le nombre max de tentatives est atteint

// ou si l'appel est effectué avant le délai minimum entre deux essais
// Prelude – retry (même appel que pour la création)

const retry = await client.verification.create({

  target: { type: 'phone_number', value: '+14155552671' },

});




// retry.status === 'retry' lorsque l'on est dans la fenêtre temporelle

// Renvoie 429 Too Many Requests si le nombre max de tentatives est atteint

// ou si l'appel est effectué avant le délai minimum entre deux essais

Vous pouvez configurer le nombre maximal de tentatives ainsi que la durée de la fenêtre de vérification depuis votre Dashboard Prelude.

Prévention de la fraude

Twilio Fraud Guard vs. dispositif natif de Prelude

Twilio Fraud Guard est un module complémentaire optionnel. La prévention contre la fraude de Prelude est quant à elle activée par défaut pour chaque requête, propulsée par des modèles de ML et des heuristiques entraînés sur des dizaines de millions de données à travers tout le réseau de Prelude.

Signaux à transmettre

Plus vous fournissez de signaux, plus la détection de la fraude gagne en efficacité. Le tableau ci-dessous estime la hausse du taux de conversion par signal fourni :

Champ du signal

Hausse estimée • Remarques

signals.ip

+50%  •  IPv4 ou IPv6 publique de l'appareil de l'utilisateur final. Derrière un proxy, utilisez X-Forwarded-For / CF-Connecting-IP.

signals.device_id

+40%  •  Identifiant unique stable par appareil (Android : ANDROID_ID, iOS : identifierForVendor).

signals.device_platform

+35%  •  'ios' ou 'android'.

signals.ja4_fingerprint

+30%  •  Détecté automatiquement avec les SDK Frontend de Prelude ; à envoyer manuellement si vous gérez vous-même la couche TLS.

signals.device_model

+20%  •  Chaîne correspondant au modèle d'appareil.

signals.os_version

+20%  •  Version du système d'exploitation.

signals.app_version

+10%  •  Version de votre application.

Utilisation des SDK Frontend pour des signaux enrichis et l'empreinte réseau

Installez l'un des SDK Frontend de Prelude (Android, iOS, Web, React Native, Flutter) pour collecter automatiquement les données de l'appareil. Le SDK récupère automatiquement les signaux et vous fournit un dispatch_id à transmettre lors de l'appel de vérification en backend.

// Exemple SDK Web – récupération du dispatch_id côté frontend

import { dispatchSignals } from "@prelude.so/js-sdk/signals";




const dispatchId = await dispatchSignals(<votre-prelude-sdk-key>);




// Backend – envoi du dispatch_id pour lier les signaux de l'appareil

const verification = await client.verification.create({

target: { type

// Exemple SDK Web – récupération du dispatch_id côté frontend

import { dispatchSignals } from "@prelude.so/js-sdk/signals";




const dispatchId = await dispatchSignals(<votre-prelude-sdk-key>);




// Backend – envoi du dispatch_id pour lier les signaux de l'appareil

const verification = await client.verification.create({

target: { type

Canaux & Multi-Routage

Twilio Verify requiert de spécifier explicitement un canal ('sms', 'whatsapp', 'call', 'email'). Prelude quant à lui sélectionne automatiquement la meilleure option et la route optimale selon le coût, le taux de conversion et les indices de fraude, vous évitant de devoir concevoir la logique de sélection des opérateurs ou des canaux.

Aucune action requise : Supprimez le champ correspondant au canal de vos payloads. L'outil de multi-routage de Prelude gère la sélection automatiquement. Vous pouvez toujours paramétrer des canaux favoris depuis le Dashboard si vous le souhaitez.

Contenu des messages & Personnalisation

Prelude envoie l'OTP sous la forme suivante :

12345 est votre code de vérification.

Le message est traduit automatiquement dans 32 langues en se basant sur l'indicatif pays du numéro de téléphone. Options de personnalisation disponibles (paramétrables sur le Dashboard ou à la demande) :

  • Suffixe de marque – ex. “12345 est votre code de vérification pour {nom de l'entreprise}.”

  • Avertissement de sécurité – ex. “Ne le partagez pas.”

  • Langue spécifique – via options.locale (format BCP-47).

  • Longueur du code – de 4 à 8 chiffres défini sur le Dashboard, peut être écrasé via options.code_size.

  • Code OTP personnalisé – fournissez votre propre code via options.custom_code (soumis à validation).

  • Modèle PSD2 – modèle conforme pour les transactions PSD2 via options.template_id: 'prelude:psd2'.

Webhooks

Twilio – avant

Twilio envoie un POST StatusCallback vers l'URL que vous indiquez sur le service de vérification ou par requête.

Prelude – après

Renseignez un callback_url par requête de vérification.

const verification = await client.verification.create({

  target: {

    type: 'phone_number',

    value: '+14155552671',

  },

  options: {

    callback_url: 'https://votre-app.example.com/webhooks/prelude',

  },

});
const verification = await client.verification.create({

  target: {

    type: 'phone_number',

    value: '+14155552671',

  },

  options: {

    callback_url: 'https://votre-app.example.com/webhooks/prelude',

  },

});

Types d'événements

Type d'événement

Description

verify.authentication

La vérification a été créée et facturée.

verify.attempt

Une tentative d'OTP a été envoyée à l'utilisateur.

verify.delivery_status

Mise à jour du statut d'acheminement reçue de l'opérateur.

Contrôle des signatures

Prelude signe l'ensemble des webhooks en employant RSASSA-PSS sur le hash SHA-256 du payload. La signature se situe dans l'en-tête X-Webhook-Signature, précédée de rsassa-pss-sha256=. Créez une clé de signature depuis votre Dashboard.

Liste d'IP autorisées (Allowlist)

Ajoutez ces adresses IP de sortie de Prelude à votre pare-feu :

  • 34.252.67.209

  • 52.30.192.161

  • 34.248.153.151

Tester votre intégration

Numéros magiques Twilio vs. numéros de test Prelude

Les deux plateformes mettent à disposition des numéros réservés pour les tests automatisés, exempts de facturation. Chez Prelude, ces numéros de test se configurent via le Dashboard dans Verify API > Configure > Numbers.

Pour chaque numéro de test, vous pré-définissez un code fixe. Seul ce code sera validé par l'endpoint Check, facilitant l'écriture de scénarios succès/échec dans vos suites de tests.

Bonne pratique :  Utilisez des numéros de test au sein de vos pipelines CI/CD. Renseignez-les sur votre Dashboard avant de lancer vos phases de tests d'intégration. 

Installation & Initialisation du SDK

Node.js

# Retirer Twilio

npm uninstall twilio




# Installer Prelude

npm add @prelude.so/sdk
# Retirer Twilio

npm uninstall twilio




# Installer Prelude

npm add @prelude.so/sdk
import Prelude from '@prelude.so/sdk';




const client = new Prelude({

  apiToken: process.env.PRELUDE_API_KEY,

});
import Prelude from '@prelude.so/sdk';




const client = new Prelude({

  apiToken: process.env.PRELUDE_API_KEY,

});

Python

# Retirer Twilio

pip uninstall twilio




# Installer Prelude

pip install prelude_python_sdk
# Retirer Twilio

pip uninstall twilio




# Installer Prelude

pip install prelude_python_sdk
from prelude_python_sdk import Prelude

import os




client = Prelude(api_token=os.environ['PRELUDE_API_KEY'])
from prelude_python_sdk import Prelude

import os




client = Prelude(api_token=os.environ['PRELUDE_API_KEY'])

Go

go get github.com/prelude-so/go-sdk
go get github.com/prelude-so/go-sdk
import (

  "github.com/prelude-so/go-sdk"

  "github.com/prelude-so/go-sdk/option"




client := prelude.NewClient(

  option.WithAPIToken(os.Getenv("PRELUDE_API_KEY")),

)
import (

  "github.com/prelude-so/go-sdk"

  "github.com/prelude-so/go-sdk/option"




client := prelude.NewClient(

  option.WithAPIToken(os.Getenv("PRELUDE_API_KEY")),

)

Java / Kotlin

// build.gradle

implementation("so.prelude.sdk:prelude-java:0.2.0")




// Initialisation

PreludeClient client = PreludeOkHttpClient.fromEnv();

// Définir la variable d'environnement API_TOKEN
// build.gradle

implementation("so.prelude.sdk:prelude-java:0.2.0")




// Initialisation

PreludeClient client = PreludeOkHttpClient.fromEnv();

// Définir la variable d'environnement API_TOKEN

Ruby

# Gemfile

gem 'prelude_sdk'




# Initialisation

require 'prelude_sdk'

prelude = PreludeSDK::Client.new(api_token: ENV['API_TOKEN'])
# Gemfile

gem 'prelude_sdk'




# Initialisation

require 'prelude_sdk'

prelude = PreludeSDK::Client.new(api_token: ENV['API_TOKEN'])

Checklist de migration

Parcourez chaque étape ci-dessous pour finaliser votre transition :

Phase 1 – Initialisation

  • Inscrivez-vous sur app.prelude.so et connectez-vous sur le Dashboard.

  • Générez une clé d'API via Dashboard > Configure > API Keys.

  • Ajoutez PRELUDE_API_KEY dans votre gestionnaire de secrets / de variables d'environnement.

  • Installez le SDK Prelude correspondant à votre langage (voir Section 12).

  • Configurez vos numéros de test sous Dashboard > Verify API > Configure > Numbers.

Phase 2 – Ajustements du code

  • Remplacez l'initialisation du SDK Twilio par celle de Prelude (voir Section 12).

  • Remplacez verifications.create(...) par client.verification.create(...).

  • Remplacez verificationChecks.create(...) par client.verification.check(...).

  • Modifiez vos validations de statut de 'approved' à 'success' et de 'pending' à 'success'.

  • Retirez le paramètre channel – Prelude sélectionne automatiquement le meilleur canal.

  • Supprimez les références de type ServiceSID.

  • Transmettez les signaux liés à la fraude (signals.ip, signals.device_id, etc.) lors de l'appel de création.

  • Mettez à jour le gestionnaire de webhooks pour intercepter les types d'événements Prelude (voir Section 10.3).

  • Intégrez la validation des signatures de webhooks (RSASSA-PSS, voir Section 10.4).

Phase 3 – Phase de test

  • Exécutez un test complet de bout en bout en pré-production à l'aide d'un véritable numéro de téléphone.

  • Validez la bonne réception des webhooks ainsi que la lecture du payload.

  • Vérifiez que les flux de blocage/fraude renvoient bien le statut prévu.

Phase 4 – Déploiement

  • Déployez en production (un déploiement progressif ou par feature flags est fortement conseillé).

  • Surveillez de près vos taux de conversion et de blocage depuis le Dashboard Prelude.

  • Supprimez vos anciennes informations d'identification Twilio de votre gestionnaire de secrets.

Référentiel des codes d'erreur

Prelude tire parti des codes d'état HTTP conventionnels. Le corps de réponse encapsule un objet JSON contenant les clés code et message.

Statut HTTP / Code

Description

429 too_many_attempts

Nombre maximal d'essais autorisé atteint pour cette fenêtre de vérification.

429 premature_retry

Nouvel essai demandé avant la fin du temps d'attente imposé entre deux essais.

429 too_many_checks

Nombre maximal de validations de code atteint.

400 invalid_phone_number

Le numéro de téléphone n'est pas formaté selon la norme E.164.

401 unauthorized

Clé API non valide ou manquante.

Pour consulter la liste complète des erreurs en 4xx

https://docs.prelude.so/introduction/errors

Support & Ressources

Pourquoi devrions-nous migrer de Twilio à Prelude ?

Il y a quatre raisons majeures pour lesquelles les équipes franchissent le pas :

  • Coûts réduits. Les entreprises constatent généralement une baisse de 30 à 40 % de leurs dépenses mensuelles en SMS, principalement parce que le bouclier anti-fraude de Prelude intercepte le faux trafic avant qu'il n'atteigne les opérateurs — vous ne payez pas pour les messages frauduleux.

  • Meilleure conversion. Le système automatisé de routage multi-canal choisit le meilleur opérateur et canal pour chaque destination, améliorant ainsi la délivrabilité. Les équipes constatent typiquement une hausse de 20 à 30 % des conversions d'OTP.

  • Prévention contre la fraude incluse. Twilio Fraud Guard est une option payante. Sur Prelude, la détection de la fraude basée sur le ML est en place par défaut pour chaque requête, grâce à des modèles entraînés sur des dizaines de millions de données globales du réseau.

  • Intégration simplifiée. Deux services de Twilio (Verify + Programmable Messaging) fusionnent en une seule API chez Prelude. Finis les ServiceSID, les règles de sélection de canaux ou la gestion fastidieuse des opérateurs — le périmètre d'intégration est grandement réduit.

La migration est très sûre : l'API Prelude a été pensée pour faire directement écho aux concepts de Twilio Verify, permettant à la plupart des équipes de finaliser et déployer l'intégration sous forme de feature flag en un sprint seulement. Découvrez comment Finfrog, fintech française de crédit, a réduit ses coûts de SMS de 45 % suite à sa migration : Étude de cas Finfrog

Nous sommes satisfaits de Twilio. Cela vaut-il la peine de changer ?

L'effort de migration est faible, requérant généralement quelques jours de développement, assurant un retour sur investissement rapide, même avec un gain modéré en coût ou conversion. La bascule fait particulièrement sens si :

  • Vous observez de la fraude aux SMS ou des abus de vérification récurrents.

  • Vos taux de délivrabilité d'OTP fluctuent fortement selon les pays ou les opérateurs.

  • Vous payez pour Twilio Fraud Guard en supplément.

  • Vous désirez proposer d'autres canaux en dehors du SMS (WhatsApp, Viber, RCS, Zalo) sans pour autant concevoir la logique de routage vous-même.

Un déploiement progressif (canari) vous permet de valider directement l’impact avant de vous engager pleinement — aiguillez par exemple 5 à 10 % de votre trafic sur Prelude et analysez les chiffres de conversion et de blocage sur le Dashboard. C'est exactement cette formule qu'a adoptée Finfrog pour basculer la totalité de son trafic en quelques jours : lire l'étude de cas

Combien de temps prend la migration ?

La majorité des équipes techniques dédiées au backend finalisent la bascule en un seul sprint. Adapter le code — intégrer le nouveau SDK, réajuster les méthodes d'envoi et de vérification et harmoniser les statuts — ne prend que quelques heures. La validation des signatures de webhooks et l'intégration des signaux de fraude peuvent être déployées dans un second temps de façon incrémentale.

Puis-je utiliser Twilio et Prelude en parallèle lors d'un déploiement progressif ?

Oui, et c'est en réalité la méthode conseillée. Structurez votre appel de vérification derrière un feature flag pour ne router dans un premier temps qu'une part réduite de votre trafic vers Prelude. Prêtez attention à vos taux de conversion et aux rejets sur le Dashboard Prelude puis augmentez le volume d'appels à votre rythme. Conservez vos identifiants Twilio actifs tant que la transition n'est pas finalisée et que vos indicateurs clés ne sont pas confirmés.

La détection de la fraude est-elle active d'office ou dois-je l'activer ?

Elle est active de base sur toutes les requêtes, contrairement à Twilio Fraud Guard qui relève d’une option payante à activer. Les modèles de ML de Prelude s’exécutent à chaque validation en tâche de fond. Vous bénéficiez d'une sécurité standard sans configuration requise. Transmettre des signaux liés aux appareils (ipdevice_iddevice_platform) accroît progressivement la précision des analyses au-delà du socle par défaut.

Dispose-t-on d'un Dashboard d'analyse en temps réel pour suivre les taux de livraison et de blocage ?

Oui, tout à fait. Le Dashboard Prelude vous donne une visibilité immédiate de vos taux de conversion, des taux de blocage, de la segmentation des statuts de livraison et de la répartition des canaux utilisés. Suivez ces métriques pendant et après votre déploiement pour valider les performances avant d'éteindre définitivement votre compte Twilio.

Remplacer votre fournisseur d'OTP ne doit pas nécessairement être un projet multi-sprint. L'API Verify unifiée de Prelude se calque directement sur les concepts de Twilio Verify. Prelude fournit un point de terminaison REST unique qui gère l'ensemble du cycle de vie des OTP, de la détection de la fraude au routage multi-canal. La plupart des équipes déploient une solution de remplacement fonctionnelle en un seul sprint.

Pourquoi migrer ? Les entreprises qui passent à Prelude constatent généralement des taux de conversion de 20 à 30 % plus élevés et des coûts de SMS mensuels de 30 à 40 % inférieurs, en plus d'une prévention de la fraude intégrée basée sur le ML qui ne requiert aucun outil personnalisé.

Ce qui change

À haut niveau, vous remplacez deux interfaces Twilio : Programmable Messaging et Twilio Verify par une seule API Prelude. Le tableau ci-dessous associe chaque concept Twilio à son équivalent Prelude.

Concept

Twilio Verify

Prelude Verify

Catégorie de service

Twilio Programmable Messaging + Twilio Verify

API Prelude Verify (service unique)

URL de base de l'API

api.twilio.com/2010-04-01/Accounts/{SID}

api.prelude.dev

Authentification

HTTP Basic (AccountSID:AuthToken)

Jeton Bearer dans l'en-tête Authorization

Envoyer un OTP

POST /Services/{ServiceSID}/Verifications

POST /v2/verification

Vérifier un OTP

POST /Services/{ServiceSID}/VerificationChecks

POST /v2/verification/check

Ressaisir l'OTP

POST /Services/{ServiceSID}/Verifications (répéter)

POST /v2/verification (même numéro, dans la fenêtre de temps)

Statut de la vérification

pending / approved / canceled

success / retry / blocked / challenged

Service / espace de noms

Verify Service (ServiceSID)

Implicite par clé API (configurée dans le Dashboard)

Prévention de la fraude

Twilio Fraud Guard (add-on)

ML intégré, activé par défaut

Canaux

SMS, WhatsApp, appel, e-mail

SMS, WhatsApp, Viber, Zalo, RCS, voix, e-mail

Expéditeur / marque

Service de messagerie ou numéro de téléphone

Configuré en contactant le support client (Sender ID)

Numéros de test

Numéros magiques par service Verify

Numéros de test dans le Dashboard (Verify > Configure > Numbers)

Webhooks

URL StatusCallback par requête

callback_url par requête ; signature via RSASSA-PSS

SDKs

twilio-node, twilio-python, etc.

npm @prelude.so/sdk, pip prelude_python_sdk, go-sdk, Java, Ruby

Authentification

Twilio (avant)

Twilio utilise l'authentification HTTP Basic avec votre SID de compte comme identifiant et votre jeton de sécurité comme mot de passe.

# Twilio HTTP Basic Auth

curl -X POST https://verify.twilio.com/v2/Services/{ServiceSID}/Verifications \

  -u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN \

  -d 'To=+14155552671' \

  -d 'Channel=sms'

Prelude (après)

Prelude utilise un jeton Bearer. Générez une clé API dans le Dashboard sous Settings > API Keys.

# Prelude Bearer Token

curl -X POST https://api.prelude.dev/v2/verification \

  -H “Authorization: Bearer $PRELUDE_API_KEY” \

  -H 'Content-Type: application/json' \

  -d '{"target": {"type": "phone_number", "value": "+14155552671"}}'

Action requise :  Stockez votre clé API Prelude dans une variable d'environnement (ex: PRELUDE_API_KEY). Ne la soumettez jamais dans votre gestionnaire de version. Supprimez TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, et VERIFY_SERVICE_SID une fois la migration terminée.

Envoi d'une vérification (OTP)

Twilio Verify – avant

// Node.js – Twilio Verify

const client = require('twilio')(accountSid, authToken);



const verification = await client.verify.v2

  .services(verifySid)

  .verifications

  .create({ to: '+14155552671', channel: 'sms' });



console.log(verification.status); // 'pending'

Prelude – après

// Node.js – Prelude SDK

import Prelude from '@prelude.so/sdk';



const client = new Prelude({ apiToken: process.env.PRELUDE_API_KEY });



const verification = await client.verification.create({

  target: { type: 'phone_number', value: '+14155552671' },

  // Optionnel : transmettre des signaux digitaux pour mieux contrer la fraude

  signals: {

    ip: '203.0.113.42',          // IP publique de l'utilisateur final

    device_id: 'abc123-unique',   // identifiant unique et stable du périphérique

    device_platform: 'ios',

    device_model: 'iPhone 15',

  },

});



console.log(verification.id);     // 'vrf_01...'

console.log(verification.status); // 'success' | 'blocked' | 'challenged'

Valeurs de statut

Prelude renvoie un ensemble de statuts plus riche lors du lancement d'une vérification :

Statut

Signification

success

Nouvelle fenêtre de vérification ouverte ; code envoyé à l'utilisateur.

retry

Même numéro de téléphone sollicité à nouveau à l'intérieur de la fenêtre de tir ; nouvelle tentative envoyée.

blocked

Requête identifiée comme frauduleuse ; aucun code envoyé, pas de facturation d'envoi de message.

challenged

Trafic suspect ; livraison limitée aux canaux alternatifs hors SMS (doit être activé par le support Prelude).

Vérification d'un code de validation

Twilio Verify – avant

// Node.js – Twilio Verify check

const check = await client.verify.v2

  .services(verifySid)

  .verificationChecks

  .create({ to: '+14155552671', code: '123456' });




if (check.status === 'approved') {

  // accorder l'accès

}

Prelude – après

// Node.js – Prelude check

const check = await client.verification.check({

  target: { type: 'phone_number', value: '+14155552671' },

  code: '123456',

});




if (check.status === 'success') {

  // accorder l'accès

}




// Statuts possibles : 'success' | 'failure' | ‘expired_or_not_found’

Gestion des nouvelles tentatives (Retries)

Dans Twilio Verify, vous lancez une nouvelle tentative en créant une nouvelle vérification pour le même numéro de téléphone au cours de la fenêtre temporelle de retry définie dans le service. Prelude fonctionne de la même manière : appelez à nouveau POST /v2/verification avec le même numéro de téléphone et Prelude détectera la fenêtre de vérification ouverte pour émettre une nouvelle tentative plutôt qu'une toute nouvelle session.

// Prelude – retry (même appel que pour la création)

const retry = await client.verification.create({

  target: { type: 'phone_number', value: '+14155552671' },

});




// retry.status === 'retry' lorsque l'on est dans la fenêtre temporelle

// Renvoie 429 Too Many Requests si le nombre max de tentatives est atteint

// ou si l'appel est effectué avant le délai minimum entre deux essais

Vous pouvez configurer le nombre maximal de tentatives ainsi que la durée de la fenêtre de vérification depuis votre Dashboard Prelude.

Prévention de la fraude

Twilio Fraud Guard vs. dispositif natif de Prelude

Twilio Fraud Guard est un module complémentaire optionnel. La prévention contre la fraude de Prelude est quant à elle activée par défaut pour chaque requête, propulsée par des modèles de ML et des heuristiques entraînés sur des dizaines de millions de données à travers tout le réseau de Prelude.

Signaux à transmettre

Plus vous fournissez de signaux, plus la détection de la fraude gagne en efficacité. Le tableau ci-dessous estime la hausse du taux de conversion par signal fourni :

Champ du signal

Hausse estimée • Remarques

signals.ip

+50%  •  IPv4 ou IPv6 publique de l'appareil de l'utilisateur final. Derrière un proxy, utilisez X-Forwarded-For / CF-Connecting-IP.

signals.device_id

+40%  •  Identifiant unique stable par appareil (Android : ANDROID_ID, iOS : identifierForVendor).

signals.device_platform

+35%  •  'ios' ou 'android'.

signals.ja4_fingerprint

+30%  •  Détecté automatiquement avec les SDK Frontend de Prelude ; à envoyer manuellement si vous gérez vous-même la couche TLS.

signals.device_model

+20%  •  Chaîne correspondant au modèle d'appareil.

signals.os_version

+20%  •  Version du système d'exploitation.

signals.app_version

+10%  •  Version de votre application.

Utilisation des SDK Frontend pour des signaux enrichis et l'empreinte réseau

Installez l'un des SDK Frontend de Prelude (Android, iOS, Web, React Native, Flutter) pour collecter automatiquement les données de l'appareil. Le SDK récupère automatiquement les signaux et vous fournit un dispatch_id à transmettre lors de l'appel de vérification en backend.

// Exemple SDK Web – récupération du dispatch_id côté frontend

import { dispatchSignals } from "@prelude.so/js-sdk/signals";




const dispatchId = await dispatchSignals(<votre-prelude-sdk-key>);




// Backend – envoi du dispatch_id pour lier les signaux de l'appareil

const verification = await client.verification.create({

target: { type

Canaux & Multi-Routage

Twilio Verify requiert de spécifier explicitement un canal ('sms', 'whatsapp', 'call', 'email'). Prelude quant à lui sélectionne automatiquement la meilleure option et la route optimale selon le coût, le taux de conversion et les indices de fraude, vous évitant de devoir concevoir la logique de sélection des opérateurs ou des canaux.

Aucune action requise : Supprimez le champ correspondant au canal de vos payloads. L'outil de multi-routage de Prelude gère la sélection automatiquement. Vous pouvez toujours paramétrer des canaux favoris depuis le Dashboard si vous le souhaitez.

Contenu des messages & Personnalisation

Prelude envoie l'OTP sous la forme suivante :

12345 est votre code de vérification.

Le message est traduit automatiquement dans 32 langues en se basant sur l'indicatif pays du numéro de téléphone. Options de personnalisation disponibles (paramétrables sur le Dashboard ou à la demande) :

  • Suffixe de marque – ex. “12345 est votre code de vérification pour {nom de l'entreprise}.”

  • Avertissement de sécurité – ex. “Ne le partagez pas.”

  • Langue spécifique – via options.locale (format BCP-47).

  • Longueur du code – de 4 à 8 chiffres défini sur le Dashboard, peut être écrasé via options.code_size.

  • Code OTP personnalisé – fournissez votre propre code via options.custom_code (soumis à validation).

  • Modèle PSD2 – modèle conforme pour les transactions PSD2 via options.template_id: 'prelude:psd2'.

Webhooks

Twilio – avant

Twilio envoie un POST StatusCallback vers l'URL que vous indiquez sur le service de vérification ou par requête.

Prelude – après

Renseignez un callback_url par requête de vérification.

const verification = await client.verification.create({

  target: {

    type: 'phone_number',

    value: '+14155552671',

  },

  options: {

    callback_url: 'https://votre-app.example.com/webhooks/prelude',

  },

});

Types d'événements

Type d'événement

Description

verify.authentication

La vérification a été créée et facturée.

verify.attempt

Une tentative d'OTP a été envoyée à l'utilisateur.

verify.delivery_status

Mise à jour du statut d'acheminement reçue de l'opérateur.

Contrôle des signatures

Prelude signe l'ensemble des webhooks en employant RSASSA-PSS sur le hash SHA-256 du payload. La signature se situe dans l'en-tête X-Webhook-Signature, précédée de rsassa-pss-sha256=. Créez une clé de signature depuis votre Dashboard.

Liste d'IP autorisées (Allowlist)

Ajoutez ces adresses IP de sortie de Prelude à votre pare-feu :

  • 34.252.67.209

  • 52.30.192.161

  • 34.248.153.151

Tester votre intégration

Numéros magiques Twilio vs. numéros de test Prelude

Les deux plateformes mettent à disposition des numéros réservés pour les tests automatisés, exempts de facturation. Chez Prelude, ces numéros de test se configurent via le Dashboard dans Verify API > Configure > Numbers.

Pour chaque numéro de test, vous pré-définissez un code fixe. Seul ce code sera validé par l'endpoint Check, facilitant l'écriture de scénarios succès/échec dans vos suites de tests.

Bonne pratique :  Utilisez des numéros de test au sein de vos pipelines CI/CD. Renseignez-les sur votre Dashboard avant de lancer vos phases de tests d'intégration. 

Installation & Initialisation du SDK

Node.js

# Retirer Twilio

npm uninstall twilio




# Installer Prelude

npm add @prelude.so/sdk
import Prelude from '@prelude.so/sdk';




const client = new Prelude({

  apiToken: process.env.PRELUDE_API_KEY,

});

Python

# Retirer Twilio

pip uninstall twilio




# Installer Prelude

pip install prelude_python_sdk
from prelude_python_sdk import Prelude

import os




client = Prelude(api_token=os.environ['PRELUDE_API_KEY'])

Go

go get github.com/prelude-so/go-sdk
import (

  "github.com/prelude-so/go-sdk"

  "github.com/prelude-so/go-sdk/option"




client := prelude.NewClient(

  option.WithAPIToken(os.Getenv("PRELUDE_API_KEY")),

)

Java / Kotlin

// build.gradle

implementation("so.prelude.sdk:prelude-java:0.2.0")




// Initialisation

PreludeClient client = PreludeOkHttpClient.fromEnv();

// Définir la variable d'environnement API_TOKEN

Ruby

# Gemfile

gem 'prelude_sdk'




# Initialisation

require 'prelude_sdk'

prelude = PreludeSDK::Client.new(api_token: ENV['API_TOKEN'])

Checklist de migration

Parcourez chaque étape ci-dessous pour finaliser votre transition :

Phase 1 – Initialisation

  • Inscrivez-vous sur app.prelude.so et connectez-vous sur le Dashboard.

  • Générez une clé d'API via Dashboard > Configure > API Keys.

  • Ajoutez PRELUDE_API_KEY dans votre gestionnaire de secrets / de variables d'environnement.

  • Installez le SDK Prelude correspondant à votre langage (voir Section 12).

  • Configurez vos numéros de test sous Dashboard > Verify API > Configure > Numbers.

Phase 2 – Ajustements du code

  • Remplacez l'initialisation du SDK Twilio par celle de Prelude (voir Section 12).

  • Remplacez verifications.create(...) par client.verification.create(...).

  • Remplacez verificationChecks.create(...) par client.verification.check(...).

  • Modifiez vos validations de statut de 'approved' à 'success' et de 'pending' à 'success'.

  • Retirez le paramètre channel – Prelude sélectionne automatiquement le meilleur canal.

  • Supprimez les références de type ServiceSID.

  • Transmettez les signaux liés à la fraude (signals.ip, signals.device_id, etc.) lors de l'appel de création.

  • Mettez à jour le gestionnaire de webhooks pour intercepter les types d'événements Prelude (voir Section 10.3).

  • Intégrez la validation des signatures de webhooks (RSASSA-PSS, voir Section 10.4).

Phase 3 – Phase de test

  • Exécutez un test complet de bout en bout en pré-production à l'aide d'un véritable numéro de téléphone.

  • Validez la bonne réception des webhooks ainsi que la lecture du payload.

  • Vérifiez que les flux de blocage/fraude renvoient bien le statut prévu.

Phase 4 – Déploiement

  • Déployez en production (un déploiement progressif ou par feature flags est fortement conseillé).

  • Surveillez de près vos taux de conversion et de blocage depuis le Dashboard Prelude.

  • Supprimez vos anciennes informations d'identification Twilio de votre gestionnaire de secrets.

Référentiel des codes d'erreur

Prelude tire parti des codes d'état HTTP conventionnels. Le corps de réponse encapsule un objet JSON contenant les clés code et message.

Statut HTTP / Code

Description

429 too_many_attempts

Nombre maximal d'essais autorisé atteint pour cette fenêtre de vérification.

429 premature_retry

Nouvel essai demandé avant la fin du temps d'attente imposé entre deux essais.

429 too_many_checks

Nombre maximal de validations de code atteint.

400 invalid_phone_number

Le numéro de téléphone n'est pas formaté selon la norme E.164.

401 unauthorized

Clé API non valide ou manquante.

Pour consulter la liste complète des erreurs en 4xx

https://docs.prelude.so/introduction/errors

Support & Ressources

Pourquoi devrions-nous migrer de Twilio à Prelude ?

Il y a quatre raisons majeures pour lesquelles les équipes franchissent le pas :

  • Coûts réduits. Les entreprises constatent généralement une baisse de 30 à 40 % de leurs dépenses mensuelles en SMS, principalement parce que le bouclier anti-fraude de Prelude intercepte le faux trafic avant qu'il n'atteigne les opérateurs — vous ne payez pas pour les messages frauduleux.

  • Meilleure conversion. Le système automatisé de routage multi-canal choisit le meilleur opérateur et canal pour chaque destination, améliorant ainsi la délivrabilité. Les équipes constatent typiquement une hausse de 20 à 30 % des conversions d'OTP.

  • Prévention contre la fraude incluse. Twilio Fraud Guard est une option payante. Sur Prelude, la détection de la fraude basée sur le ML est en place par défaut pour chaque requête, grâce à des modèles entraînés sur des dizaines de millions de données globales du réseau.

  • Intégration simplifiée. Deux services de Twilio (Verify + Programmable Messaging) fusionnent en une seule API chez Prelude. Finis les ServiceSID, les règles de sélection de canaux ou la gestion fastidieuse des opérateurs — le périmètre d'intégration est grandement réduit.

La migration est très sûre : l'API Prelude a été pensée pour faire directement écho aux concepts de Twilio Verify, permettant à la plupart des équipes de finaliser et déployer l'intégration sous forme de feature flag en un sprint seulement. Découvrez comment Finfrog, fintech française de crédit, a réduit ses coûts de SMS de 45 % suite à sa migration : Étude de cas Finfrog

Nous sommes satisfaits de Twilio. Cela vaut-il la peine de changer ?

L'effort de migration est faible, requérant généralement quelques jours de développement, assurant un retour sur investissement rapide, même avec un gain modéré en coût ou conversion. La bascule fait particulièrement sens si :

  • Vous observez de la fraude aux SMS ou des abus de vérification récurrents.

  • Vos taux de délivrabilité d'OTP fluctuent fortement selon les pays ou les opérateurs.

  • Vous payez pour Twilio Fraud Guard en supplément.

  • Vous désirez proposer d'autres canaux en dehors du SMS (WhatsApp, Viber, RCS, Zalo) sans pour autant concevoir la logique de routage vous-même.

Un déploiement progressif (canari) vous permet de valider directement l’impact avant de vous engager pleinement — aiguillez par exemple 5 à 10 % de votre trafic sur Prelude et analysez les chiffres de conversion et de blocage sur le Dashboard. C'est exactement cette formule qu'a adoptée Finfrog pour basculer la totalité de son trafic en quelques jours : lire l'étude de cas

Combien de temps prend la migration ?

La majorité des équipes techniques dédiées au backend finalisent la bascule en un seul sprint. Adapter le code — intégrer le nouveau SDK, réajuster les méthodes d'envoi et de vérification et harmoniser les statuts — ne prend que quelques heures. La validation des signatures de webhooks et l'intégration des signaux de fraude peuvent être déployées dans un second temps de façon incrémentale.

Puis-je utiliser Twilio et Prelude en parallèle lors d'un déploiement progressif ?

Oui, et c'est en réalité la méthode conseillée. Structurez votre appel de vérification derrière un feature flag pour ne router dans un premier temps qu'une part réduite de votre trafic vers Prelude. Prêtez attention à vos taux de conversion et aux rejets sur le Dashboard Prelude puis augmentez le volume d'appels à votre rythme. Conservez vos identifiants Twilio actifs tant que la transition n'est pas finalisée et que vos indicateurs clés ne sont pas confirmés.

La détection de la fraude est-elle active d'office ou dois-je l'activer ?

Elle est active de base sur toutes les requêtes, contrairement à Twilio Fraud Guard qui relève d’une option payante à activer. Les modèles de ML de Prelude s’exécutent à chaque validation en tâche de fond. Vous bénéficiez d'une sécurité standard sans configuration requise. Transmettre des signaux liés aux appareils (ipdevice_iddevice_platform) accroît progressivement la précision des analyses au-delà du socle par défaut.

Dispose-t-on d'un Dashboard d'analyse en temps réel pour suivre les taux de livraison et de blocage ?

Oui, tout à fait. Le Dashboard Prelude vous donne une visibilité immédiate de vos taux de conversion, des taux de blocage, de la segmentation des statuts de livraison et de la répartition des canaux utilisés. Suivez ces métriques pendant et après votre déploiement pour valider les performances avant d'éteindre définitivement votre compte Twilio.

Start optimizing your auth flow

Send verification text-messages anywhere in the world with the best price, the best deliverability and no spam.