El árbol del catálogo
Recorre el catálogo con un nivel acotado por llamada (plataformas, luego países, luego proveedores, luego opciones) sin clave de API, y usa los ids directamente en un pedido.
El catálogo es un árbol. Cada llamada devuelve solo el nivel que hay debajo de la elección que hiciste, así que nunca descargas todo el mercado para encontrar un precio.
/catalog/platforms todas las plataformas con stock
/catalog/platforms/{platform}/countries dónde se vende esa plataforma
/catalog/platforms/{platform}/countries/{country}/providers quién la vende allí
/catalog/platforms/{platform}/countries/{country}/providers/{provider}/options desde qué la vende cada unoCada id del recorrido es exacto y es lo que acepta /purchase/sms.
No necesitas clave
Todo el árbol es público. Si lo llamas sin clave, recibes los precios de lista públicos, con un límite de 10 solicitudes por segundo por dirección IP. Si envías tu clave, cada precio es el de tu cuenta (lo que realmente te cobrará un pedido), con el límite de tu cuenta. Una clave incorrecta se rechaza con 403 en lugar de ignorarse. Consulta Autenticación.
- 1 · Plataformas
- 2 · Países
- 3 · Proveedores
- 4 · Opciones
curl https://numestri.com/api/v1/catalog/platforms{
"success": 1,
"prices_at": "2026-10-14T01:40:00.000Z",
"count": 1326,
"next": "/api/v1/catalog/platforms/{platform}/countries",
"data": [
{ "id": "discord", "name": "Discord", "countries": 12, "from_price": "0.07", "from_price_cents": 7 }
]
}Campo | Significado |
|---|---|
| El id de la plataforma: |
| En cuántos países tiene stock. |
| Su número más barato, en cualquier país. |
curl https://numestri.com/api/v1/catalog/platforms/discord/countries{
"success": 1,
"prices_at": "2026-10-14T01:40:00.000Z",
"platform": "discord",
"count": 12,
"next": "/api/v1/catalog/platforms/discord/countries/{country}/providers",
"data": [
{ "id": "US", "name": "United States", "providers": 2, "from_price": "0.07", "from_price_cents": 7 }
]
}Campo | Significado |
|---|---|
| Código ISO 3166-1 alfa-2: |
| Cuántos proveedores venden la plataforma allí. |
| El número más barato para la plataforma en este país. |
curl https://numestri.com/api/v1/catalog/platforms/discord/countries/US/providers{
"success": 1,
"prices_at": "2026-10-14T01:40:00.000Z",
"platform": "discord",
"country": "US",
"count": 2,
"next": "/api/v1/catalog/platforms/discord/countries/US/providers/{provider}/options",
"data": [
{ "id": "prv_k3Jd9QmXa2", "rank": 1, "options": 2, "from_price": "0.07", "from_price_cents": 7, "quality": null, "success_rate": null }
]
}Campo | Significado |
|---|---|
| El identificador del proveedor: |
|
|
| Cuántas ofertas tiene aquí. |
| Su historial de entrega para esta plataforma en este país; |
curl https://numestri.com/api/v1/catalog/platforms/discord/countries/US/providers/prv_k3Jd9QmXa2/options{
"success": 1,
"prices_at": "2026-10-14T01:40:00.000Z",
"platform": "discord",
"country": "US",
"provider": "prv_k3Jd9QmXa2",
"count": 2,
"order": { "endpoint": "/api/v1/purchase/sms", "params": { "service": "discord", "country": "US", "option": "{option}" } },
"data": [
{ "option": "k3Jd9QmXa2Lp0cWe", "rank": 1, "price": "0.07", "price_cents": 7, "quality": null, "success_rate": null, "stock": "plenty" },
{ "option": "Vb7nR2sYq0Te4hUa", "rank": 2, "price": "0.10", "price_cents": 10, "quality": null, "success_rate": null, "stock": "plenty" }
]
}Campo | Significado |
|---|---|
| El id que debes enviar como |
| Lo que cuesta un número. |
|
|
order detalla la llamada a /purchase/sms que compra una de estas.
Ids: plataforma, país, proveedor, opción
Id | Aspecto | ¿Estable? | Úsalo como |
|---|---|---|---|
Plataforma |
| Sí |
|
País |
| Sí |
|
Proveedor |
| Sí: un mismo proveedor conserva su identificador en todas las plataformas, países y a lo largo del tiempo |
|
Opción | De 8 a 32 letras, dígitos, | Mientras exista esa oferta |
|
Ambos identificadores son opacos. El de un proveedor no dice nada de quién está detrás, y el id de una opción es propio de una plataforma y un país (la misma oferta en otro lugar tiene otro id), así que no los analices ni los construyas tú: cópialos del catálogo. Una opción que ya no existe se rechaza al hacer el pedido con el código OPTION_GONE.
Reglas que conviene conocer
Solo lo que tiene stock. Cada nivel muestra únicamente lo que puedes comprar ahora mismo. Una elección sin nada debajo devuelve un
404cuyo mensaje te remite al nivel superior:{ "success": 0, "errors": [{ "message": "Nothing is in stock for \"discord\" in \"FR\". See /api/v1/catalog/platforms/discord/countries.", "param": "country" }] }Ids exactos.
Telegram,tg,usyUnited Statesno son ids. En una ruta del catálogo no encuentran nada y responden404; como parámetroserviceocountryde/request/priceo/purchase/smsse rechazan con400. UsatelegramyUStal como aparecen en el catálogo.Actualizado. Los precios y el stock se actualizan aproximadamente cada dos minutos;
prices_atindica cuándo se leyeron los precios que estás viendo.En arranque. Justo después de un reinicio, el catálogo puede responder
503conPrices are being refreshed. Try again in a few seconds.: vuelve a intentarlo en un momento.Los números compartidos no están en el árbol. El árbol muestra números privados. Si hay un número compartido más barato, con bandeja pública, para una plataforma y un país, lo indica el campo
shared_inboxde/request/price.
Caché con ETags
Cada nivel incluye un ETag y Cache-Control: private, max-age=30. Devuelve el ETag como If-None-Match y, mientras nada haya cambiado en ese nivel, recibirás un 304 sin cuerpo en lugar de la lista:
curl -i https://numestri.com/api/v1/catalog/platforms/discord/countries
# HTTP/1.1 200 OK
# ETag: W/"…"
curl -i https://numestri.com/api/v1/catalog/platforms/discord/countries -H 'If-None-Match: W/"…"'
# HTTP/1.1 304 Not ModifiedLas etiquetas son débiles y se comparan de forma débil:
W/"x"y"x"coinciden.If-None-Matchpuede contener una lista separada por comas, o*.La etiqueta cambia cada vez que pueden haber cambiado los precios que hay detrás del nivel (también cuando cambian los precios que se te aplican a ti), así que un
304siempre significa que tu copia está al día.Los precios públicos y los de tu cuenta pueden tener etiquetas distintas. Guarda cada etiqueta con la respuesta de la que salió y no reutilices una etiqueta anónima en una solicitud con clave.
Una solicitud con
key=en la URL nunca se puede almacenar en caché; envía la clave en una cabecera si quieres caché.
Llamada de resumen
GET /api/v1/catalog describe el árbol y las tres formas de hacer un pedido, para que un cliente pueda descubrirlo sin rutas escritas a mano. También es pública.
{
"success": 1,
"prices_at": "2026-10-14T01:40:00.000Z",
"platforms_in_stock": 1326,
"tree": [
{ "level": 1, "list": "platforms", "path": "/api/v1/catalog/platforms" },
{ "level": 2, "list": "countries for a platform", "path": "/api/v1/catalog/platforms/{platform}/countries" },
{ "level": 3, "list": "providers for a platform in a country", "path": "/api/v1/catalog/platforms/{platform}/countries/{country}/providers" },
{ "level": 4, "list": "a provider's options", "path": "/api/v1/catalog/platforms/{platform}/countries/{country}/providers/{provider}/options" }
],
"ordering": {
"endpoint": "/api/v1/purchase/sms",
"choose_by": [
"service + country: the best option, failing over to the next",
"service + country + provider: that provider only, its best option first",
"service + country + option: exactly that option at its listed price, or nothing"
]
}
}Listas públicas más sencillas
Si solo necesitas nombres e ids (para una lista desplegable, por ejemplo), hay dos listas planas que mantienen el formato que usan la mayoría de las API de verificación. No aceptan ninguna clave.
Endpoint | Devuelve |
|---|---|
|
|
|
|
ID es el id exacto que aceptan los endpoints de pedidos. Ambas muestran siempre los precios públicos.