Desarrolladores
Cuatro endpoints, dos webhooks, ninguna sorpresa.
Todo lo que hace la tienda lo puede hacer tu producto. La superficie entera cabe en una página.
Por qué existe esta API
Aprovisionar la conexión debería ocurrir en el momento en que el viajero reserva, dentro de tu propio producto. No debería ser algo que descubra en un aeropuerto.
Una plataforma de reservas puede añadir datos a un itinerario. Un fabricante de dispositivos puede activar un plan durante la configuración inicial. Una herramienta de equipo puede entregarle sus datos a alguien que acaba de entrar, junto con el portátil.
Los tres casos son cuatro llamadas y un webhook. No hay ningún portal de socios en el que entrar ni ningún CSV que subir.
Autenticación
Envía tu clave como token bearer en cada petición. Las claves llevan el prefijo sk_test en sandbox y sk_live en producción.
Una clave pegada en el entorno equivocado falla con un 401 en vez de gastar dinero en silencio. Las claves tienen alcance, así que una clave de solo lectura no puede crear un pedido y una clave emitida para una cuenta de equipo no puede ver otra.
Rótalas desde la consola cuando quieras. La clave antigua sigue funcionando 24 horas, así que nunca te obligamos a un cambio de golpe.
curl https://api.orbislo.com/v1/catalog?country=jp \
-H "Authorization: Bearer sk_live_9f2c..." \
-H "Orbislo-Version: 2026-08-01"Sobre la cabecera de versión
La cabecera de versión es opcional y fija la forma de la respuesta a una publicación con fecha. Sin ella recibes la versión con la que se creó tu clave, que nunca cambia por debajo de ti.
Añadimos campos sin avisar. Nunca quitamos un campo ni cambiamos su tipo dentro de una versión.
4
endpoints en toda la API, más 2 eventos de webhook
90 s
mediana desde un pedido correcto hasta un perfil activado
24 h
ventana en la que una clave de idempotencia repetida devuelve la respuesta original
Los endpoints
| Método | Ruta | Qué hace | Límite de tasa |
|---|---|---|---|
| GET | /v1/catalog | Todos los planes que vendemos, con precio, datos, validez y los países que cubren. | 600 por minuto |
| POST | /v1/orders | Compra un plan y devuelve un pedido con un trabajo de aprovisionamiento asociado. | 60 por minuto |
| GET | /v1/provisioning/:id | El estado de un trabajo de aprovisionamiento, desde queued hasta activated o failed. | 600 por minuto |
| GET | /v1/usage/:esim_id | Bytes usados, bytes restantes y el operador al que está enganchada una eSIM. | 300 por minuto |
Los límites son por clave en una ventana deslizante. Cada respuesta lleva el conteo restante y la hora de reinicio, y un 429 lleva un retardo de reintento en segundos. Si tu caso de uso necesita de verdad un cubo mayor, pídelo, porque ampliarlo es un cambio de configuración y no una negociación.
Catálogo
El catálogo es la fuente de verdad sobre qué existe y cuánto cuesta. Cubre los 145 destinos activos hoy.
Filtra por país, por región o por familia de planes. Los precios se devuelven en unidades menores, así que los números en coma flotante nunca llegan a tu código de facturación.
GET /v1/catalog?country=jp
{
"object": "list",
"data": [
{
"id": "plan_jp_5gb",
"name": "Japan 5 GB",
"countries": ["jp"],
"data_mb": 5120,
"price": { "amount": 1150, "currency": "usd" },
"expires": false,
"throttle_mbps": null,
"tethering": true,
"carriers": ["NTT Docomo", "KDDI", "SoftBank"]
}
],
"has_more": false
}Dos campos que conviene leer dos veces
El campo expires es false en todos los planes medidos que vendemos, porque nuestros datos no caducan. Si estás construyendo una comparativa de precios, ese campo cambia la aritmética más que el precio.
El campo throttle_mbps es null en los planes medidos y 1 en los pases diarios ilimitados, donde la velocidad completa llega hasta 2 GB al día y luego baja a 1 Mbps.
Ponemos la cifra del límite en la API por la misma razón por la que la imprimimos en el botón de compra. Un número que el viajero descubre más tarde es un ticket de soporte.
Pedidos
Un solo POST compra un plan y arranca el aprovisionamiento. La cabecera Idempotency-Key es obligatoria, no una recomendación.
El peor desenlace de esta API es un timeout que te deja sin saber si al viajero se le cobró. Una clave obligatoria elimina ese estado por completo.
POST /v1/orders
Idempotency-Key: 4f1d0f6e-1c3a-4a2b-9d77-1b6a0e7c9f21
Content-Type: application/json
{
"plan_id": "plan_jp_5gb",
"traveller_ref": "user_88213",
"imei": "356938035643809",
"activate": "on_first_use"
}
201 Created
{
"id": "ord_7Kd2mQ",
"status": "provisioning",
"esim_id": "esim_2xB9Ln",
"provisioning_id": "prv_5Ttq81",
"amount": { "amount": 1150, "currency": "usd" },
"activation": {
"type": "universal_link",
"url": "https://orbislo.com/i/2xB9Ln",
"lpa": "LPA:1$rsp.orbislo.com$K4-9TT-2XB9LN"
}
}Comprobación del dispositivo y activación diferida
El campo imei es opcional pero muy recomendable. Envíalo y comprobamos la compatibilidad con eSIM y el bloqueo de operador antes de cobrar.
Un teléfono que no puede alojar un perfil recibe un 422 con device_not_eligible en vez de un plan vendido y un viajero enfadado.
Poner activate en on_first_use hace que cualquier ventana de validez empiece cuando el viajero aterriza, no cuando tu servidor nos llamó.
Estado del aprovisionamiento
El aprovisionamiento es asíncrono, porque al otro lado hay una plataforma de operador. Sondea este endpoint, o quédate con el webhook y olvídate del sondeo.
La mediana desde queued hasta activated es de menos de 90 segundos. Todo lo que siga en queued pasados 10 minutos es un fallo, y se reembolsa solo.
GET /v1/provisioning/prv_5Ttq81
{
"id": "prv_5Ttq81",
"status": "activated",
"states": [
{ "state": "queued", "at": "2026-08-24T09:14:02Z" },
{ "state": "provisioning", "at": "2026-08-24T09:14:04Z" },
{ "state": "installed", "at": "2026-08-24T09:14:41Z" },
{ "state": "activated", "at": "2026-08-24T09:15:07Z" }
],
"carrier": "KDDI",
"failure_reason": null
}Webhooks
Dos eventos, y los dos cambian lo que hay que contarle al viajero. Apúntalos a cualquier endpoint HTTPS, configurado por separado en cada entorno.
Eventos de webhook
| Evento | Se dispara cuando | Qué hacer con él |
|---|---|---|
| esim.activated | El perfil se engancha a una red por primera vez. | Dile al viajero que ya está en línea. Ese es el momento en que la compra se vuelve real para él. |
| esim.depleted | El plan cruza un umbral de consumo, al 80 por ciento y otra vez al 100 por ciento. | Ofrécele una recarga antes de que se quede tirado, no después. |
POST https://your-app.example/hooks/orbislo
Orbislo-Signature: t=1756032907,v1=6c1b...
Content-Type: application/json
{
"id": "evt_9pQ4rz",
"type": "esim.depleted",
"created": "2026-08-24T11:41:33Z",
"data": {
"esim_id": "esim_2xB9Ln",
"threshold": 80,
"used_mb": 4096,
"remaining_mb": 1024,
"country": "jp"
}
}Verificar una entrega
Calcula HMAC SHA-256 sobre la marca de tiempo, un punto y el cuerpo crudo de la petición, con el secreto de tu endpoint. Compara en tiempo constante.
Rechaza cualquier cosa con una marca de tiempo de más de 5 minutos, y así paras un replay. Las entregas son al menos una vez y se reintentan 8 veces a lo largo de 24 horas, así que indexa tu handler por el id del evento.
Códigos de error
| HTTP | Código | Qué significa | Qué hacer |
|---|---|---|---|
| 400 | invalid_request | Falta un campo o tiene el tipo equivocado. El cuerpo nombra el campo. | Corrige la petición. Reintentar no sirve de nada. |
| 401 | invalid_token | El token bearer es incorrecto, está revocado o es del otro entorno. | Comprueba que no estás enviando una clave de sandbox al host de producción. |
| 402 | insufficient_balance | El saldo de tu cuenta no cubre el pedido. | Recarga y reintenta con la misma clave de idempotencia. |
| 404 | not_found | No hay ningún objeto con ese id en este entorno. | Los id de sandbox y los de producción no son intercambiables. |
| 409 | idempotency_conflict | La misma clave de idempotencia se reutilizó con un cuerpo distinto. | Usa una clave nueva, o reenvía el cuerpo original byte a byte. |
| 422 | device_not_eligible | El dispositivo no admite eSIM, o está bloqueado por operador. | Haz la comprobación del dispositivo antes de cobrar. |
| 429 | rate_limited | Te pasaste del cubo de ese endpoint. | Espera usando el retardo de reintento de la cabecera. No insistas en bucle. |
| 500 | internal_error | Nuestro. Ya está en nuestras alertas. | Reintenta con la misma clave de idempotencia después de 2 segundos. |
| 503 | provider_unavailable | Una plataforma de operador aguas arriba está caída. | Reintenta hasta 10 minutos. Hacemos failover automático donde existe un segundo operador. |
Todo cuerpo de error lleva un código, un mensaje legible por una persona y un id de petición. Cita el id de petición al soporte y te saltas las cuatro primeras preguntas.
Sandbox frente a producción
Mismo host, mismas rutas, mismas formas de respuesta. Una clave con prefijo sk_test nunca toca dinero y nunca crea un perfil de operador.
Los trabajos de aprovisionamiento recorren la máquina de estados completa en unos 4 segundos, así que tus pruebas no duermen 90 segundos cada una.
Pide el plan con id plan_test_fail para obtener un trabajo fallido con su motivo. Pide plan_test_slow para obtener uno que se queda en provisioning 11 minutos, y así ejercitas tu ruta de timeout.
Los webhooks también se disparan en sandbox, contra una URL que configuras por entorno.
Si prefieres no construir nada
El programa de afiliados paga por los pedidos referidos sin ninguna integración, que es la respuesta correcta para la mayoría de los sitios de contenido.
El endpoint MCP expone nuestro conjunto de datos de cobertura y el índice de precios a un asistente de IA con una línea de configuración y cero código.
Los planes que venderías, los datos de velocidad medida que hay detrás del catálogo y la lista completa de países están publicados abiertamente en este sitio.
Preguntas que hacen los desarrolladores
¿Puedo conseguir una clave de API hoy?
¿Cuánto tarda la aprobación?
¿Qué diferencia hay entre sandbox y producción?
¿Necesito claves de idempotencia?
¿Cuáles son los límites de tasa?
¿Hasta qué punto son fiables los webhooks?
¿Hay SDK?
¿Qué pasa si el aprovisionamiento falla?
Empieza por el sandbox, o sáltate el código del todo
Las credenciales de sandbox llegan el mismo día laborable. Si prefieres no escribir una integración, ni el programa de afiliados ni el endpoint MCP necesitan que construyas nada.