Developer
Empat endpoint, dua webhook, tanpa kejutan.
Semua yang bisa dilakukan toko, bisa dilakukan produk kamu. Seluruh permukaannya muat dalam satu halaman.
Kenapa API ini ada
Koneksi seharusnya disiapkan pada saat pelancong memesan, di dalam produk kamu sendiri. Bukan sesuatu yang baru dia sadari di bandara.
Platform pemesanan bisa menempelkan kuota ke sebuah rencana perjalanan. Produsen perangkat bisa mengaktifkan paket saat penyiapan awal. Perkakas tim bisa menyerahkan kuota ke karyawan baru bersamaan dengan laptopnya.
Ketiganya sama saja: empat panggilan dan satu webhook. Tidak ada portal mitra yang harus dimasuki dan tidak ada CSV yang harus diunggah.
Autentikasi
Kirim kuncimu sebagai token bearer di setiap permintaan. Kunci berawalan sk_test untuk sandbox dan sk_live untuk produksi.
Kunci yang tertempel di lingkungan yang salah gagal dengan 401, bukan diam-diam menghabiskan uang. Kunci punya cakupan, jadi kunci baca saja tidak bisa membuat pesanan dan kunci untuk satu akun tim tidak bisa melihat akun lain.
Rotasi kapan saja dari konsol. Kunci lama tetap jalan selama 24 jam, jadi kamu tidak pernah dipaksa berganti serentak dalam satu hari.
curl https://api.orbislo.com/v1/catalog?country=jp \
-H "Authorization: Bearer sk_live_9f2c..." \
-H "Orbislo-Version: 2026-08-01"Soal header versi
Header versi sifatnya opsional dan mengunci bentuk respons ke rilis bertanggal. Tanpa header itu kamu dapat versi saat kuncimu dibuat, dan versi itu tidak pernah berubah di bawah kakimu.
Kami menambah kolom tanpa pemberitahuan. Kami tidak pernah menghapus kolom atau mengubah tipenya di dalam satu versi.
4
endpoint di seluruh API, ditambah 2 peristiwa webhook
90 dtk
waktu median dari pesanan berhasil sampai profil aktif
24 jam
rentang saat kunci idempotensi yang diulang mengembalikan respons aslinya
Daftar endpoint
| Metode | Path | Fungsinya | Batas permintaan |
|---|---|---|---|
| GET | /v1/catalog | Setiap paket yang kami jual, lengkap dengan harga, kuota, masa berlaku, dan negara yang dicakup. | 600 per menit |
| POST | /v1/orders | Membeli paket dan mengembalikan pesanan dengan job provisioning yang menempel. | 60 per menit |
| GET | /v1/provisioning/:id | Status satu job provisioning, dari queued sampai activated atau failed. | 600 per menit |
| GET | /v1/usage/:esim_id | Byte terpakai, byte tersisa, dan operator tempat satu eSIM menempel. | 300 per menit |
Batas dihitung per kunci dalam jendela bergerak. Setiap respons membawa sisa jatah dan waktu reset, dan 429 membawa jeda coba ulang dalam detik. Kalau kebutuhanmu memang perlu jatah lebih besar, minta saja, karena menaikkannya adalah perubahan konfigurasi, bukan negosiasi.
Katalog
Katalog adalah acuan untuk apa saja yang ada dan berapa harganya. Isinya mencakup 145 destinasi yang aktif hari ini.
Saring berdasarkan negara, wilayah, atau keluarga paket. Harga dikembalikan dalam satuan terkecil, jadi bilangan pecahan tidak pernah sampai ke kode penagihanmu.
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
}Dua kolom yang layak dibaca dua kali
Kolom expires bernilai false di semua paket berbasis kuota yang kami jual, karena data kami tidak hangus. Kalau kamu sedang membuat pembanding harga, kolom itu mengubah hitungan lebih besar daripada harganya.
Kolom throttle_mbps bernilai null di paket berbasis kuota dan 1 di paket harian tanpa batas, di mana kecepatan penuh berlaku sampai 2 GB per hari lalu turun ke 1 Mbps.
Kami menaruh angka pembatasan itu di API dengan alasan yang sama seperti kami mencetaknya di tombol beli. Angka yang baru diketahui pelancong belakangan akan jadi tiket dukungan.
Pesanan
Satu POST membeli paket dan memulai provisioning. Header Idempotency-Key wajib, bukan sekadar saran.
Hasil terburuk di API ini adalah timeout yang membuatmu tidak tahu apakah pelancong sudah ditagih. Kunci yang wajib menghapus kondisi itu sepenuhnya.
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"
}
}Cek perangkat dan aktivasi tertunda
Kolom imei bersifat opsional tapi sangat kami sarankan. Kirim saja, dan kami cek dukungan eSIM serta kunci operator sebelum uangnya diambil.
Ponsel yang tidak bisa menyimpan profil akan menerima 422 dengan device_not_eligible, bukan paket terjual dan pelancong yang marah.
Menyetel activate ke on_first_use membuat masa berlaku dimulai saat pelancong mendarat, bukan saat servermu memanggil kami.
Status provisioning
Provisioning berjalan asinkron, karena di ujung sana ada platform operator. Cek endpoint ini, atau ambil webhook-nya dan lupakan pengecekan berulang.
Median dari queued sampai activated di bawah 90 detik. Apa pun yang masih queued setelah 10 menit dianggap gagal, dan uangnya kembali otomatis.
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
}Webhook
Dua peristiwa, dan keduanya mengubah apa yang perlu disampaikan ke pelancong. Arahkan ke endpoint HTTPS mana pun, disetel terpisah per lingkungan.
Peristiwa webhook
| Peristiwa | Terpicu saat | Apa yang harus dilakukan |
|---|---|---|
| esim.activated | Profil menempel ke jaringan untuk pertama kalinya. | Beri tahu pelancong bahwa dia sudah tersambung. Di titik inilah pembelian terasa nyata baginya. |
| esim.depleted | Paket melewati ambang pemakaian, di 80 persen lalu di 100 persen. | Tawarkan isi ulang sebelum dia kehabisan, bukan sesudahnya. |
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"
}
}Memverifikasi sebuah kiriman
Hitung HMAC SHA-256 atas stempel waktu, sebuah titik, dan badan permintaan mentah, memakai secret endpoint kamu. Bandingkan dengan waktu konstan.
Tolak apa pun yang stempel waktunya lebih tua dari 5 menit, itu menghentikan serangan ulang. Kiriman dijamin minimal sekali dan diulang 8 kali sepanjang 24 jam, jadi kunci handler kamu pada id peristiwa.
Kode error
| HTTP | Kode | Artinya | Apa yang harus dilakukan |
|---|---|---|---|
| 400 | invalid_request | Ada kolom yang hilang atau tipenya salah. Badan respons menyebut kolomnya. | Perbaiki permintaannya. Mengulang tidak akan menolong. |
| 401 | invalid_token | Token bearer salah, sudah dicabut, atau dari lingkungan yang lain. | Pastikan kamu tidak mengirim kunci sandbox ke host produksi. |
| 402 | insufficient_balance | Saldo akunmu tidak cukup untuk pesanan itu. | Isi saldo, lalu ulangi dengan kunci idempotensi yang sama. |
| 404 | not_found | Tidak ada objek dengan id itu di lingkungan ini. | Id sandbox dan id produksi tidak bisa saling dipakai. |
| 409 | idempotency_conflict | Kunci idempotensi yang sama dipakai ulang dengan badan yang berbeda. | Pakai kunci baru, atau kirim ulang badan aslinya persis byte demi byte. |
| 422 | device_not_eligible | Perangkatnya tidak mendukung eSIM, atau terkunci operator. | Jalankan cek perangkat sebelum kamu mengambil uangnya. |
| 429 | rate_limited | Kamu melewati jatah untuk endpoint itu. | Mundur sesuai jeda coba ulang di header. Jangan menghantam terus. |
| 500 | internal_error | Salah kami. Sudah masuk ke sistem peringatan kami. | Ulangi dengan kunci idempotensi yang sama setelah 2 detik. |
| 503 | provider_unavailable | Platform operator di hulu sedang mati. | Ulangi sampai 10 menit. Kami pindah otomatis di tempat yang punya operator kedua. |
Setiap badan error membawa kode, pesan yang bisa dibaca manusia, dan id permintaan. Sebutkan id permintaan ke dukungan, dan kamu melewati empat pertanyaan pertama.
Sandbox dibanding produksi
Host sama, path sama, bentuk respons sama. Kunci berawalan sk_test tidak pernah menyentuh uang dan tidak pernah membuat profil operator.
Job provisioning melewati seluruh mesin status dalam sekitar 4 detik, jadi tesmu tidak perlu tidur 90 detik untuk tiap kasus.
Pesan paket dengan id plan_test_fail untuk mendapat job gagal beserta alasannya. Pesan plan_test_slow untuk mendapat job yang bertahan di provisioning selama 11 menit, supaya kamu bisa menguji jalur timeout.
Kiriman webhook juga jalan di sandbox, ke URL yang kamu setel per lingkungan.
Kalau kamu lebih suka tidak membangun apa pun
Jalur afiliasi membayar atas pesanan rujukan tanpa integrasi sama sekali, dan itu jawaban yang tepat untuk kebanyakan situs konten.
Endpoint MCP membuka kumpulan data cakupan dan indeks harga kami ke asisten AI dengan satu baris konfigurasi dan tanpa kode.
Paket yang akan kamu jual, data kecepatan terukur di balik katalog, dan daftar negara lengkap, semuanya terbit terbuka di situs ini.
Pertanyaan yang sering diajukan developer
Bisakah saya dapat kunci API hari ini?
Berapa lama proses persetujuannya?
Apa bedanya sandbox dan produksi?
Apakah saya perlu kunci idempotensi?
Berapa batas permintaannya?
Seberapa andal webhook-nya?
Ada SDK?
Apa yang terjadi kalau provisioning gagal?
Mulai dari sandbox, atau lewati kodenya sama sekali
Kredensial sandbox datang di hari kerja yang sama. Kalau kamu lebih suka tidak menulis integrasi, jalur afiliasi dan endpoint MCP sama-sama tidak menuntut apa pun untuk dibangun.