getBalance
Le solde du compte en dollars.
Seulement api_key et action.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getBalanceRéponse
ACCESS_BALANCE:25.00Si votre logiciel fonctionne déjà avec un service d'activation via handler_api.php, il fonctionne avec RelySMS : changez l'adresse du serveur et la clé. Mêmes actions, mêmes réponses, nos prix et nos remboursements.
https://relysms.pro/stubs/handler_api.phpChaque requête est un GET ou un POST vers une seule adresse, avec les paramètres dans l'URL ou dans un formulaire. La clé va dans api_key, l'action dans action.
getBalanceLe solde du compte en dollars.
Seulement api_key et action.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getBalanceRéponse
ACCESS_BALANCE:25.00getNumberAcheter un numéro pour un service dans un pays. Débité tout de suite ; remboursé si aucun code n'arrive. Réponse : ACCESS_NUMBER:numéro_de_commande:téléphone.
| Paramètre | Obligatoire | Description |
|---|---|---|
service | oui | Code du service (getServicesList), p. ex. tg. |
country | oui | Code du pays (getCountries). |
maxPrice | non | Prix maximal en dollars. Au-delà : WRONG_MAX_PRICE avec le prix actuel, rien n'est débité. |
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getNumber&service=tg&country=187&maxPrice=0.80Réponse
ACCESS_NUMBER:1042:15550001111Erreurs possibles: BAD_SERVICE, BAD_COUNTRY, NO_NUMBERS, NO_BALANCE, WRONG_MAX_PRICE:0.59, LIMIT_ACTIVATIONS, RATE_LIMIT, BANNED
getNumberV2Comme getNumber, avec une réponse JSON incluant le prix et les horaires de la fenêtre.
| Paramètre | Obligatoire | Description |
|---|---|---|
service | oui | Code du service. |
country | oui | Code du pays. |
maxPrice | non | Prix maximal en dollars. |
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getNumberV2&service=tg&country=187&maxPrice=0.80Réponse
{
"activationId": 1042,
"phoneNumber": "15550001111",
"activationCost": 0.59,
"countryCode": "187",
"canGetAnotherSms": true,
"activationTime": "2026-10-27T10:00:00.000Z",
"activationEndTime": "2026-10-27T10:20:00.000Z"
}Erreurs possibles: BAD_SERVICE, BAD_COUNTRY, NO_NUMBERS, NO_BALANCE, WRONG_MAX_PRICE:0.59, LIMIT_ACTIVATIONS, RATE_LIMIT
getStatusStatut de la commande : en attente du code, code reçu (avec le code) ou annulée.
| Paramètre | Obligatoire | Description |
|---|---|---|
id | oui | Numéro de commande renvoyé par getNumber. |
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getStatus&id=1042Réponse
STATUS_OK:48213Erreurs possibles: NO_ACTIVATION
setStatusAgir sur une commande : prêt, autre code, terminer, annuler (voir Statuts).
| Paramètre | Obligatoire | Description |
|---|---|---|
id | oui | Numéro de commande. |
status | oui | 1, 3, 6 ou 8. |
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=setStatus&id=1042&status=6Réponse
ACCESS_ACTIVATIONErreurs possibles: NO_ACTIVATION, BAD_STATUS, EARLY_CANCEL_DENIED, ERROR_SQL
getActiveActivationsToutes les commandes ouvertes de la clé : numéro, statut, codes et textes reçus.
Seulement api_key et action.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getActiveActivationsRéponse
{
"status": "success",
"activeActivations": [
{
"activationId": 1042,
"serviceCode": "tg",
"phoneNumber": "15550001111",
"activationCost": 0.59,
"activationStatus": "2",
"smsCode": ["48213"],
"smsText": ["Telegram code: 48213"],
"activationTime": "2026-10-27T10:00:00.000Z",
"countryCode": "187"
}
]
}getPricesNos prix en dollars et le nombre approximatif de numéros. Sans paramètres : tout ce qui est en vente.
| Paramètre | Obligatoire | Description |
|---|---|---|
service | non | Seulement ce service. |
country | non | Seulement ce pays. |
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getPrices&service=tg&country=187Réponse
{ "187": { "tg": { "cost": 0.59, "count": 1000 } } }Erreurs possibles: BAD_SERVICE, BAD_COUNTRY
getCountriesListe des pays avec les codes du protocole et les noms en russe et en anglais.
Seulement api_key et action.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getCountriesRéponse
{ "187": { "id": 187, "rus": "США", "eng": "United States", "visible": 1 } }getServicesListListe des services avec les codes du protocole.
Seulement api_key et action.
GET https://relysms.pro/stubs/handler_api.php?api_key=KEY&action=getServicesListRéponse
{ "status": "success", "services": [{ "code": "tg", "name": "Telegram" }] }Valeurs de status dans setStatus :
status=1 → ACCESS_READY — Le numéro est saisi dans le service, en attente du code. Ne change rien ; conservé pour la compatibilité.status=3 → ACCESS_RETRY_GET — Demander un autre code sur le même numéro — après le premier code, tant que la commande est ouverte. Gratuit. En attendant, getStatus répond STATUS_WAIT_RETRY.status=6 → ACCESS_ACTIVATION — Terminer la commande après le code. Aucun nouveau SMS n'arrivera sur le numéro.status=8 → ACCESS_CANCEL — Annuler une commande sans code (pas avant 2 minutes). L'argent revient sur votre solde.Réponses de getStatus :
STATUS_WAIT_CODE — Pas encore de code — redemandez dans 5 à 10 secondes.STATUS_OK:48213 — Le code est arrivé ; après les deux-points figure le code (ou le texte du SMS s'il n'en contient pas).STATUS_WAIT_RETRY:48213 — Un autre code a été demandé et n'est pas encore arrivé ; après les deux-points figure le code précédent.STATUS_CANCEL — Annulée ou close sans code ; l'argent est déjà revenu sur le solde.Les erreurs sont des chaînes de texte, comme le veut l'usage de ce protocole. Toutes, sauf RATE_LIMIT, arrivent avec le statut 200.
NO_KEY | api_key manquant. |
BAD_KEY | Clé erronée ou désactivée, ou compte bloqué. |
BAD_ACTION | Action inconnue. |
BAD_SERVICE | Ce code de service n'existe pas. |
BAD_COUNTRY | Ce code de pays n'existe pas. |
NO_NUMBERS | Pas de numéro pour cette paire pour l'instant ; rien n'est débité. |
NO_BALANCE | Moins de 20 $ de solde (seuil de l'API) ou moins que le prix. |
WRONG_MAX_PRICE | Le prix dépasse maxPrice ; le prix actuel suit les deux-points. |
LIMIT_ACTIVATIONS | Trop de commandes ouvertes — terminez-en ou annulez-en. |
RATE_LIMIT | Trop fréquent ; HTTP 429. Réessayez dans une seconde. |
BANNED | Le compte est bloqué — contactez le support. |
NO_ACTIVATION | Aucune commande avec ce numéro pour cette clé. |
BAD_STATUS | Cette action n'est pas disponible pour la commande en ce moment (p. ex. terminer sans code). |
EARLY_CANCEL_DENIED | L'annulation n'est possible que 2 minutes après l'achat. |
ERROR_SQL | Erreur temporaire de notre côté — répétez la requête dans une minute. |
Les codes sont ceux, standard, du protocole : tg — Telegram, wa — WhatsApp, etc. ; le pays 187 — les États-Unis. getServicesList et getCountries renvoient les listes complètes — prenez les codes là, pas dans d'anciens tableaux : services et pays évoluent avec le stock.
Les mêmes numéros et les mêmes règles que handler_api.php, en JSON : services par nom (telegram), pays par code ISO (US), statuts HTTP et codes d'erreur sur lesquels un programme peut s'appuyer. Utilisez-la pour du code neuf ; gardez handler_api.php pour les logiciels qui le parlent déjà.
https://relysms.pro/api/v1Envoyez la clé dans un en-tête : Authorization: Bearer <clé> (ou X-Api-Key: <clé>). Jamais dans l'URL — les URL finissent dans les logs. Les limites, le seuil de 20 $ et le catalogue sont ceux de handler_api.php.
Ajoutez l'en-tête Idempotency-Key avec une valeur à vous (un UUID, jusqu'à 255 caractères) sur POST /orders et /orders/batch. Si la connexion coupe et que vous renvoyez la requête avec la même clé, vous recevez la première réponse (avec l'en-tête Idempotent-Replayed: true) et rien n'est acheté deux fois. La même clé avec un autre corps est refusée ; une répétition arrivée pendant que la première tourne encore reçoit idempotency_in_progress. Les réponses réussies sont gardées 24 heures ; un achat échoué n'a rien débité et peut être relancé avec la même clé.
POST /orders/batch achète jusqu'à 20 numéros pour un service et un pays en une requête — c'est ainsi qu'on achète plus de 5 par seconde. Les achats se font un par un ; le premier qui échoue arrête le lot, et la réponse contient ce qui a été acheté et la raison dans stoppedBy. Si rien n'a été acheté, la réponse est cette erreur.
GET /orders renvoie d'abord les plus récentes. Quand next n'est pas null, passez-le dans before pour obtenir la page suivante.
Plutôt que d'interroger GET /orders/{id}, définissez une adresse HTTPS avec PUT /webhook : nous y envoyons un POST quand il arrive quelque chose à une commande passée par l'API. Le corps contient la commande telle qu'elle est au moment de l'envoi. Répondez par n'importe quel 2xx sous 10 secondes ; une commande peut produire plusieurs événements, et le même événement peut arriver deux fois après une nouvelle tentative : appuyez-vous sur l'id de livraison.
order.code_received — Un code est arrivé (chaque nouveau code le renvoie).order.finished — La commande est terminée — par vous, ou à la fin de son temps après un code.order.cancelled — Annulée sans code ; l'argent est revenu sur le solde.order.expired — Temps écoulé sans code ; l'argent est revenu sur le solde.ping — Un test depuis POST /webhook/test ; order vaut null.POST /relysms-hook HTTP/1.1
Content-Type: application/json
X-RelySMS-Event: order.code_received
X-RelySMS-Delivery: cm…
X-RelySMS-Signature: t=1793095272,v1=5f2b…
{
"id": "cm…",
"event": "order.code_received",
"createdAt": "2026-10-27T10:01:12.000Z",
"order": { "id": 1042, "status": "received", "codes": [{ "code": "48213", … }], … }
}Chaque requête porte X-RelySMS-Signature: t=<heure unix>,v1=<signature>. La signature est le HMAC-SHA256 de la chaîne « t.corps » (le corps brut, octet pour octet) avec le secret du webhook, en hexadécimal. Vérifiez-la, ainsi que t date de moins de 5 minutes, avant de faire confiance au corps.
Python
import hashlib, hmac, time
def verify(secret: str, body: bytes, header: str, tolerance=300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t, sig = parts.get("t", ""), parts.get("v1", "")
if not t.isdigit() or abs(time.time() - int(t)) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{t}.".encode() + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig)Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(secret, rawBody, header, tolerance = 300) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
const t = Number(parts.t);
if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > tolerance) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return expected.length === parts.v1?.length && timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}Si votre serveur ne répond pas 2xx, nous réessayons après 10 secondes, 1 minute, 5 minutes, 30 minutes, 2 heures et 6 heures — 7 tentatives en tout — puis abandonnons. GET /webhook/deliveries montre ce qui est parti et ce qui a échoué.
GET /balanceLe solde en dollars, et s'il suffit pour acheter par l'API.
curl -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/balanceRéponse
{ "balance": 25, "currency": "USD", "canBuy": true, "apiMinimum": 20 }GET /servicesTous les services en vente : notre id, le nom et le code handler_api.php.
| Paramètre | Obligatoire | Description |
|---|---|---|
lang query | non | Langue des noms : en (par défaut), ru, uk, zh, es, pt, id, vi, tr, ar, fr. |
curl -H "Authorization: Bearer $KEY" "https://relysms.pro/api/v1/services?lang=en"Réponse
{ "services": [{ "id": "telegram", "name": "Telegram", "protocolCode": "tg" }] }GET /countriesTous les pays en vente : code ISO, nom et code handler_api.php.
| Paramètre | Obligatoire | Description |
|---|---|---|
lang query | non | Langue des noms : en (par défaut), ru, uk, zh, es, pt, id, vi, tr, ar, fr. |
curl -H "Authorization: Bearer $KEY" "https://relysms.pro/api/v1/countries?lang=en"Réponse
{ "countries": [{ "id": "US", "name": "United States", "protocolCode": 187 }] }GET /pricesNos prix en dollars et le nombre approximatif de numéros. Sans paramètres : tout ce qui est en vente.
| Paramètre | Obligatoire | Description |
|---|---|---|
service query | non | Id du service tiré de /services, p. ex. telegram. |
country query | non | Code ISO du pays tiré de /countries, p. ex. US. |
curl -H "Authorization: Bearer $KEY" "https://relysms.pro/api/v1/prices?service=telegram"Réponse
{ "prices": [{ "service": "telegram", "country": "US", "price": 0.59, "stock": 1000 }] }Erreurs possibles: unknown_service, unknown_country
POST /ordersAcheter un numéro. Débité tout de suite ; remboursé si aucun code n'arrive.
| Paramètre | Obligatoire | Description |
|---|---|---|
service body | oui | Id du service tiré de /services, p. ex. telegram. |
country body | oui | Code ISO du pays tiré de /countries, p. ex. US. |
maxPrice body | non | Prix maximal en dollars, un nombre. Au-delà : price_above_max avec le prix actuel, rien n'est débité. |
curl -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: 7c1f0e2a-run-1" \
-d '{"service":"telegram","country":"US","maxPrice":0.8}' \
https://relysms.pro/api/v1/ordersRéponse
{
"order": {
"id": 1042,
"service": "telegram",
"country": "US",
"phone": "15550001111",
"price": 0.59,
"status": "waiting",
"refunded": false,
"codes": [],
"awaitingAnotherCode": false,
"createdAt": "2026-10-27T10:00:00.000Z",
"expiresAt": "2026-10-27T10:20:00.000Z",
"cancelableAt": "2026-10-27T10:02:00.000Z"
}
}Erreurs possibles: bad_request, unknown_service, unknown_country, no_numbers, insufficient_balance, below_api_minimum, price_above_max, too_many_open_orders, buying_too_fast, idempotency_key_reused, idempotency_in_progress
POST /orders/batchAcheter jusqu'à 20 numéros pour un service et un pays en une requête.
| Paramètre | Obligatoire | Description |
|---|---|---|
service body | oui | Id du service tiré de /services, p. ex. telegram. |
country body | oui | Code ISO du pays tiré de /countries, p. ex. US. |
quantity body | oui | Combien de numéros, de 1 à 20. |
maxPrice body | non | Prix maximal en dollars, un nombre. Au-delà : price_above_max avec le prix actuel, rien n'est débité. |
curl -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: 7c1f0e2a-batch-1" \
-d '{"service":"telegram","country":"US","quantity":5}' \
https://relysms.pro/api/v1/orders/batchRéponse
{
"orders": [{ "id": 1043, "phone": "15550001112", … }, { "id": 1044, … }],
"requested": 5,
"placed": 2,
"stoppedBy": { "code": "no_numbers", "message": "…" }
}Erreurs possibles: bad_request, unknown_service, unknown_country, no_numbers, insufficient_balance, below_api_minimum, price_above_max, too_many_open_orders, buying_too_fast, idempotency_key_reused, idempotency_in_progress
GET /ordersVos commandes, les plus récentes d'abord : les ouvertes par défaut, ou toutes.
| Paramètre | Obligatoire | Description |
|---|---|---|
status query | non | open (par défaut) — en attente ou avec code ; all — toutes les commandes. |
limit query | non | Commandes par page, de 1 à 100 (50 par défaut). |
before query | non | La valeur next de la page précédente. |
curl -H "Authorization: Bearer $KEY" "https://relysms.pro/api/v1/orders?status=all&limit=50"Réponse
{ "orders": [{ "id": 1042, … }], "next": "1001" }Erreurs possibles: bad_request
GET /orders/{id}Une commande avec ses codes. Interrogez-la toutes les 5 à 10 secondes tant que le statut est waiting.
| Paramètre | Obligatoire | Description |
|---|---|---|
id path | oui | L'id de la commande renvoyé à l'achat. |
curl -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/orders/1042Réponse
{
"order": {
"id": 1042,
"status": "received",
"codes": [{ "code": "48213", "text": "Telegram code: 48213", "receivedAt": "2026-10-27T10:01:12.000Z" }],
…
}
}Erreurs possibles: not_found
POST /orders/{id}/finishTerminer une commande qui a un code. Le numéro ne recevra plus de SMS. Recommencer est sans effet.
| Paramètre | Obligatoire | Description |
|---|---|---|
id path | oui | L'id de la commande renvoyé à l'achat. |
curl -X POST -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/orders/1042/finishRéponse
{ "order": { "id": 1042, "status": "finished", … } }Erreurs possibles: not_found, invalid_state
POST /orders/{id}/another-codeUn autre code sur le même numéro — après le premier code, tant que la commande est ouverte. Gratuit. En attendant, la commande a awaitingAnotherCode = true.
| Paramètre | Obligatoire | Description |
|---|---|---|
id path | oui | L'id de la commande renvoyé à l'achat. |
curl -X POST -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/orders/1042/another-codeRéponse
{ "order": { "id": 1042, "status": "received", "awaitingAnotherCode": true, … } }Erreurs possibles: not_found, invalid_state, try_later
POST /orders/{id}/cancelAnnuler une commande sans code, 2 minutes après l'achat. L'argent revient aussitôt.
| Paramètre | Obligatoire | Description |
|---|---|---|
id path | oui | L'id de la commande renvoyé à l'achat. |
curl -X POST -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/orders/1042/cancelRéponse
{ "order": { "id": 1042, "status": "cancelled", "refunded": true, … } }Erreurs possibles: not_found, invalid_state, too_early_to_cancel
GET /webhookL'adresse du webhook et son secret de signature, ou null.
curl -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/webhookRéponse
{ "webhook": { "url": "https://example.com/relysms-hook", "secret": "whsec_…", "createdAt": "2026-10-27T10:00:00.000Z" } }PUT /webhookDéfinir ou changer l'adresse. Le secret est créé une fois et conservé ; rotateSecret en crée un nouveau.
| Paramètre | Obligatoire | Description |
|---|---|---|
url body | oui | Adresse HTTPS de votre serveur. Les adresses privées et locales sont refusées. |
rotateSecret body | non | true — créer un nouveau secret de signature. |
curl -X PUT -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"url":"https://example.com/relysms-hook"}' \
https://relysms.pro/api/v1/webhookRéponse
{ "webhook": { "url": "https://example.com/relysms-hook", "secret": "whsec_…", "createdAt": "2026-10-27T10:00:00.000Z" } }Erreurs possibles: bad_request, invalid_webhook_url
DELETE /webhookSupprimer le webhook. Les événements pas encore envoyés sont abandonnés.
curl -X DELETE -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/webhookRéponse
{ "webhook": null }POST /webhook/testEnvoyer un événement ping pour vérifier l'adresse et la signature.
curl -X POST -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/webhook/testRéponse
{ "delivery": { "id": "cm…" } }Erreurs possibles: not_found
GET /webhook/deliveriesLes 20 dernières livraisons : événement, statut, tentatives, dernière réponse de votre serveur.
curl -H "Authorization: Bearer $KEY" https://relysms.pro/api/v1/webhook/deliveriesRéponse
{
"deliveries": [{
"id": "cm…", "event": "order.code_received", "orderId": 1042,
"status": "pending", "attempts": 2, "lastHttpStatus": 502, "lastError": "HTTP 502",
"createdAt": "2026-10-27T10:01:12.000Z", "deliveredAt": null, "nextAttemptAt": "2026-10-27T10:02:22.000Z"
}]
}Le champ status d'une commande :
waiting — Le numéro est à vous et aucun code n'est encore arrivé.received — Un code est arrivé ; il est dans codes. D'autres peuvent arriver tant que la commande est ouverte.finished — Vous avez terminé la commande (ou son temps s'est écoulé après un code).cancelled — Annulée sans code ; refunded vaut true et l'argent est sur le solde.expired — Le temps s'est écoulé sans code ; l'argent est revenu sur le solde.Une erreur, c'est un statut HTTP et un JSON avec code pour le programme et message pour les humains. Certaines portent des champs en plus (price, cancelableAt, apiMinimum).
{ "error": { "code": "price_above_max", "message": "The price is above maxPrice.", "price": 0.59 } }missing_key | 401 | Aucune clé dans Authorization ni dans X-Api-Key. |
invalid_key | 401 | La clé est fausse, a été remplacée, ou le compte est bloqué. |
bad_request | 400 | Le corps ou un paramètre est incorrect ; message précise lequel. |
unknown_service | 400 | Cet id de service n'existe pas. |
unknown_country | 400 | Ce code de pays n'existe pas. |
idempotency_key_invalid | 400 | Idempotency-Key est vide ou dépasse 255 caractères. |
invalid_webhook_url | 400 | L'adresse du webhook n'est pas en HTTPS, n'est pas une URL ou pointe vers un serveur privé ou local. |
insufficient_balance | 402 | Le solde est inférieur au prix. |
below_api_minimum | 402 | Moins de 20 $ de solde — l'API n'achète qu'à partir de 20 $. |
account_blocked | 403 | Le compte est bloqué — contactez le support. |
not_found | 404 | Aucune commande avec cet id pour cette clé. |
no_numbers | 409 | Pas de numéro pour cette paire pour l'instant ; rien n'est débité. |
price_above_max | 409 | Le prix dépasse maxPrice ; price contient le prix actuel. |
too_many_open_orders | 409 | Trop de commandes ouvertes — terminez-en ou annulez-en. |
invalid_state | 409 | Impossible dans ce statut (p. ex. terminer sans code). |
too_early_to_cancel | 409 | L'annulation est possible à partir de cancelableAt, 2 minutes après l'achat. |
idempotency_in_progress | 409 | Une requête avec cet Idempotency-Key est encore en cours ; réessayez dans un instant. |
idempotency_key_reused | 422 | Cet Idempotency-Key a déjà servi pour une autre requête. |
rate_limited | 429 | Plus de 20 requêtes par seconde ; Retry-After indique quand réessayer. |
buying_too_fast | 429 | Plus de 5 achats par seconde ; utilisez /orders/batch. |
try_later | 503 | Échec temporaire — réessayez dans une minute. |
Acheter un numéro, attendre le code, terminer la commande.
Python
import time, uuid, requests
BASE = "https://relysms.pro/api/v1"
S = requests.Session()
S.headers["Authorization"] = "Bearer rs_your_key"
r = S.post(f"{BASE}/orders",
json={"service": "telegram", "country": "US", "maxPrice": 0.8},
headers={"Idempotency-Key": str(uuid.uuid4())}, timeout=30)
if r.status_code != 201:
raise SystemExit(r.json()["error"]) # no_numbers, below_api_minimum, …
order = r.json()["order"]
print("number:", order["phone"])
while order["status"] == "waiting": # up to 20 minutes
time.sleep(10)
order = S.get(f"{BASE}/orders/{order['id']}", timeout=30).json()["order"]
if order["status"] == "received":
print("code:", order["codes"][-1]["code"])
S.post(f"{BASE}/orders/{order['id']}/finish", timeout=30)
# "expired" or "cancelled": the money is back on the balanceNode.js
const BASE = "https://relysms.pro/api/v1";
const headers = { Authorization: "Bearer rs_your_key", "Content-Type": "application/json" };
const res = await fetch(`${BASE}/orders`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({ service: "telegram", country: "US", maxPrice: 0.8 }),
});
if (res.status !== 201) throw new Error((await res.json()).error.code);
let { order } = await res.json();
console.log("number:", order.phone);
while (order.status === "waiting") {
await new Promise((r) => setTimeout(r, 10_000));
({ order } = await (await fetch(`${BASE}/orders/${order.id}`, { headers })).json());
}
if (order.status === "received") {
console.log("code:", order.codes.at(-1).code);
await fetch(`${BASE}/orders/${order.id}/finish`, { method: "POST", headers });
}Le cycle complet : acheter un numéro, attendre le code, terminer la commande.
curl
KEY=rs_your_key
BASE=https://relysms.pro/stubs/handler_api.php
curl "$BASE?api_key=$KEY&action=getBalance"
curl "$BASE?api_key=$KEY&action=getNumber&service=tg&country=187&maxPrice=0.80"
# → ACCESS_NUMBER:1042:15550001111
curl "$BASE?api_key=$KEY&action=getStatus&id=1042"
# → STATUS_WAIT_CODE … then STATUS_OK:48213
curl "$BASE?api_key=$KEY&action=setStatus&id=1042&status=6"Python
import time, requests
BASE = "https://relysms.pro/stubs/handler_api.php"
KEY = "rs_your_key"
def call(action, **params):
r = requests.get(BASE, params={"api_key": KEY, "action": action, **params}, timeout=30)
r.raise_for_status()
return r.text
answer = call("getNumber", service="tg", country="187", maxPrice="0.80")
if not answer.startswith("ACCESS_NUMBER"):
raise SystemExit(answer) # NO_NUMBERS, NO_BALANCE, …
_, order_id, phone = answer.split(":")
print("number:", phone)
for _ in range(120): # up to 20 minutes, every 10 s
status = call("getStatus", id=order_id)
if status.startswith("STATUS_OK:"):
print("code:", status.split(":", 1)[1])
call("setStatus", id=order_id, status=6)
break
if status == "STATUS_CANCEL":
break # refunded automatically
time.sleep(10)Node.js
const BASE = "https://relysms.pro/stubs/handler_api.php";
const KEY = "rs_your_key";
async function call(action, params = {}) {
const url = new URL(BASE);
url.search = new URLSearchParams({ api_key: KEY, action, ...params });
const res = await fetch(url);
return res.text();
}
const answer = await call("getNumber", { service: "tg", country: "187", maxPrice: "0.80" });
if (!answer.startsWith("ACCESS_NUMBER")) throw new Error(answer);
const [, id, phone] = answer.split(":");
console.log("number:", phone);
for (let i = 0; i < 120; i++) {
const status = await call("getStatus", { id });
if (status.startsWith("STATUS_OK:")) {
console.log("code:", status.slice("STATUS_OK:".length));
await call("setStatus", { id, status: "6" });
break;
}
if (status === "STATUS_CANCEL") break; // refunded automatically
await new Promise((r) => setTimeout(r, 10_000));
}L'adresse du serveur en https://relysms.pro/stubs/handler_api.php et la clé par celle de votre compte. Les codes des services et des pays restent les mêmes.
Les achats par l'API exigent un solde de 20 $ ou plus. Le compte et la Mini App n'ont pas ce seuil.
Il revient tout seul sur votre solde à la fin de la fenêtre, ou aussitôt si vous annulez après 2 minutes.
Oui, tant que la fenêtre est ouverte : setStatus=3, puis à nouveau getStatus.
Non : tous les achats sont réels. Commencez par une paire bon marché et testez votre flux sur un numéro.
Compte → Solde → API → En émettre une nouvelle. L'ancienne cesse de fonctionner aussitôt.
La documentation complète en un seul texte pour ChatGPT, Claude et d'autres modèles se trouve sur /fr/developers.md, et une carte courte sur /llms.txt. Donnez le lien au modèle et demandez-lui de connecter RelySMS à votre code.
Lis https://relysms.pro/fr/developers.md et connecte RelySMS à mon script.