伺服器與 Base URL
ExpTech API 依用途分成幾組伺服器。多數組別有一個由 DNS 自動分配節點的名稱(下面標為 Auto),以及可以直接指定的節點名稱(例如 TNN-1)。各端點(endpoint)上方的下拉選單就是這裡的 host,而且只會列出有提供該端點的 host。
Base URL 只包含 https:// 與 host,端點路徑一律從 /api/... 開始接在後面,例如 https://api.core.exptech.dev/api/v2/eq/report。
資料 API
Section titled “資料 API”- Auto:
https://api.core.exptech.dev - TNN-1:
https://api.core-tnn1.exptech.dev - TYO-1:
https://api.core-tyo1.exptech.dev
提供地震報告、MCP 伺服器等資料 API。下一節的路由也在這個名稱底下,但只有 TNN-1 節點提供。
僅 TNN-1 提供的路由
Section titled “僅 TNN-1 提供的路由”- TNN-1:
https://api.core-tnn1.exptech.dev
氣象資料,以及地圖圖磚的列表(雷達、衛星、風場、QPESUMS 的 list)。
靜態檔與圖磚
Section titled “靜態檔與圖磚”- TNN-1:
https://static.core-tnn1.exptech.dev
地圖圖磚的圖檔(雷達、衛星、風場、QPESUMS),以及氣象資料中指定時間點的歷史檔。這些回應會長時間快取。這組不提供 Auto:由 DNS 分配節點的名稱可能分配到沒有這些檔案的節點,請直接使用 TNN-1。
即時串流與時間同步
Section titled “即時串流與時間同步”- Auto:
https://api.lb.exptech.dev - TPE-1:
https://api.lb-tpe1.exptech.dev - KHH-1:
https://api.lb-khh1.exptech.dev
SSE 即時串流與時間同步。TPE-1 與 KHH-1 是兩個提供相同路由的節點,任選一個都可以。
帳號、OAuth2 與公開資訊
Section titled “帳號、OAuth2 與公開資訊”- Manager:
https://manager.exptech.com.tw
- Announcement:
https://announcement.exptech.com.tw
公告。
- LB:
https://lb.exptech.dev
舊版氣象(已棄用)
Section titled “舊版氣象(已棄用)”- TNN:
https://tnn.exptech.dev
只提供已棄用的舊版氣象 API,新程式請改用氣象頁的新版 API。
節點與 Auto
Section titled “節點與 Auto”- Auto 由 DNS 分配到其中一個節點。分配方式與切換時間不保證:某個節點故障時,DNS 不一定會立刻把它移除,這段期間經由 Auto 的請求可能失敗。
- 指定節點(TNN-1、TYO-1、TPE-1、KHH-1)會固定連到同一台,但那個節點維護或故障時就無法使用。
- 資料 API 的各節點提供的路由不完全相同,見上方「僅 TNN-1 提供的路由」。
- 帳號、API Token 與配額在所有節點共用。換節點不影響驗證與用量計算。
- 資料 API、靜態檔、即時串流與底圖圖磚大多允許任何來源(
Access-Control-Allow-Origin: *),可以直接在瀏覽器呼叫。例外寫在各端點的說明中。 - 帳號、OAuth2 與公開資訊這組只允許官方網站,請從伺服器端呼叫。唯一的例外是權限清單,允許任何來源。
自行切換 Base URL
Section titled “自行切換 Base URL”只用一個 host,該 host 故障時你的服務就跟著停擺。建議在用戶端自己管理一份 host 清單,失敗時切換:
- 每組準備一份清單,依偏好排序,例如資料 API 用 Auto → TNN-1 → TYO-1。僅 TNN-1 提供的路由與靜態檔只有 TNN-1,沒有可以切換的 host(見架構與異地備援)。
- 每個請求設定逾時(例如 5 秒)。
- 只有連線錯誤、逾時或 5xx 才換下一個 host。
- 400、401、403、429 是參數或帳號的問題,換到哪個節點結果都一樣,不要換 host 重試。404 只有在路由依節點而異時(上面「僅 TNN-1 提供的路由」)才值得換 host。
- 記住最後一次成功的 host,之後的請求先用它;可以每隔一段時間(例如 10 分鐘)再回頭試第一順位。
- 不要同時對所有 host 發出同一個請求,這只會增加負載。
const CORE_HOSTS = [ "https://api.core.exptech.dev", "https://api.core-tnn1.exptech.dev", "https://api.core-tyo1.exptech.dev",];
let preferred = 0;
export async function fetchWithFailover(path, init = {}, hosts = CORE_HOSTS) { let lastError; for (let i = 0; i < hosts.length; i++) { const index = (preferred + i) % hosts.length; try { const res = await fetch(hosts[index] + path, { ...init, signal: AbortSignal.timeout(5000), }); if (res.status >= 500) { lastError = new Error(`HTTP ${res.status} from ${hosts[index]}`); continue; // 伺服器錯誤:換下一個 host } preferred = index; return res; // 2xx、3xx、4xx 交給呼叫端處理 } catch (err) { lastError = err; // 連線錯誤或逾時:換下一個 host } } throw lastError;}
const res = await fetchWithFailover("/api/v2/eq/report?limit=5");const reports = await res.json();