Documentación de la API
API REST v1 y endpoints compatibles con SMS-Activate
Introducción
La API te permite comprar números virtuales con el saldo de tu cuenta, leer los códigos SMS entrantes y cancelar para obtener un reembolso. Todas las solicitudes usan HTTPS; las respuestas son JSON.
- URL base
https://codesms.org- Formato
- JSON (
application/json) — también se acepta form-encoded - Moneda
- TRY (₺)
- Respuesta exitosa
{"success": true, "data": ...}- Respuesta de error
{"success": false, "error": {"code": "NO_BALANCE", "message": "..."}}
Autenticación
Envía tu clave de API en cada solicitud. Puedes obtenerla en la página API de tu panel.
curl "https://codesms.org/api/v1/balance" \
-H "X-API-Key: YOUR_API_KEY"$ch = curl_init('https://codesms.org/api/v1/balance');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY']]);requests.get("https://codesms.org/api/v1/balance", headers={"X-API-Key": "YOUR_API_KEY"})fetch("https://codesms.org/api/v1/balance", { headers: { "X-API-Key": "YOUR_API_KEY" } })Alternativas: el encabezado Authorization: Bearer YOUR_API_KEY o el parámetro de consulta ?api_key=YOUR_API_KEY (solo para pruebas; la clave podría quedar registrada en los logs).
- La API no funciona en cuentas con correo electrónico no verificado (EMAIL_NOT_VERIFIED).
- Puedes definir una lista de IP permitidas en el panel; si la lista está configurada, solo se aceptan solicitudes desde esas direcciones.
- Si tu clave se filtra, regénerala en el panel de inmediato; la clave anterior deja de ser válida al instante.
Inicio rápido
Compra un número → espera el código → finaliza. Si no llega ningún código, cancela para obtener un reembolso.
<?php
$base = 'https://codesms.org';
$key = 'YOUR_API_KEY';
function api($method, $path, $body = null) {
global $base, $key;
$ch = curl_init($base . $path);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => ['X-API-Key: ' . $key, 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => $body ? json_encode($body) : null]);
return json_decode(curl_exec($ch), true);
}
$r = api('POST', '/api/v1/activations', ['service' => 'tg', 'country' => 'tr']);
if (!$r['success']) { exit('Hata: ' . $r['error']['code']); }
$id = $r['data']['id'];
echo "Numara: {$r['data']['phone']}\n";
for ($i = 0; $i < 120; $i++) { // en fazla ~6 dk
sleep(3);
$s = api('GET', "/api/v1/activations/$id")['data'];
if ($s['status'] === 'received') { echo "Kod: {$s['code']}\n"; api('POST', "/api/v1/activations/$id/finish"); exit; }
if (in_array($s['status'], ['canceled', 'expired', 'failed'])) exit("Bitti: {$s['status']}\n");
}
api('POST', "/api/v1/activations/$id/cancel"); // kod gelmedi: iptal et, ücret iadeimport time, requests
BASE = "https://codesms.org"
HEAD = {"X-API-Key": "YOUR_API_KEY"}
r = requests.post(f"{BASE}/api/v1/activations", headers=HEAD, json={"service": "tg", "country": "tr"}).json()
if not r["success"]:
raise SystemExit(f"Hata: {r['error']['code']}")
act = r["data"]
print("Numara:", act["phone"])
for _ in range(120): # en fazla ~6 dk
time.sleep(3)
s = requests.get(f"{BASE}/api/v1/activations/{act['id']}", headers=HEAD).json()["data"]
if s["status"] == "received":
print("Kod:", s["code"])
requests.post(f"{BASE}/api/v1/activations/{act['id']}/finish", headers=HEAD)
break
if s["status"] in ("canceled", "expired", "failed"):
break
else:
requests.post(f"{BASE}/api/v1/activations/{act['id']}/cancel", headers=HEAD) # ücret iadeconst BASE = "https://codesms.org";
const HEAD = { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" };
const api = (method, path, body) => fetch(BASE + path, { method, headers: HEAD, body: body && JSON.stringify(body) }).then(r => r.json());
const r = await api("POST", "/api/v1/activations", { service: "tg", country: "tr" });
if (!r.success) throw new Error(r.error.code);
const { id, phone } = r.data;
console.log("Numara:", phone);
for (let i = 0; i < 120; i++) { // en fazla ~6 dk
await new Promise(res => setTimeout(res, 3000));
const s = (await api("GET", `/api/v1/activations/${id}`)).data;
if (s.status === "received") { console.log("Kod:", s.code); await api("POST", `/api/v1/activations/${id}/finish`); process.exit(0); }
if (["canceled", "expired", "failed"].includes(s.status)) process.exit(1);
}
await api("POST", `/api/v1/activations/${id}/cancel`); // ücret iadeCiclo de vida de la activación
| status | Significado | Acciones posibles |
|---|---|---|
waiting | Número asignado, esperando SMS. | Consultar, cancelar (si can_cancel=true). |
received | Llegó el SMS; está en el campo code. | Usa el código y finaliza; solicita otro SMS si can_retry=true. |
completed | Completado (código usado). | — |
canceled | Cancelado, reembolsado. | — |
expired | Tiempo agotado, sin SMS; reembolsado. | — |
failed | No se pudo obtener un número; reembolsado. | — |
La disponibilidad de los botones Cancelar, Reenviar SMS y Finalizar depende del número y del servicio: consulte los campos can_cancel, can_retry y can_finish de la respuesta. Si cancel_in > 0, debe esperar esa cantidad de segundos para cancelar.
Obtener saldo
Devuelve el saldo actual de tu cuenta.
curl "https://codesms.org/api/v1/balance" \
-H "X-API-Key: YOUR_API_KEY"$ch = curl_init('https://codesms.org/api/v1/balance');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.get(
"https://codesms.org/api/v1/balance",
headers={"X-API-Key": "YOUR_API_KEY"}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/balance", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY"
}
});
console.log(await response.json());package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://codesms.org/api/v1/balance", nil)
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.GetAsync("https://codesms.org/api/v1/balance");
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/balance"))
.header("X-API-Key", "YOUR_API_KEY")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/balance")
req = Net::HTTP::Get.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": {
"balance": 125.5,
"currency": "TRY"
}
}Listar servicios
Stokta numarası bulunan servisler, en düşük fiyat ve toplam stokla.
curl "https://codesms.org/api/v1/services" \
-H "X-API-Key: YOUR_API_KEY"$ch = curl_init('https://codesms.org/api/v1/services');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.get(
"https://codesms.org/api/v1/services",
headers={"X-API-Key": "YOUR_API_KEY"}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/services", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY"
}
});
console.log(await response.json());package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://codesms.org/api/v1/services", nil)
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.GetAsync("https://codesms.org/api/v1/services");
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/services"))
.header("X-API-Key", "YOUR_API_KEY")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/services")
req = Net::HTTP::Get.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": [
{
"code": "tg",
"slug": "telegram",
"name": "Telegram",
"min_price": 2.1,
"stock": 18540
}
]
}Listar países
Países con números disponibles. "id" es el código numérico de país compatible con SMS-Activate.
curl "https://codesms.org/api/v1/countries" \
-H "X-API-Key: YOUR_API_KEY"$ch = curl_init('https://codesms.org/api/v1/countries');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.get(
"https://codesms.org/api/v1/countries",
headers={"X-API-Key": "YOUR_API_KEY"}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/countries", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY"
}
});
console.log(await response.json());package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://codesms.org/api/v1/countries", nil)
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.GetAsync("https://codesms.org/api/v1/countries");
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/countries"))
.header("X-API-Key", "YOUR_API_KEY")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/countries")
req = Net::HTTP::Get.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": [
{
"iso": "tr",
"id": 62,
"name": "Turkey",
"name_tr": "Türkiye",
"dial": "90"
}
]
}Precio y stock
Precio y stock actuales por servicio/país. Una llamada sin filtros devuelve la lista completa (hasta 20.000 filas).
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| service | string | opcional | Código o slug del servicio (p. ej., tg). |
| country | string | opcional | Código ISO del país (tr) o ID numérico (62). |
| servers | integer | opcional | If set to 1 (service and country must both be given), the price, stock and success rate of each "Server N" are also returned in the "servers" array. Pass that number as the server parameter when buying. |
curl "https://codesms.org/api/v1/prices?service=tg&country=tr&servers=1" \
-H "X-API-Key: YOUR_API_KEY"$ch = curl_init('https://codesms.org/api/v1/prices?service=tg&country=tr&servers=1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.get(
"https://codesms.org/api/v1/prices?service=tg&country=tr&servers=1",
headers={"X-API-Key": "YOUR_API_KEY"}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/prices?service=tg&country=tr&servers=1", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY"
}
});
console.log(await response.json());package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://codesms.org/api/v1/prices?service=tg&country=tr&servers=1", nil)
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.GetAsync("https://codesms.org/api/v1/prices?service=tg&country=tr&servers=1");
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/prices?service=tg&country=tr&servers=1"))
.header("X-API-Key", "YOUR_API_KEY")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/prices?service=tg&country=tr&servers=1")
req = Net::HTTP::Get.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": [
{
"service": "tg",
"country": "tr",
"price": 8.5,
"currency": "TRY",
"stock": 420,
"success_rate": 87,
"servers": [
{
"server": 3,
"price": 8.5,
"stock": 300,
"success_rate": 91
},
{
"server": 7,
"price": 9.2,
"stock": 120,
"success_rate": null
}
]
}
]
}Comprar un número
Abre una nueva activación (número) y la descuenta de tu saldo. Devuelve NO_BALANCE si el saldo es insuficiente y NO_NUMBERS si no hay stock. Si no llega ningún SMS o cancelas, el importe se reembolsa automáticamente. Recomendado: envía un encabezado Idempotency-Key único en cada compra; si reintentas con la misma clave tras un error de red, no se compra un segundo número y se devuelve la primera activación (válido por 24 horas).
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| service | string | obligatorio | Código o slug del servicio (p. ej., tg). |
| country | string | obligatorio | Código ISO del país (tr) o ID numérico (62). |
| max_price | number | opcional | El precio máximo (TRY) que aceptas. Si se omite, se aplica el precio más bajo publicado; si el precio lo supera, se devuelve PRICE_CHANGED. |
| server | integer | opcional | Buy only from this "Server N" (GET /api/v1/prices?servers=1). When given, no other server is tried; NO_NUMBERS is returned if it has none, PRICE_CHANGED if its price exceeds max_price. If omitted, all servers are tried in price order. |
curl -X POST "https://codesms.org/api/v1/activations" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service":"tg","country":"tr"}'$ch = curl_init('https://codesms.org/api/v1/activations');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['service' => 'tg', 'country' => 'tr']),
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.post(
"https://codesms.org/api/v1/activations",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"service": "tg", "country": "tr"}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/activations", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({"service":"tg","country":"tr"})
});
console.log(await response.json());package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://codesms.org/api/v1/activations", bytes.NewBufferString(`{"service":"tg","country":"tr"}`))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.PostAsync("https://codesms.org/api/v1/activations", new StringContent("{\"service\":\"tg\",\"country\":\"tr\"}", System.Text.Encoding.UTF8, "application/json"));
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/activations"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{\"service\":\"tg\",\"country\":\"tr\"}"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/activations")
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
req['Content-Type'] = 'application/json'
req.body = '{"service":"tg","country":"tr"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": {
"id": 1234,
"status": "waiting",
"phone": "+905551234567",
"code": null,
"text": null,
"service": {
"code": "tg",
"name": "Telegram"
},
"country": {
"iso": "tr",
"name": "Turkey",
"dial": "90"
},
"server": 3,
"price": 8.5,
"currency": "TRY",
"created_at": "2026-01-15T10:00:00+03:00",
"expires_at": "2026-01-15T10:20:00+03:00",
"retry_count": 0,
"can_cancel": true,
"can_retry": false,
"can_finish": false,
"cancel_in": 0
}
}Estado de la activación / código SMS
Devuelve el estado de la activación y el código SMS si ya llegó. Consulta cada 3–5 segundos hasta que llegue el código (no es necesario si usas webhooks).
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| id | integer | obligatorio | ID de la activación (parámetro de ruta). |
curl "https://codesms.org/api/v1/activations/1234" \
-H "X-API-Key: YOUR_API_KEY"$ch = curl_init('https://codesms.org/api/v1/activations/1234');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.get(
"https://codesms.org/api/v1/activations/1234",
headers={"X-API-Key": "YOUR_API_KEY"}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/activations/1234", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY"
}
});
console.log(await response.json());package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://codesms.org/api/v1/activations/1234", nil)
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.GetAsync("https://codesms.org/api/v1/activations/1234");
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/activations/1234"))
.header("X-API-Key", "YOUR_API_KEY")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/activations/1234")
req = Net::HTTP::Get.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": {
"status": "received",
"code": "482913",
"text": "Your Telegram code: 482913",
"can_cancel": false,
"can_retry": true,
"can_finish": true,
"id": 1234,
"phone": "+905551234567",
"service": {
"code": "tg",
"name": "Telegram"
},
"country": {
"iso": "tr",
"name": "Turkey",
"dial": "90"
},
"server": 3,
"price": 8.5,
"currency": "TRY",
"created_at": "2026-01-15T10:00:00+03:00",
"expires_at": "2026-01-15T10:20:00+03:00",
"retry_count": 0,
"cancel_in": 0
}
}Listar activaciones
Tus últimas activaciones (las más recientes primero).
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| status | string | opcional | waiting, received, completed, canceled, expired, failed |
| limit | integer | opcional | 1–100 (predeterminado: 30). |
curl "https://codesms.org/api/v1/activations?status=waiting&limit=20" \
-H "X-API-Key: YOUR_API_KEY"$ch = curl_init('https://codesms.org/api/v1/activations?status=waiting&limit=20');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.get(
"https://codesms.org/api/v1/activations?status=waiting&limit=20",
headers={"X-API-Key": "YOUR_API_KEY"}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/activations?status=waiting&limit=20", {
method: "GET",
headers: {
"X-API-Key": "YOUR_API_KEY"
}
});
console.log(await response.json());package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://codesms.org/api/v1/activations?status=waiting&limit=20", nil)
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.GetAsync("https://codesms.org/api/v1/activations?status=waiting&limit=20");
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/activations?status=waiting&limit=20"))
.header("X-API-Key", "YOUR_API_KEY")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/activations?status=waiting&limit=20")
req = Net::HTTP::Get.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": [
{
"id": 1234,
"status": "waiting",
"phone": "+905551234567",
"code": null,
"text": null,
"service": {
"code": "tg",
"name": "Telegram"
},
"country": {
"iso": "tr",
"name": "Turkey",
"dial": "90"
},
"server": 3,
"price": 8.5,
"currency": "TRY",
"created_at": "2026-01-15T10:00:00+03:00",
"expires_at": "2026-01-15T10:20:00+03:00",
"retry_count": 0,
"can_cancel": true,
"can_retry": false,
"can_finish": false,
"cancel_in": 0
}
]
}Cancelar y obtener reembolso
Si no llegó ningún código, cancela la activación y reembolsa el importe a tu saldo. Algunos proveedores no permiten cancelar en los primeros segundos (se devuelve CANCEL_TOO_EARLY mientras cancel_in > 0). Si el proveedor no lo admite, can_cancel=false.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| id | integer | obligatorio | ID de la activación (parámetro de ruta). |
curl -X POST "https://codesms.org/api/v1/activations/1234/cancel" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'$ch = curl_init('https://codesms.org/api/v1/activations/1234/cancel');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([]),
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.post(
"https://codesms.org/api/v1/activations/1234/cancel",
headers={"X-API-Key": "YOUR_API_KEY"},
json={}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/activations/1234/cancel", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({})
});
console.log(await response.json());package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://codesms.org/api/v1/activations/1234/cancel", bytes.NewBufferString(`{}`))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.PostAsync("https://codesms.org/api/v1/activations/1234/cancel", new StringContent("{}", System.Text.Encoding.UTF8, "application/json"));
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/activations/1234/cancel"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{}"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/activations/1234/cancel")
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
req['Content-Type'] = 'application/json'
req.body = '{}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": {
"status": "canceled",
"can_cancel": false,
"id": 1234,
"phone": "+905551234567",
"code": null,
"text": null,
"service": {
"code": "tg",
"name": "Telegram"
},
"country": {
"iso": "tr",
"name": "Turkey",
"dial": "90"
},
"server": 3,
"price": 8.5,
"currency": "TRY",
"created_at": "2026-01-15T10:00:00+03:00",
"expires_at": "2026-01-15T10:20:00+03:00",
"retry_count": 0,
"can_retry": false,
"can_finish": false,
"cancel_in": 0
}
}Solicitar otro SMS
Solicita un nuevo SMS al mismo número después de recibir un código (solo cuando can_retry=true). La activación vuelve a "waiting".
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| id | integer | obligatorio | ID de la activación (parámetro de ruta). |
curl -X POST "https://codesms.org/api/v1/activations/1234/retry" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'$ch = curl_init('https://codesms.org/api/v1/activations/1234/retry');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([]),
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.post(
"https://codesms.org/api/v1/activations/1234/retry",
headers={"X-API-Key": "YOUR_API_KEY"},
json={}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/activations/1234/retry", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({})
});
console.log(await response.json());package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://codesms.org/api/v1/activations/1234/retry", bytes.NewBufferString(`{}`))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.PostAsync("https://codesms.org/api/v1/activations/1234/retry", new StringContent("{}", System.Text.Encoding.UTF8, "application/json"));
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/activations/1234/retry"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{}"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/activations/1234/retry")
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
req['Content-Type'] = 'application/json'
req.body = '{}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": {
"retry_count": 1,
"id": 1234,
"status": "waiting",
"phone": "+905551234567",
"code": null,
"text": null,
"service": {
"code": "tg",
"name": "Telegram"
},
"country": {
"iso": "tr",
"name": "Turkey",
"dial": "90"
},
"server": 3,
"price": 8.5,
"currency": "TRY",
"created_at": "2026-01-15T10:00:00+03:00",
"expires_at": "2026-01-15T10:20:00+03:00",
"can_cancel": true,
"can_retry": false,
"can_finish": false,
"cancel_in": 0
}
}Finalizar
Indica que usaste el código correctamente y cierra la activación. Las activaciones no finalizadas en 15 minutos se finalizan automáticamente.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| id | integer | obligatorio | ID de la activación (parámetro de ruta). |
curl -X POST "https://codesms.org/api/v1/activations/1234/finish" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'$ch = curl_init('https://codesms.org/api/v1/activations/1234/finish');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([]),
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.post(
"https://codesms.org/api/v1/activations/1234/finish",
headers={"X-API-Key": "YOUR_API_KEY"},
json={}
)
print(response.json())const response = await fetch("https://codesms.org/api/v1/activations/1234/finish", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({})
});
console.log(await response.json());package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://codesms.org/api/v1/activations/1234/finish", bytes.NewBufferString(`{}`))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var response = await client.PostAsync("https://codesms.org/api/v1/activations/1234/finish", new StringContent("{}", System.Text.Encoding.UTF8, "application/json"));
Console.WriteLine(await response.Content.ReadAsStringAsync());HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://codesms.org/api/v1/activations/1234/finish"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{}"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());require 'net/http'
require 'json'
uri = URI("https://codesms.org/api/v1/activations/1234/finish")
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = 'YOUR_API_KEY'
req['Content-Type'] = 'application/json'
req.body = '{}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
puts res.body{
"success": true,
"data": {
"status": "completed",
"code": "482913",
"text": "Your Telegram code: 482913",
"can_cancel": false,
"can_retry": true,
"can_finish": true,
"id": 1234,
"phone": "+905551234567",
"service": {
"code": "tg",
"name": "Telegram"
},
"country": {
"iso": "tr",
"name": "Turkey",
"dial": "90"
},
"server": 3,
"price": 8.5,
"currency": "TRY",
"created_at": "2026-01-15T10:00:00+03:00",
"expires_at": "2026-01-15T10:20:00+03:00",
"retry_count": 0,
"cancel_in": 0
}
}Webhook
Si configuras una URL de webhook en el panel, te enviamos una solicitud POST firmada cuando llega el código SMS; no necesitas consultar constantemente. Ante respuestas que no sean 2xx, se reintenta después de 1 min, 5 min, 15 min, 1 h y 6 h.
- X-SMSOnay-Event
activation.code- X-SMSOnay-Timestamp
- Segundos Unix
- X-SMSOnay-Signature
sha256=HMAC_SHA256(secret, timestamp + "." + body)
{
"event": "activation.code",
"activation": {
"id": 1234,
"status": "received",
"phone": "+905551234567",
"code": "482913",
"service": {
"code": "tg"
},
"...": "..."
},
"timestamp": 1768460000
}# HMAC-SHA256(secret, timestamp + "." + rawBody) -> "sha256=" + hex
# Header'lar: X-SMSOnay-Timestamp, X-SMSOnay-Signature$ts = $_SERVER['HTTP_X_SMSONAY_TIMESTAMP'];
$sig = $_SERVER['HTTP_X_SMSONAY_SIGNATURE'];
$body = file_get_contents('php://input');
$calc = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, 'whsec_YOUR_SECRET');
if (!hash_equals($calc, $sig) || abs(time() - (int)$ts) > 300) { http_response_code(401); exit; }
$event = json_decode($body, true);import hmac, hashlib, time
def verify(ts, signature, body: bytes, secret: str) -> bool:
calc = 'sha256=' + hmac.new(secret.encode(), ts.encode() + b'.' + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(calc, signature) and abs(time.time() - int(ts)) < 300const crypto = require('crypto');
function verify(ts, signature, rawBody, secret) {
const calc = 'sha256=' + crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(calc), Buffer.from(signature)) && Math.abs(Date.now() / 1000 - Number(ts)) < 300;
}func verify(ts, signature string, body []byte, secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(ts + "."))
mac.Write(body)
calc := "sha256=" + hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(calc), []byte(signature))
}static bool Verify(string ts, string signature, string body, string secret)
{
using var h = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var calc = "sha256=" + Convert.ToHexString(h.ComputeHash(Encoding.UTF8.GetBytes(ts + "." + body))).ToLower();
return CryptographicOperations.FixedTimeEquals(Encoding.UTF8.GetBytes(calc), Encoding.UTF8.GetBytes(signature));
}static boolean verify(String ts, String signature, String body, String secret) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
String calc = "sha256=" + HexFormat.of().formatHex(mac.doFinal((ts + "." + body).getBytes(StandardCharsets.UTF_8)));
return MessageDigest.isEqual(calc.getBytes(), signature.getBytes());
}require 'openssl'
def verify(ts, signature, body, secret)
calc = 'sha256=' + OpenSSL::HMAC.hexdigest('SHA256', secret, "#{ts}.#{body}")
Rack::Utils.secure_compare(calc, signature)
endPuedes obtener tu secreto de firma en la página API del panel. Verifica la marca de tiempo (±5 min) y la firma; descarta las entregas repetidas de la misma activación usando el id.
API compatible con SMS-Activate
Si tu software de registro/automatización actual es compatible con el protocolo SMS-Activate (handler_api), puedes conectarte con nosotros simplemente cambiando la dirección del servidor y la clave API.
- service: código del servicio (tg, wa, ig, go, fb …) — el código de GET /api/v1/services.
- country: ID de país de SMS-Activate (p. ej., 62 = Turquía, 0 = Rusia, 187 = EE. UU.) — el id de GET /api/v1/countries.
- Los precios están en liras turcas; maxPrice también se interpreta en TRY.
- operator: solo un valor numérico se interpreta como el número de «Server N» (GET /api/v1/prices?servers=1); si se omite, se prueban todos los Servers por orden de precio.
| action | Parámetros | Ejemplo de respuesta |
|---|---|---|
| getBalance | — | ACCESS_BALANCE:125.50 |
| getNumber | service, country (ID), [maxPrice], [operator = Server no] | ACCESS_NUMBER:1234:905551234567 |
| getNumberV2 | service, country (ID), [maxPrice], [operator = Server no] | {"activationId":"1234","phoneNumber":"905551234567","activationCost":8.5,"countryCode":"62","canGetAnotherSms":true,...} |
| getStatus | id | STATUS_WAIT_CODE | STATUS_OK:482913 | STATUS_WAIT_RETRY:482913 | STATUS_CANCEL |
| getStatusV2 | id | {"verificationType":0,"sms":{"dateTime":"...","code":"482913","text":"..."},"call":null} |
| setStatus | id, status (3=tekrar SMS, 6=tamamla, 8=iptal) | ACCESS_RETRY_GET | ACCESS_ACTIVATION | ACCESS_CANCEL | EARLY_CANCEL_DENIED |
| getPrices | [service], [country] | {"62":{"tg":{"cost":8.5,"count":420}}} |
| getNumbersStatus | country | {"tg_0":420,"wa_0":310} |
| getCountries | — | {"62":{"id":62,"eng":"Turkey",...}} |
| getServicesList | — | {"status":"success","services":[{"code":"tg","name":"Telegram"}]} |
| getActiveActivations | — | {"status":"success","activeActivations":[...]} |
curl "https://codesms.org/stubs/handler_api.php?api_key=YOUR_API_KEY&action=getNumber&service=tg&country=62" \
-H "X-API-Key: unused"$ch = curl_init('https://codesms.org/stubs/handler_api.php?api_key=YOUR_API_KEY&action=getNumber&service=tg&country=62');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: unused'],
]);
$response = json_decode(curl_exec($ch), true);
print_r($response);import requests
response = requests.get(
"https://codesms.org/stubs/handler_api.php?api_key=YOUR_API_KEY&action=getNumber&service=tg&country=62",
headers={"X-API-Key": "unused"}
)
print(response.json())const response = await fetch("https://codesms.org/stubs/handler_api.php?api_key=YOUR_API_KEY&action=getNumber&service=tg&country=62", {
method: "GET",
headers: {
"X-API-Key": "unused"
}
});
console.log(await response.json());Las respuestas de error son texto plano: BAD_KEY, BAD_ACTION, BAD_SERVICE, NO_NUMBERS, NO_BALANCE, NO_ACTIVATION, EARLY_CANCEL_DENIED, WRONG_MAX_PRICE:price, ACCOUNT_INACTIVE…
Solicitudes firmadas (opcional)
Si Panel → API → "Solicitud firmada obligatoria" está activado, se deben agregar los siguientes encabezados a cada solicitud REST; aunque roben tu clave, no se pueden hacer solicitudes sin el secreto de firma, y la misma solicitud no se puede repetir. El endpoint compatible con SMS-Activate no admite firmas, por lo que no se puede usar mientras esta opción esté activada.
X-Timestamp: Hora Unix (segundos); puede diferir de la hora del servidor en 5 minutos como máximo.X-Nonce: Un valor aleatorio nuevo para cada solicitud, de 16 a 64 caracteres (A-Z a-z 0-9 _ -).X-Signature:hex(HMAC-SHA256(imza_sırrı, X-Timestamp + "\n" + X-Nonce + "\n" + METHOD + "\n" + yol?sorgu + "\n" + hex(SHA256(gövde))))
$ts = (string)time(); $nonce = bin2hex(random_bytes(16)); $body = json_encode(['service' => 'tg', 'country' => 'tr']);
$sig = hash_hmac('sha256', "$ts\n$nonce\nPOST\n/api/v1/activations\n" . hash('sha256', $body), $signSecret);
// Başlıklar: X-API-Key, X-Timestamp: $ts, X-Nonce: $nonce, X-Signature: $sig, Content-Type: application/jsonCódigos de error
| code | HTTP | Descripción |
|---|---|---|
| BAD_KEY | 401 | La clave API falta o no es válida. |
| API_DISABLED | 403 | El acceso a la API está desactivado en tu cuenta. |
| EMAIL_NOT_VERIFIED | 403 | Tu dirección de correo electrónico no está verificada. |
| IP_NOT_ALLOWED | 403 | La dirección IP de la solicitud no está en la lista de permitidas. |
| ACCOUNT_BANNED | 403 | La cuenta está suspendida. |
| RATE_LIMIT | 429 | Se superó el límite de solicitudes por minuto. |
| BAD_SERVICE | 400 | El código de servicio no es válido o falta. |
| BAD_COUNTRY | 400 | El código de país no es válido o falta. |
| NO_BALANCE | 402 | Saldo insuficiente. (No hay un saldo mínimo requerido; este error se devuelve cuando tu saldo es menor que el precio). |
| NO_NUMBERS | 409 | No hay números para este servicio/país en este momento (sin cargo / reembolsado). |
| BAD_MAX_PRICE | 400 | max_price debe ser un número positivo. |
| BAD_SERVER | 400 | server must be a positive integer (the Server number). |
| PRICE_CHANGED | 409 | No quedan números al precio que aceptaste; no se te cobró. error.price en la respuesta es el precio actual; si lo aceptas, repite la misma solicitud con max_price. |
| TOO_MANY_ACTIVE | 429 | Se superó el número permitido de activaciones activas simultáneas. |
| NOT_FOUND | 404 | Activación no encontrada. |
| BAD_STATUS | 409 | Esta acción no es posible en el estado actual de la activación. |
| CANCEL_TOO_EARLY | 409 | El proveedor no permite cancelar en esta etapa; vuelve a intentarlo después de cancel_in segundos. |
| ALREADY_RECEIVED | 409 | No se puede cancelar porque el código ya llegó. |
| UNSUPPORTED | 409 | El proveedor no admite esta acción (p. ej., otro SMS). |
| PROVIDER_ERROR | 502 | El proveedor tuvo un error temporal; inténtalo de nuevo. |
| PLAN_REQUIRED | 403 | API erişimi için etkin bir API paketi gerekiyor (Panel → API). |
| BAD_SIGNATURE | 401 | İmzalı istek zorunlu ve imza eksik/geçersiz ya da zaman damgası 5 dakikadan eski. |
| BAD_IDEMPOTENCY_KEY | 400 | El encabezado Idempotency-Key debe tener entre 8 y 64 caracteres (letras, dígitos, _ - : .). |
| IDEMPOTENCY_IN_PROGRESS | 409 | Una solicitud anterior con el mismo Idempotency-Key aún se está procesando; reintenta en unos segundos. |
| REPLAYED_REQUEST | 401 | Aynı X-Nonce ikinci kez kullanıldı (tekrar oynatma koruması). |
| SERVER_ERROR | 500 | Error inesperado del servidor. |
Límites y recomendaciones
- Límite de solicitudes: 120 por minuto (por cuenta).
- Consulta el estado cada 3–5 segundos; usar webhooks es más eficiente.
- Las activaciones que no reciben SMS se cancelan y reembolsan automáticamente al agotarse el tiempo; también puedes cancelarlas antes.
- La cantidad de activaciones abiertas simultáneamente es limitada (TOO_MANY_ACTIVE).
- Si se agota el tiempo de red, reenvía la solicitud de compra con el mismo encabezado Idempotency-Key; no se comprará un segundo número. Si no usas el encabezado, revisa primero tus activaciones recientes con GET /api/v1/activations.
- El precio puede cambiar según la disponibilidad: si no quedan números al precio publicado, no se te cobra y se informa el precio actual con PRICE_CHANGED (WRONG_MAX_PRICE:price en el endpoint compatible con SMS-Activate). Si lo aceptas, repite la solicitud con max_price (maxPrice).
- El campo success_rate de la lista de precios es el porcentaje de ventas de los últimos 30 días para ese servicio y país en las que llegó un código SMS; es null cuando la muestra es demasiado pequeña.