Desenvolvedores
Quatro endpoints, dois webhooks, nenhuma surpresa.
Tudo o que a loja faz, o seu produto também faz. A superfície inteira cabe em uma página.
Por que esta API existe
Provisionar conexão deveria acontecer no momento em que o viajante reserva, dentro do seu próprio produto. Não deveria ser algo que ele descobre no aeroporto.
Uma plataforma de reservas pode anexar dados a um itinerário. Um fabricante de aparelhos pode ativar um plano durante a configuração inicial. Uma ferramenta de equipe pode entregar os dados de quem acabou de entrar junto com o notebook.
Os três casos são quatro chamadas e um webhook. Não existe portal de parceiros para acessar nem CSV para subir.
Autenticação
Envie sua chave como token bearer em toda requisição. As chaves têm prefixo sk_test no sandbox e sk_live em produção.
Uma chave colada no ambiente errado falha com um 401 em vez de gastar dinheiro em silêncio. As chaves têm escopo, então uma chave somente de leitura não cria pedido e uma chave emitida para uma conta de equipe não enxerga outra.
Rotacione pelo console quando quiser. A chave antiga continua funcionando por 24 horas, então você nunca é forçado a virar tudo de uma vez.
curl https://api.orbislo.com/v1/catalog?country=jp \
-H "Authorization: Bearer sk_live_9f2c..." \
-H "Orbislo-Version: 2026-08-01"Sobre o cabeçalho de versão
O cabeçalho de versão é opcional e prende o formato da resposta a uma publicação datada. Sem ele você recebe a versão com a qual sua chave foi criada, que nunca muda por baixo de você.
Adicionamos campos sem aviso. Nunca removemos um campo nem mudamos o tipo dele dentro de uma versão.
4
endpoints na API inteira, mais 2 eventos de webhook
90 s
tempo mediano de um pedido aceito até um perfil ativado
24 h
janela em que uma chave de idempotência repetida devolve a resposta original
Os endpoints
| Método | Caminho | O que faz | Limite de taxa |
|---|---|---|---|
| GET | /v1/catalog | Todo plano que vendemos, com preço, dados, validade e os países cobertos. | 600 por minuto |
| POST | /v1/orders | Compra um plano e devolve um pedido com um job de provisionamento anexado. | 60 por minuto |
| GET | /v1/provisioning/:id | O estado de um job de provisionamento, de queued até activated ou failed. | 600 por minuto |
| GET | /v1/usage/:esim_id | Bytes usados, bytes restantes e a operadora à qual uma eSIM está conectada. | 300 por minuto |
Os limites são por chave em uma janela deslizante. Toda resposta traz a contagem restante e a hora de reinício, e um 429 traz um atraso de nova tentativa em segundos. Se o seu caso de uso realmente precisa de um balde maior, peça, porque aumentar um é mudança de configuração e não negociação.
Catálogo
O catálogo é a fonte da verdade sobre o que existe e quanto custa. Ele cobre os 145 destinos no ar hoje.
Filtre por país, por região ou por família de planos. Os preços voltam em unidades menores, então ponto flutuante nunca chega ao seu código de cobrança.
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
}Dois campos que merecem uma segunda leitura
O campo expires é false em todo plano medido que vendemos, porque nossos dados não expiram. Se você está montando uma comparação de preços, esse campo muda a conta mais do que o preço muda.
O campo throttle_mbps é null nos planos medidos e 1 nos passes diários ilimitados, onde a velocidade cheia vai até 2 GB por dia e depois cai para 1 Mbps.
Colocamos o número da redução na API pelo mesmo motivo que o imprimimos no botão de compra. Um número que o viajante descobre depois vira chamado de suporte.
Pedidos
Um POST compra um plano e inicia o provisionamento. O cabeçalho Idempotency-Key é obrigatório, não uma sugestão.
O pior desfecho desta API é um timeout que deixa você sem saber se o viajante foi cobrado. Uma chave obrigatória elimina esse 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"
}
}Checagem de aparelho e ativação adiada
O campo imei é opcional, mas muito recomendado. Mande ele e verificamos a compatibilidade com eSIM e o bloqueio de operadora antes de cobrar.
Um celular que não consegue guardar um perfil recebe um 422 com device_not_eligible em vez de um plano vendido e um viajante irritado.
Definir activate como on_first_use faz qualquer janela de validade começar quando o viajante pousa, não quando o seu servidor nos chamou.
Status do provisionamento
O provisionamento é assíncrono, porque do outro lado existe uma plataforma de operadora. Consulte este endpoint, ou fique com o webhook e esqueça a consulta em laço.
A mediana de queued até activated fica abaixo de 90 segundos. Qualquer coisa ainda em queued depois de 10 minutos é falha, e o estorno é automático.
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
Dois eventos, e os dois mudam o que o viajante precisa ouvir. Aponte para qualquer endpoint HTTPS, configurado separadamente em cada ambiente.
Eventos de webhook
| Evento | Dispara quando | O que fazer com ele |
|---|---|---|
| esim.activated | O perfil se conecta a uma rede pela primeira vez. | Avise o viajante de que ele está online. É neste momento que a compra fica real para ele. |
| esim.depleted | O plano cruza um limite de consumo, em 80 por cento e de novo em 100 por cento. | Ofereça uma recarga antes de ele ficar na mão, não depois. |
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"
}
}Verificando uma entrega
Calcule HMAC SHA-256 sobre o timestamp, um ponto final e o corpo cru da requisição, usando o segredo do seu endpoint. Compare em tempo constante.
Rejeite qualquer coisa com timestamp de mais de 5 minutos, o que barra um replay. As entregas são pelo menos uma vez e são repetidas 8 vezes ao longo de 24 horas, então indexe seu handler pelo id do evento.
Códigos de erro
| HTTP | Código | O que significa | O que fazer |
|---|---|---|---|
| 400 | invalid_request | Falta um campo ou ele tem o tipo errado. O corpo diz qual campo é. | Corrija a requisição. Repetir não ajuda. |
| 401 | invalid_token | O token bearer está errado, foi revogado ou é do outro ambiente. | Confira se você não está mandando chave de sandbox para o host de produção. |
| 402 | insufficient_balance | O saldo da sua conta não cobre o pedido. | Recarregue e repita com a mesma chave de idempotência. |
| 404 | not_found | Não existe objeto com esse id neste ambiente. | Os id de sandbox e os de produção não são intercambiáveis. |
| 409 | idempotency_conflict | A mesma chave de idempotência foi reusada com um corpo diferente. | Use uma chave nova, ou reenvie o corpo original byte a byte. |
| 422 | device_not_eligible | O aparelho não aceita eSIM, ou está travado na operadora. | Faça a checagem do aparelho antes de cobrar. |
| 429 | rate_limited | Você passou do balde daquele endpoint. | Recue usando o atraso de nova tentativa do cabeçalho. Não fique em laço. |
| 500 | internal_error | Culpa nossa. Já está no nosso alerta. | Repita com a mesma chave de idempotência depois de 2 segundos. |
| 503 | provider_unavailable | Uma plataforma de operadora acima na cadeia está fora do ar. | Repita por até 10 minutos. Fazemos failover automático onde existe uma segunda operadora. |
Todo corpo de erro traz um código, uma mensagem legível por gente e um id de requisição. Cite o id de requisição ao suporte e você pula as quatro primeiras perguntas.
Sandbox contra produção
Mesmo host, mesmos caminhos, mesmos formatos de resposta. Uma chave com prefixo sk_test nunca toca em dinheiro e nunca cria perfil de operadora.
Os jobs de provisionamento percorrem a máquina de estados inteira em cerca de 4 segundos, então seus testes não dormem 90 segundos cada um.
Peça o plano de id plan_test_fail para receber um job falho com motivo. Peça plan_test_slow para receber um que fica em provisioning por 11 minutos, e assim você exercita o caminho de timeout.
As entregas de webhook também disparam no sandbox, contra uma URL que você define por ambiente.
Se você preferir não construir nada
O programa de afiliados paga sobre pedidos indicados sem nenhuma integração, que é a resposta certa para a maioria dos sites de conteúdo.
O endpoint MCP entrega nosso conjunto de dados de cobertura e o índice de preços a um assistente de IA com uma linha de configuração e nenhum código.
Os planos que você venderia, os dados de velocidade medida por trás do catálogo e a lista completa de países estão publicados abertamente neste site.
Perguntas que desenvolvedores fazem
Consigo uma chave de API hoje?
Quanto tempo leva a aprovação?
Qual é a diferença entre sandbox e produção?
Preciso de chaves de idempotência?
Quais são os limites de taxa?
Os webhooks são confiáveis?
Existe SDK?
O que acontece quando o provisionamento falha?
Comece pelo sandbox, ou pule o código de vez
As credenciais de sandbox chegam no mesmo dia útil. Se você preferir não escrever uma integração, nem o programa de afiliados nem o endpoint MCP exigem construir nada.