API de vérification par SMS
L'API de vérification par SMS tient en trois appels : acheter un numéro, attendre le code, libérer le numéro. Elle atteint 517 services dans 225 pays, les numéros démarrent à 0,07 €, et une activation qui ne reçoit rien est remboursée sans ticket au support. Les clés sont limitées par scope, les achats sont idempotents, et les anciens clients handler_api fonctionnent sans modification.
L'API en un bloc
Mis à jour le 28 août 2026- URL de base
- https://virtualsmsnumbers.com/api/v1
- Authentification
- Clé bearer, ou X-Api-Key
- Limite de débit
- 120/min, pointe 20/s
- Fenêtre d'idempotence
- 24 heures
- Remboursement auto après
- 20 minutes
- Activation la moins chère
- 0,07 €
- Pays couverts
- 225
- Format
- JSON, centimes, ISO 8601 UTC
Les prix et les stocks proviennent du pool d'opérateurs tel qu'il est en ce moment, pas d'une grille tarifaire publiée.
Le parcours en trois appels
Tout le reste de la référence est facultatif. Voici l'intégralité du chemin de vérification, inchangé depuis 2019.
- 1
POST /activations
Demandez un service, et un pays si cela vous importe. La réponse porte le numéro, le prix en centimes et l'horodatage d'expiration. Envoyez un Idempotency-Key pour qu'une requête rejouée ne puisse pas acheter un second numéro, et un max_price_cents si l'appelant est automatisé.
- 2
GET /activations/{id}?wait=180
Long poll. La connexion reste ouverte jusqu'à l'arrivée du message ou l'expiration du délai : une requête remplace ainsi une boucle qui en ferait quatre-vingt-dix. Le statut revient en code_received, avec le code analysé à côté du texte brut, car les expéditeurs le formatent différemment.
- 3
POST /activations/{id}/complete
Fermez l'activation et libérez la ligne. Si rien n'est arrivé, ne faites rien du tout : la fenêtre expire d'elle-même et le solde est recrédité. Annuler par avance est le même appel sous un autre nom.
Un exemple qui fonctionne
Définissez VSN_KEY et lancez-le. Les réponses en commentaire sont les formes réelles, avec les champs que vous voudrez stocker.
# 1. Buy a Telegram number in Portugal
-kw">curl -X POST https://virtualsmsnumbers.com/api/v1/activations \
-H "Authorization: Bearer $VSN_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"service":"telegram","country":"PT"}'
# {"id":"1043872915","phone_number":"351926114508","status":"waiting",
# "price_cents":11,"expires_at":"2026-08-26T12:41:07Z"}
# 2. Long-poll until the code lands (blocks up to 120 s)
-kw">curl "https://virtualsmsnumbers.com/api/v1/activations/1043872915?wait=120" \
-H "Authorization: Bearer $VSN_KEY"
# {"id":"1043872915","status":"code_received",
# "messages":[{"code":"48219","text":"Telegram code: 48219"}]}
# 3. Release the number
-kw">curl -X POST https://virtualsmsnumbers.com/api/v1/activations/1043872915/complete \
-H "Authorization: Bearer $VSN_KEY"Limites de débit
120 requêtes par minute et par clé, avec des pointes à 20 par seconde. Chaque réponse porte X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset, et un 429 vous dit combien de temps attendre au lieu de vous laisser deviner.
La limite est rarement contraignante si l'API est utilisée comme prévu : un long poll au lieu de quatre-vingt-dix interrogations, un webhook au lieu d'un minuteur, et les listes de pays et de services mises en cache au démarrage. S'il vous faut vraiment plus de marge, demandez-la : relever une limite est plus simple pour tout le monde que de déboguer une flotte de clés.
Idempotence
Envoyez un en-tête Idempotency-Key sur POST /activations. Rejouer la même clé dans les 24 heures renvoie l'activation initiale dans son état actuel, avec un en-tête Idempotent-Replay, au lieu d'acheter un second numéro et de vous facturer deux fois.
La clé n'est pas un hachage du corps : une charge utile différente sous une clé déjà utilisée renvoie quand même la première activation. Générez une clé par achat logique — un UUID convient — et réutilisez-la entre les tentatives, jamais entre les achats.
Anciens clients handler_api
Les scripts écrits pour le protocole classique handler_api.php continuent de fonctionner. Pointez-les vers l'endpoint de compatibilité, remplacez l'api_key, et les mêmes actions renvoient les mêmes jetons ACCESS_ et STATUS_ qu'auparavant.
C'est une couche de traduction au-dessus du même pool : prix, stocks et remboursements se comportent donc à l'identique. Le nouveau code devrait tout de même utiliser /api/v1, dont les réponses JSON portent des horodatages, des codes d'erreur et des champs de prix que le format à jetons ne peut pas exprimer.
# Existing scripts keep working: same actions, same response tokens.
BASE="https://virtualsmsnumbers.com/stubs/handler_api.php"
-kw">curl "$BASE?api_key=$KEY&action=getNumber&service=tg&country=117"
# ACCESS_NUMBER:1043872915:351926114508
-kw">curl "$BASE?api_key=$KEY&action=getStatus&id=1043872915"
# STATUS_WAIT_CODE
# STATUS_OK:48219
-kw">curl "$BASE?api_key=$KEY&action=setStatus&id=1043872915&status=6"
# ACCESS_ACTIVATION
-kw">curl "$BASE?api_key=$KEY&action=getBalance"
# ACCESS_BALANCE:41.87Agents, MCP et découverte
Il existe un serveur MCP hébergé, un document OpenAPI 3.1 et un index llms.txt : un agent peut donc découvrir les trois outils dont il a besoin sans code de liaison écrit à la main. Pointez votre client vers l'endpoint ci-dessous et il trouvera l'achat, l'attente et la libération.
Avant de laisser quoi que ce soit d'autonome dépenser sur le solde : limitez la clé à numbers:read et numbers:write, fixez un plafond max_price_cents sur chaque achat, et donnez-lui sa propre clé pour que la révoquer ne coupe pas votre intégration de production.
{
"mcpServers": {
"virtualsmsnumbers": {
"type": "http",
"url": "https://virtualsmsnumbers.com/api/mcp",
"headers": { "Authorization": "Bearer vsn_live_xxxxxxxxxxxx" }
}
}
}Avant la production
- Fixez max_price_cents sur chaque achat. Les prix suivent le pool, et un agent sans plafond achètera volontiers le haut de la fourchette.
- Traitez les identifiants comme des chaînes opaques. Les identifiants d'activation font dix chiffres aujourd'hui ; ce n'est pas une promesse, et leur longueur non plus.
- Branchez sur le code d'erreur, jamais sur le message. Les codes sont stables au sein d'une version ; les messages sont écrits pour des humains et finissent réécrits.
- Abonnez-vous à sms.received et vérifiez la signature — HMAC-SHA256 sur le corps brut, avec une fenêtre de rejeu de cinq minutes — plutôt que d'interroger un état dont on peut vous avertir.
- Faites les calculs sur les champs entiers en centimes. Les chaînes formatées à côté servent à l'affichage et dépendent de la locale.
La référence complète
Six endpoints, tables d'erreurs, charges utiles des webhooks, scopes et correspondance des anciens jetons.
Questions fréquentes
La réception médiane est inférieure à neuf secondes à partir de l'envoi par le service. Le long poll existe parce que la traîne est longue : l'activation reste ouverte 20 minutes, puis expire en remboursement si rien n'arrive.
Rien que vous ayez à gérer. La fenêtre se ferme, le solde est recrédité automatiquement, et l'activation se termine dans un état expiré que vous pouvez lire depuis l'API.
Oui, et cela ne coûte rien. Les clés portent des scopes fixes, une liste d'IP autorisées facultative et une expiration choisie à la création : une clé de préproduction qui fuit ne peut pas acheter de numéros en production.
Il existe des wrappers légers et sans dépendances, mais l'API tient en six endpoints sur JSON : fetch, requests ou curl suffisent vraiment pour le parcours en trois appels.
Sur une même activation, oui : les messages supplémentaires arrivent sur le même numéro tant qu'elle est ouverte. D'une session à l'autre, il faut une location, qui retient la ligne de quatre heures à douze mois.
Non. C'est le même pool aux mêmes prix ; seul l'encodage des réponses diffère.