開發者

四個端點,兩個 webhook,沒有意外。

商店做得到的事,你的產品也做得到。整個介面一頁就寫得完。

在 api.orbislo.com 上以 HTTPS 提供 REST,使用 bearer 驗證,進出都是 JSON。列出目錄、建立訂單、查詢開通作業、讀取用量。兩個 webhook 會告訴你 eSIM 何時啟用、何時快用完。沙箱憑證同一個工作天就會寄到。正式環境目前採申請制,我們在下面說明原因,而不是把申請表包裝成流量限制。

這個 API 為什麼存在

旅客一按下預訂,連線就該在你自己的產品裡準備好。不該是他到了機場才發現的事。

訂房平台可以把數據掛在行程上。裝置廠商可以在開機設定時就啟用方案。團隊工具可以把數據和筆電一起交給剛報到的同事。

這三種情境都只是四次呼叫加一個 webhook。沒有要登入的夥伴後台,也沒有要上傳的 CSV。

1
點一下安裝
2
在手機的視窗中確認
3
開啟數據漫遊
不用 QR code,不用相機,不用第二台裝置。所有訂單的設定時間中位數是 41 秒。
在你的 POST 和旅客手機有訊號之間,發生了哪些事。

驗證

每一次請求都把金鑰當成 bearer token 送出。金鑰前綴在沙箱是 sk_test,在正式環境是 sk_live。

貼錯環境的金鑰會回 401 而不是默默花錢。金鑰有權限範圍,唯讀金鑰不能建立訂單,為某個團隊帳號發出的金鑰也看不到另一個帳號。

你隨時可以在主控台輪替金鑰。舊金鑰還會運作 24 小時,所以永遠不會被逼著在同一天全面切換。

curl https://api.orbislo.com/v1/catalog?country=jp \
  -H "Authorization: Bearer sk_live_9f2c..." \
  -H "Orbislo-Version: 2026-08-01"

關於版本標頭

版本標頭是選填的,用來把回應格式釘在某個有日期的版本上。不帶的話,就會使用你建立金鑰當下的版本,而那個版本不會在你腳下改變。

我們會不預告就新增欄位。我們絕不在同一個版本裡移除欄位或更動它的型別。

4

整個 API 的端點數,另外還有 2 個 webhook 事件

90 秒

從訂單成立到設定檔啟用的時間中位數

24 小時

重送同一把冪等鍵仍會回傳原始回應的時間長度

端點一覽

方法路徑用途流量限制
GET/v1/catalog我們販售的每一個方案,含價格、數據量、效期與涵蓋國家。每分鐘 600 次
POST/v1/orders買下一個方案,回傳一筆附帶開通作業的訂單。每分鐘 60 次
GET/v1/provisioning/:id單一開通作業的狀態,從 queued 一路到 activated 或 failed。每分鐘 600 次
GET/v1/usage/:esim_id已用位元組、剩餘位元組,以及這張 eSIM 接上的電信商。每分鐘 300 次

限制以金鑰為單位,採滑動視窗計算。每個回應都帶著剩餘次數與重設時間,429 則帶著以秒為單位的重試延遲。如果你的用途真的需要更大的額度,開口說一聲,因為調高額度是設定變更,不是談判。

目錄

有哪些方案、各賣多少錢,都以目錄為準。目前上線的 145 個目的地全部都在裡面。

可以依國家、依區域或依方案系列篩選。價格以最小貨幣單位回傳,浮點數不會流進你的計費程式碼。

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
}

兩個值得看兩遍的欄位

我們賣的每一個計量方案,expires 欄位都是 false,因為我們的數據不會過期。如果你在做價格比較,這個欄位對算式的影響比價格本身更大。

throttle_mbps 欄位在計量方案是 null,在無限量日票是 1。日票每天 2 GB 內是全速,之後降到 1 Mbps。

我們把這個降速數字放進 API,理由和把它印在購買按鈕上一樣。旅客事後才知道的數字,就是一張客服工單。

訂單

一次 POST 就買下方案並開始開通。Idempotency-Key 標頭是必填,不是建議。

這個 API 最糟的結果,是逾時之後你搞不清楚旅客到底有沒有被扣款。把金鑰設成必填,這個狀態就整個消失了。

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"
  }
}

裝置檢查與延後啟用

imei 欄位可填可不填,但我們強烈建議填。你送過來,我們就會在收錢之前確認 eSIM 支援度和電信鎖。

裝不下設定檔的手機會拿到帶著 device_not_eligible 的 422,而不是一份賣出去的方案和一位生氣的旅客。

把 activate 設成 on_first_use,效期就會從旅客落地那一刻開始算,而不是從你的伺服器呼叫我們那一刻。

開通狀態

另一端是電信商的平台,所以開通是非同步的。你可以輪詢這個端點,也可以收 webhook,然後完全不必輪詢。

從 queued 到 activated 的中位數低於 90 秒。過了 10 分鐘還卡在 queued 就算失敗,而且會自動退款。

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

兩個事件,兩個都會改變你該對旅客說什麼。指向任何一個 HTTPS 端點都可以,每個環境分開設定。

Webhook 事件

事件何時觸發拿到之後要做什麼
esim.activated設定檔第一次連上網路的時候。告訴旅客他已經上線了。對他來說,這一刻購買才變成真的。
esim.depleted方案用量越過門檻時,百分之 80 一次,百分之 100 再一次。在他被困住之前提供加值,不要等到之後。
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"
  }
}

驗證一次投遞

用你的端點密鑰,對時間戳、一個句點、以及原始請求內容計算 HMAC SHA-256。比對時請用固定時間的做法。

時間戳超過 5 分鐘的一律拒收,這樣可以擋掉重放。投遞至少一次,並在 24 小時內重試 8 次,所以你的處理程式要以事件 ID 去重。

錯誤碼

HTTP錯誤碼代表什麼該怎麼做
400invalid_request少了某個欄位,或型別不對。回應內容會指出是哪個欄位。修正請求。重試沒有用。
401invalid_tokenbearer token 錯誤、已撤銷,或來自另一個環境。確認你沒有把沙箱金鑰送到正式環境的主機。
402insufficient_balance你的帳戶餘額不足以支付這筆訂單。儲值之後,用同一把冪等鍵重試。
404not_found這個環境裡沒有那個 ID 的物件。沙箱的 ID 和正式環境的 ID 不能互換。
409idempotency_conflict同一把冪等鍵被拿去搭配不同的請求內容。換一把新的鍵,或是逐位元組重送原本的內容。
422device_not_eligible裝置不支援 eSIM,或是被電信商鎖住。在收錢之前先跑一次裝置檢查。
429rate_limited你超出了那個端點的額度。依照標頭裡的重試延遲退讓。不要一直重打。
500internal_error我們的問題。已經進到我們的告警了。等 2 秒後用同一把冪等鍵重試。
503provider_unavailable上游的電信商平台掛了。最多重試 10 分鐘。有第二家電信商的地方,我們會自動切換。

每一個錯誤回應都帶著錯誤碼、一句人看得懂的訊息,以及一組請求 ID。把請求 ID 給客服,就可以跳過前面四個問題。

正式環境目前採申請制,這是一個真實的限制。你沒辦法凌晨兩點註冊、三點就開始開通,這確實比自助開通的 API 差。我們不會硬把它說成什麼精心設計的導入體驗。一把正式金鑰會動用金流、會建立電信商設定檔,與其事後收拾外流金鑰的爛攤子,我們寧可先讀一段你在做什麼。沙箱憑證同一個工作天就會寄到,所以在我們讀的同時,沒有任何事會擋住你先把串接寫好。

沙箱與正式環境的差別

同一個主機、同樣的路徑、同樣的回應格式。前綴 sk_test 的金鑰不會碰到錢,也不會建立電信商設定檔。

開通作業大約 4 秒就會走完整個狀態機,所以你的測試不用每一支都睡 90 秒。

訂購方案 ID plan_test_fail,就會拿到一個附帶原因的失敗作業。訂購 plan_test_slow,就會拿到一個在 provisioning 停留 11 分鐘的作業,讓你能演練逾時的處理路徑。

webhook 在沙箱同樣會送出,送到你為該環境設定的 URL。

如果你根本不想寫程式

分潤方案完全不需要串接,就能依推薦成交的訂單付款,對大多數內容網站來說這才是正解。

MCP 端點只要一行設定、不用寫程式,就能把我們的涵蓋範圍資料集和價格指數開放給 AI 助理使用。

你會拿去賣的方案、目錄背後的實測速度資料、完整的國家清單,全部都公開在這個網站上。

開發者常問的問題

我今天就能拿到 API 金鑰嗎?
沒辦法自助開通。目前採申請制,這是刻意的選擇,不是我們忘了打開的排隊機制。每一把正式金鑰都能動用真的錢,並在真的電信商平台上建立真的設定檔,金鑰被偷走,代價是某位旅客斷網。所以我們會親自讀申請內容。沙箱則不一樣:開口要,同一個工作天就給你沙箱憑證,不用簽約,也沒有任何綁定。
審核要多久?
第一次回覆兩個工作天,整個流程通常一週以內。我們想知道你在做什麼、每個月大概預期多少次啟用、以及哪些國家。如果我們認為 API 不是你所描述那件事的正確工具,我們會直說,並改為建議分潤方案,那條路完全不用寫程式也有收入。
沙箱和正式環境差在哪裡?
沙箱用同一個主機,搭配前綴 sk_test 的金鑰。它會回傳真實的目錄、接受訂單,並把開通作業以大約 4 秒的壓縮時間軸走過 queued、provisioning 和 activated。不會有金流,也不會建立電信商設定檔。只要訂購方案 ID plan_test_fail,就能逼出任何一種失敗狀態。正式金鑰的前綴是 sk_live,那邊的一切都是真的。
我一定要用冪等鍵嗎?
建立訂單時一定要,沒帶的話端點會直接拒絕。訂單遇到網路逾時,是這個 API 裡代價最高的模糊地帶,因為盲目重試會把方案買兩次。請在 Idempotency-Key 標頭裡放一組 UUID。我們會把鍵和回應一起保存 24 小時,所以這段期間內的重試會回傳原本的結果,而不是再開一筆訂單。
流量限制是多少?
讀取類端點每分鐘 600 次,用量端點每分鐘 300 次,建立訂單每分鐘 60 次,都以金鑰為單位、採滑動視窗。每個回應都帶著剩餘次數與重設時間。429 會帶著以秒為單位的重試延遲。如果你的用途真的需要更多,開口說一聲,因為調高額度是設定變更,不是談判。
webhook 可靠嗎?
非 2xx 的回應,我們會在 24 小時內重試 8 次,採指數退避,從 10 秒開始。每一次投遞都會用你的端點密鑰,對原始內容做 HMAC SHA-256 簽章,並附上時間戳,你應該用 5 分鐘的區間去檢查,藉此擋掉重放。投遞至少一次,所以請讓你的處理程式以事件 ID 做到冪等。
有 SDK 嗎?
有一個 TypeScript 用戶端和一個 Python 用戶端,兩個都是同樣那四個端點的薄薄一層包裝。兩個都沒有藏任何東西。傳輸格式夠穩定,用 curl 當正式環境的用戶端也很合理。與其把十一個 SDK 都維護得很差,我們寧可把傳輸格式寫清楚。
開通失敗會怎樣?
作業會帶著原因轉成 failed,我們會送出載有該狀態的啟用 webhook,訂單也會在 60 秒內自動退款,不需要任何人開口。這個情境你不必自己做一套退款流程。但你確實要處理 failed 狀態,因為你的旅客還是沒有網路,應該馬上被告知。

從沙箱開始,或是完全跳過寫程式

沙箱憑證同一個工作天就會寄到。如果你不想寫串接,分潤方案和 MCP 端點都不需要你做任何東西。