Skip to content
Console

Servers and Base URL

The ExpTech API is split into several groups of servers by purpose. Most groups have a name that DNS assigns to a node automatically (marked Auto below), and node names you can choose directly (for example TNN-1). The host dropdown above each endpoint is this list, and it only includes hosts that serve that endpoint.

A Base URL is only https:// plus the host. The endpoint path always starts with /api/... and is appended after it, for example https://api.core.exptech.dev/api/v2/eq/report.

  • Auto: https://api.core.exptech.dev
  • TNN-1: https://api.core-tnn1.exptech.dev
  • TYO-1: https://api.core-tyo1.exptech.dev

Serves data APIs such as earthquake reports and the MCP server. The routes in the next section use this same name, but only the TNN-1 node serves them.

  • TNN-1: https://api.core-tnn1.exptech.dev

Weather data, and the lists for map tiles (the list endpoints for radar, satellite, wind, and QPESUMS).

  • TNN-1: https://static.core-tnn1.exptech.dev

Tile images for map tiles (radar, satellite, wind, and QPESUMS), and historical files for a chosen time in the weather data. These responses are cached for a long time. This group has no Auto. A name assigned by DNS might point at a node that does not have these files. Use TNN-1 directly.

  • Auto: https://api.lb.exptech.dev
  • TPE-1: https://api.lb-tpe1.exptech.dev
  • KHH-1: https://api.lb-khh1.exptech.dev

SSE real-time streams and time sync. TPE-1 and KHH-1 are two nodes that serve the same routes. Either one works.

  • Manager: https://manager.exptech.com.tw

OAuth2 and the public info API. There is only one host.

  • Announcement: https://announcement.exptech.com.tw

Announcements.

  • LB: https://lb.exptech.dev

Base map, terrain, and GSI tiles.

  • TNN: https://tnn.exptech.dev

Serves only the deprecated legacy weather API. New code should use the current API on the Weather page.

  • Auto is assigned by DNS to one of the nodes. How it is assigned, and when it switches, are not guaranteed. If a node fails, DNS may not remove it right away, and requests through Auto can fail during that time.
  • A named node (TNN-1, TYO-1, TPE-1, KHH-1) always connects to the same machine. If that node is down for maintenance or has failed, it is unavailable.
  • Data API nodes do not all serve the same routes. See “Routes served only by TNN-1” above.
  • Accounts, API Tokens, and quotas are shared by every node. Switching nodes does not change auth or how usage is counted.
  • The data API, static files, real-time streams, and base map tiles mostly allow any origin (Access-Control-Allow-Origin: *), so you can call them from a browser. Exceptions are written on each endpoint.
  • The accounts, OAuth2, and public info group allows only the official site. Call it from your server. The only exception is the permission list, which allows any origin.

If you use only one host, your service stops when that host fails. Keep a host list in the client, and switch when a request fails:

  1. For each group, keep a list ordered by preference. For example, for the data API use Auto → TNN-1 → TYO-1. Routes served only by TNN-1, and static files, have only TNN-1. There is no other host to switch to (see Current limits).
  2. Set a timeout on each request (for example, 5 seconds).
  3. Switch to the next host only on a connection error, a timeout, or a 5xx.
  4. 400, 401, 403, and 429 mean a problem with the parameters or the account. Every node returns the same result, so do not retry those by switching hosts. A 404 is worth a host switch only when the route differs by node (“Routes served only by TNN-1” above).
  5. Remember the last host that succeeded, and use it first for later requests. You can try the first choice again after a while (for example, 10 minutes).
  6. Send a request to one host at a time. Sending the same request to every host at once only adds load.
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; // server error: try the next host
}
preferred = index;
return res; // 2xx, 3xx, and 4xx are left to the caller
} catch (err) {
lastError = err; // connection error or timeout: try the next host
}
}
throw lastError;
}
const res = await fetchWithFailover("/api/v2/eq/report?limit=5");
const reports = await res.json();
  • After a disconnect, wait 3 seconds according to the server’s retry: 3000, then reconnect. After several failures in a row (for example 3), switch to the next host in the list.
  • An event: close (for example quota exceeded or token revoked) means an account or quota problem, not a server failure. Switching hosts will not fix it. See Error codes.
  • Heartbeat interval and reconnect details are in Real-time streams.