API de verificación SMS para desarrolladores
La API de RecibeSMS te permite comprar números temporales, leer códigos OTP y cancelar números sin usar desde tu propio código. Tiene dos variantes que comparten saldo y la misma regla de cobro, solo pagas si llega el código: una API REST en JSON bajo /api/v1 y un endpoint compatible con SMS-Activate para bots y herramientas que ya tienes.
Respuesta rápida
¿RecibeSMS tiene una API para recibir SMS?
Sí. RecibeSMS ofrece una API REST en https://recibesms.com/api/v1 y un endpoint compatible con SMS-Activate en /api/stubs/handler_api.php. Ambas usan una clave de API, disponible tras tu primera recarga. Comprar un número congela su precio; solo se cobra cuando llega el SMS, y los números cancelados o caducados se devuelven automáticamente.
| URL base REST | https://recibesms.com/api/v1 |
|---|---|
| Endpoint compatible con SMS-Activate | https://recibesms.com/api/stubs/handler_api.php (GET o POST) |
| Autenticación | Cabecera X-Api-Key, Authorization: Bearer o parámetro api_key en la URL |
| Acceso a la API | Clave disponible tras tu primera recarga; una clave activa por cuenta |
| Cobro | Precio congelado al comprar, cobrado solo cuando llega el SMS y devuelto en caso contrario |
| Número reservado | hasta 20 minutos |
| Límite de compras | 500 compras por minuto por cuenta (y por IP en REST) |
| Consulta recomendada | Cada 3 a 5 segundos |
¿Cómo funciona la API de RecibeSMS?
Cada activación sigue el mismo ciclo. Pides un número para un servicio (y, si quieres, un país). El precio se congela en tu saldo y el pedido empieza en PENDING. Escribes el número en la app de destino y consultas el pedido. Cuando llega el SMS, el pedido pasa a RECEIVED, se devuelve el código y se cobra el importe congelado. Después terminas el pedido, o lo cancelas si no llegó nada.
Las dos API usan la misma lógica que el sitio web: mismo catálogo, mismos precios, mismo saldo y las mismas devoluciones automáticas. Usa la API REST para integraciones nuevas y el endpoint compatible con SMS-Activate cuando ya tienes software escrito para ese protocolo.
¿Cómo consigo y uso una clave de API?
El acceso a la API se activa tras tu primera recarga confirmada (mínimo US$ 5). Abre la sección API de tu panel y genera una clave. La clave completa se muestra una sola vez, al generarla; guardamos solo un hash y el panel muestra después sus primeros caracteres. Cada cuenta tiene una clave activa: generar una nueva revoca la anterior al instante, y puedes revocarla cuando quieras.
Envía la clave de una de estas tres formas, que se revisan en este orden: la cabecera X-Api-Key (recomendada en REST), una cabecera Authorization: Bearer o el parámetro api_key en la URL (el estilo de SMS-Activate). Una clave no válida o revocada devuelve HTTP 401 en REST y BAD_KEY en el endpoint compatible. Trata la clave como una contraseña: puede gastar tu saldo.
¿Qué acepta el endpoint compatible con SMS-Activate?
Envía solicitudes GET o POST a https://recibesms.com/api/stubs/handler_api.php con api_key y action (también se aceptan campos de formulario POST). Las respuestas son texto plano o JSON y usan siempre HTTP 200, así que lee el cuerpo, no el código de estado. El parámetro service acepta códigos estándar del protocolo como wa o tg, o el nombre del servicio, como whatsapp. El país es un id numérico de la numeración de SMS-Activate; omítelo o envía 0 para el país predeterminado, Estados Unidos (187). El id que devuelve getNumber es el id del pedido en RecibeSMS.
| action | Parámetros | Respuesta correcta | Errores posibles |
|---|---|---|---|
| getBalance | ninguno | ACCESS_BALANCE:12.50 | NO_KEY, BAD_KEY |
| getNumber | service, country (opcional: id numérico, nombre del catálogo o ISO2; 0 = Estados Unidos), operator (opcional), server (opcional, 1 o 2) | ACCESS_NUMBER:{id}:{teléfono} | BAD_SERVICE, WRONG_COUNTRY, WRONG_OPERATOR, NO_BALANCE, NO_NUMBERS, SERVER_ERROR |
| getStatus | id | STATUS_WAIT_CODE, STATUS_OK:{código}, STATUS_WAIT_RETRY:{último código}, STATUS_CANCEL | NO_ACTIVATION |
| setStatus | id, status (1, 3, 6 u 8) | 1: ACCESS_READY; 3: ACCESS_RETRY_GET; 6: ACCESS_ACTIVATION; 8: ACCESS_CANCEL | NO_ACTIVATION, BAD_STATUS, EARLY_CANCEL_DENIED |
| getPrices | country (opcional), service (opcional), server (opcional) | JSON: {"187": {"wa": {"cost": precio, "count": stock}}} | {} para un país desconocido |
| getNumbersStatus | country (opcional), server (opcional) | JSON: {"wa_0": stock, "tg_0": stock} | {} para un país desconocido |
| getServicesList | ninguno | JSON: {"status": "success", "services": [{"code": "wa", "name": "whatsapp"}]} | ninguno |
| getCountries | ninguno | JSON con cada país con stock: {"187": {"id": 187, "eng": "usa", "rus": "usa", "visible": 1, "name": nombre, "iso": "us", "dial_code": "+1"}} (los ids mayores de 1000 son ids propios de RecibeSMS para países sin id en la numeración de SMS-Activate) | ninguno |
¿Qué hace cada valor de setStatus?
setStatus sigue el protocolo original en los cuatro valores que importan en una activación. Cualquier otro valor devuelve BAD_STATUS.
| status | Significado | Respuesta | Notas |
|---|---|---|---|
| 1 | Listo para recibir el SMS | ACCESS_READY | Se acepta por compatibilidad; no cambia nada más |
| 3 | Pedir otro SMS en el mismo número | ACCESS_RETRY_GET | Solo después del primer código y mientras el número sigue activo; sin costo extra. Si no, BAD_STATUS |
| 6 | Terminar la activación | ACCESS_ACTIVATION | Si nunca llegó un SMS, se libera el importe congelado |
| 8 | Cancelar y devolver | ACCESS_CANCEL | Solo antes de que llegue un SMS. Demasiado pronto devuelve EARLY_CANCEL_DENIED (espera unos 2 minutos); después de un SMS devuelve BAD_STATUS |
¿Qué endpoints tiene la API REST v1?
La API REST está en https://recibesms.com/api/v1, devuelve JSON y usa códigos HTTP estándar. Autentícate con la cabecera X-Api-Key. Los importes están en la moneda de tu cuenta. Al comprar, country acepta el nombre del catálogo (usa, mexico, spain…), un código ISO2 (us, mx, es) o el nombre en inglés; el predeterminado es Estados Unidos. El parámetro opcional server (1 o 2) elige el proveedor de líneas; omítelo para la selección automática. Los nombres de servicio salen de GET /services.
| Método y ruta | Qué hace | Notas |
|---|---|---|
| GET /balance | Devuelve {"balance", "frozen", "currency"} | frozen es el importe retenido por pedidos que esperan un SMS |
| GET /services | Catálogo: product, price, count (stock), rate, countries_count y países disponibles | Opcionales ?search= (hasta 60 caracteres), ?server= (1 o 2, por defecto 1), ?country= |
| GET /services/{product}/countries | Cada país con oferta para un servicio: country, name, iso, dial_code, price, count, server, rate3, rate24 y offers[] por servidor | Funciona con cualquier producto; ?server= opcional; lista vacía si no hay stock |
| POST /orders | Compra un número. Cuerpo: {"product": "whatsapp", "country": "mexico", "server": 1, "operator": "any"} (server y operator opcionales) | 201 Created; 400 país u operador no disponible o cancelación demasiado pronto, 402 sin saldo, 404 servicio desconocido, 409 sin números, 422 cuerpo no válido (detail es una lista), 429 más de 500 por minuto, 502 proveedor no disponible |
| GET /orders | Lista tus pedidos, del más reciente al más antiguo | ?limit= de 1 a 100 (por defecto 50), ?offset= |
| GET /orders/{id} | Estado del pedido, sincronizado con el proveedor de líneas | Aquí aparece el SMS; consulta cada 3 a 5 segundos |
| POST /orders/{id}/finish | Marca la activación como terminada | Libera el importe congelado si no llegó ningún SMS |
| POST /orders/{id}/cancel | Cancela y devuelve | Solo antes de que llegue un SMS; puede exigir esperar unos 2 minutos (400 si es demasiado pronto). Idempotente: un pedido ya cancelado, caducado o bloqueado devuelve 200 con el pedido |
| POST /orders/{id}/resend | Pide otro SMS en el mismo número | Después del primer código, mientras está activo, sin costo extra; 30 solicitudes por minuto |
| POST /orders/{id}/ban | Reporta el número como ya usado o bloqueado y lo devuelve | Libera el importe congelado si no se cobró ningún SMS; puede exigir esperar unos 2 minutos |
¿Cómo es un pedido?
Los endpoints de pedidos devuelven un objeto con id, phone, product, country, operator, status, price, created_at, expires (marcas de tiempo UTC), messages, awaiting_resend, server y provider_order_id (el id de la activación en el proveedor de líneas, útil al abrir un ticket). Cada elemento de messages tiene sender, text, code y received_at. Cuando una app envía un mensaje sin un código aislado, el texto completo sigue en text.
| Estado REST | Significado | Respuesta de getStatus | Cobro |
|---|---|---|---|
| PENDING | Número emitido, esperando el SMS | STATUS_WAIT_CODE | Precio congelado, sin cobrar |
| RECEIVED | Llegó el SMS; el código está en messages | STATUS_OK:{código} (STATUS_WAIT_RETRY:{código} mientras hay un reenvío pendiente) | Cobrado |
| FINISHED | Activación cerrada por ti | STATUS_OK:{código}, o STATUS_CANCEL si nunca llegó un SMS | Cobrado solo si llegó un SMS |
| CANCELED | Cancelado antes de cualquier SMS | STATUS_CANCEL | Devuelto completo |
| TIMEOUT | Caducó sin SMS | STATUS_CANCEL | Devuelto automáticamente |
| BANNED | Reportado como usado o bloqueado | STATUS_CANCEL | Devuelto si no se cobró ningún SMS |
¿Hay límites de uso y cómo se devuelven los errores?
Cada cuenta puede hacer hasta 500 compras de números por minuto entre las dos API. En REST, POST /orders también está limitado a 500 solicitudes por minuto por IP, y resend a 30 por minuto; si te pasas, recibes HTTP 429. En el endpoint compatible, llegar al límite de compras devuelve NO_NUMBERS. La generación de claves en el panel está limitada a 10 por hora.
Los errores REST usan códigos HTTP con un campo detail en JSON: 400 (solicitud no válida, como cancelar demasiado pronto o un país sin oferta), 401 (clave ausente, no válida o revocada), 402 (saldo insuficiente), 404 (servicio o pedido desconocido), 409 (sin números en stock), 422 (el cuerpo no pasó la validación; detail es una lista de errores por campo), 429 (límite de solicitudes por IP o del límite de 500 compras por minuto de la cuenta) y 502 (proveedor de líneas no disponible). Un 429 con cabecera Retry-After también puede indicar una pausa del proveedor: espera los segundos indicados o reintenta con el otro servidor. El endpoint compatible siempre devuelve HTTP 200 con un código de texto: NO_KEY, BAD_KEY, BAD_ACTION, BAD_SERVICE, WRONG_COUNTRY, WRONG_OPERATOR, NO_BALANCE, NO_NUMBERS, NO_ACTIVATION, BAD_STATUS, EARLY_CANCEL_DENIED o SERVER_ERROR.
¿Cómo funcionan las devoluciones en la API?
Nunca tienes que reclamar una devolución. Una compra solo congela el precio. Si no llega ningún SMS en hasta 20 minutos, el pedido caduca y el importe congelado vuelve a tu saldo automáticamente. Para recuperarlo antes, cancela con POST /orders/{id}/cancel o setStatus 8 una vez pasados unos 2 minutos. Cuando ya llegó un SMS, el pedido está cobrado y no se puede cancelar; termínalo.
¿Qué reglas de uso tiene la API?
La API tiene el mismo poder de compra que tu cuenta y las mismas reglas. Úsala para verificar cuentas propias o probar tus propios productos, respeta las condiciones de cada app y no la uses para fraude, spam, suplantación ni para saltarte bloqueos; lo detalla nuestra política de uso aceptable. Las dudas sobre una integración puedes enviarlas a [email protected].
Ejemplos de código
curl "https://recibesms.com/api/stubs/handler_api.php?api_key=$API_KEY&action=getBalance"
# ACCESS_BALANCE:12.50curl "https://recibesms.com/api/stubs/handler_api.php?api_key=$API_KEY&action=getNumber&service=wa&country=187"
# ACCESS_NUMBER:123456:12025550123curl "https://recibesms.com/api/stubs/handler_api.php?api_key=$API_KEY&action=getStatus&id=123456"
# STATUS_WAIT_CODE (sigue consultando cada 3-5 segundos)
# STATUS_OK:482913 (código recibido)# Terminar después de usar el código
curl "https://recibesms.com/api/stubs/handler_api.php?api_key=$API_KEY&action=setStatus&id=123456&status=6"
# ACCESS_ACTIVATION
# Cancelar y recuperar el saldo si no llegó ningún SMS
curl "https://recibesms.com/api/stubs/handler_api.php?api_key=$API_KEY&action=setStatus&id=123456&status=8"
# ACCESS_CANCEL (o EARLY_CANCEL_DENIED: vuelve a intentarlo en un momento)curl -X POST "https://recibesms.com/api/v1/orders" \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"product": "whatsapp", "country": "mexico"}'
curl "https://recibesms.com/api/v1/orders/123456" -H "X-Api-Key: $API_KEY"import os
import time
import requests
BASE = "https://recibesms.com/api/v1"
HEADERS = {"X-Api-Key": os.environ["RECIBESMS_API_KEY"]}
order = requests.post(f"{BASE}/orders", headers=HEADERS,
json={"product": "whatsapp", "country": "mexico"}).json()
print("Número:", order["phone"])
deadline = time.time() + 20 * 60
while time.time() < deadline:
order = requests.get(f"{BASE}/orders/{order['id']}", headers=HEADERS).json()
if order["messages"]:
print("Código:", order["messages"][-1]["code"])
requests.post(f"{BASE}/orders/{order['id']}/finish", headers=HEADERS)
break
if order["status"] in ("CANCELED", "TIMEOUT", "BANNED", "FINISHED"):
print("Cerrado sin código; el importe congelado se devolvió.")
break
time.sleep(5)const BASE = "https://recibesms.com/api/stubs/handler_api.php";
const KEY = process.env.RECIBESMS_API_KEY;
async function call(params) {
const qs = new URLSearchParams({ api_key: KEY, ...params });
const res = await fetch(BASE + "?" + qs);
return (await res.text()).trim();
}
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const number = await call({ action: "getNumber", service: "wa", country: "187" });
if (!number.startsWith("ACCESS_NUMBER:")) throw new Error(number);
const [, id, phone] = number.split(":");
console.log("Número:", phone);
for (let i = 0; i < 240; i++) {
const status = await call({ action: "getStatus", id });
if (status.startsWith("STATUS_OK:")) {
console.log("Código:", status.slice("STATUS_OK:".length));
await call({ action: "setStatus", id, status: "6" });
break;
}
if (status === "STATUS_CANCEL") break;
await sleep(5000);
}Preguntas frecuentes
Preguntas frecuentes sobre la API
¿La API de RecibeSMS es compatible con SMS-Activate?
Sí, para el flujo principal de activación. RecibeSMS sirve el protocolo handler_api de SMS-Activate en /api/stubs/handler_api.php con getBalance, getNumber, getStatus, setStatus, getPrices, getNumbersStatus, getServicesList y getCountries. La mayoría de las herramientas hechas para SMS-Activate funcionan cambiando la URL base y la api_key, y la API REST está para proyectos nuevos.
¿Cómo consigo una clave de API?
Haz tu primera recarga de al menos US$ 5, abre la sección API de tu panel de RecibeSMS y genera una clave. Se muestra una sola vez, así que guárdala en un lugar seguro. Cada cuenta tiene una clave activa; generar una nueva revoca la anterior al instante, y también puedes revocarla tú cuando quieras.
¿Se me cobra al pedir un número por la API?
No. Pedir un número congela su precio en tu saldo; el cobro solo ocurre cuando llega el SMS. Si el número caduca tras hasta 20 minutos sin código, o lo cancelas tras unos 2 minutos, el importe congelado vuelve a tu saldo automáticamente. GET /balance muestra el saldo disponible y el congelado por separado.
¿Cada cuánto debo consultar el código SMS?
Consulta cada 3 a 5 segundos con GET /api/v1/orders/{id} o con la acción getStatus. Cada consulta sincroniza el pedido con el proveedor de líneas, y ahí aparece el código. Deja de consultar cuando tengas el código o cuando el pedido esté en CANCELED, TIMEOUT, BANNED o FINISHED (STATUS_CANCEL en el endpoint compatible).
¿Qué límites de uso tiene la API?
Cada cuenta puede comprar hasta 500 números por minuto entre las dos API. En REST, POST /orders también está limitado a 500 solicitudes por minuto por IP y el endpoint de reenvío a 30 por minuto; al superarlos recibes HTTP 429. En el endpoint compatible, el límite de compras aparece como NO_NUMBERS.
¿Qué códigos de país usa el endpoint compatible?
Los ids de país siguen la numeración de SMS-Activate. Si omites country o envías 0, RecibeSMS usa el país predeterminado, Estados Unidos, cuyo id es 187. Llama a getCountries para ver todos los ids disponibles en tu cuenta, y a getPrices o getNumbersStatus con un id de país para ver precio y stock actuales.
¿Puedo recibir un segundo código en el mismo número?
Sí, mientras el número siga activo y después de que haya llegado el primer código. Usa setStatus con status=3 en el endpoint compatible o POST /api/v1/orders/{id}/resend en REST. No tiene costo extra. Hasta que llegue el nuevo SMS, getStatus devuelve STATUS_WAIT_RETRY con el último código recibido.
¿Por qué el endpoint compatible siempre devuelve HTTP 200?
Así funciona el protocolo de SMS-Activate: los clientes leen el cuerpo de la respuesta, no el código HTTP. RecibeSMS mantiene ese comportamiento para que el software existente funcione sin cambios. Los errores llegan como códigos de texto, como BAD_KEY, NO_BALANCE o NO_NUMBERS. La API REST bajo /api/v1 usa códigos HTTP normales.
Última actualización:
Listo cuando tú lo estés
Empieza a integrar en minutos
Crea tu cuenta, haz tu primera recarga y genera tu clave de API.