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. 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. 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. 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.

buy-and-wait.sh
# 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.

legacy-compat.sh
# 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.87

Agents, 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.

mcp.json
{
  "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.