跳至主要內容

功能

等候提醒

當某個地點的即時等候降到你的門檻以下時,Waity 會呼叫你的 Webhook,代理不必一再查詢。所有方案都有,包括 Free。

運作方式

為一個地點建立提醒,設定以分鐘為單位的門檻與一個 https Webhook。每分鐘擷取資料後,Waity 會檢查剛收到新讀數的地點,當等候等於或低於門檻時,向你的 Webhook POST 一個已簽署的 JSON 本文。

提醒讀取的即時回答與 GET /v1/places/{id} 相同,因此絕不會與 API 不一致。只有在 now.usable 為 true、單位是分鐘且 now.value 不超過 under 時才會觸發。下限值(「超過 60」)、過時或暫停的數字、已關閉的地點或沒有資料,都不會觸發。

建立提醒

以 API 金鑰與 JSON 本文呼叫 POST /v1/alerts。回應即該提醒,包含其 id 與簽章密鑰。簽章密鑰只顯示一次:請將它存放在你的 Webhook 讀得到的地方。

欄位接受的值
place_id一個地點、通道或科別。機場、邊境口岸或醫院院區沒有單一的等候時間,因此其 id 會被拒絕,並附上其通道或科別的 id。
under整數分鐘,從 1 到 600。
webhook_urlWaity POST 的目標位址。僅限 https;見下方規則。
repeatfalse(預設)只觸發一次,之後提醒變為 fired。true 會在等候升到門檻加 5 分鐘以上之後再次觸發,最多每 30 分鐘一次。
expires_at選填,ISO 8601。預設為從現在起 24 小時,最長 30 天。
curl -X POST "https://api.waity.ai/v1/alerts" \
  -H "X-Api-Key: $WAITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"place_id":"pl_nvk0wkb3ps","under":30,"webhook_url":"https://example.com/waity/webhook"}'

201回應

{
  "id": "al_3k9qx2m7t4p8w1za",
  "place": {
    "id": "pl_nvk0wkb3ps",
    "name": "Ysleta Passenger Vehicles, Standard",
    "category": "border"
  },
  "under": 30,
  "unit": "min",
  "repeat": false,
  "webhook_url": "https://example.com/waity/webhook",
  "status": "armed",
  "created_at": "2026-10-31T19:02:11Z",
  "expires_at": "2026-11-01T19:02:11Z",

Webhook URL 規則

為了避免提醒到達私人網路,Waity 會拒絕符合以下情況的 Webhook URL:

Waity 自己不解析任何名稱,也從不跟隨重新導向:3xx 回應算作傳送失敗。

列出、讀取與刪除

GET /v1/alerts 回傳你的提醒,最新的在前,附帶狀態與最近一次傳送。同一帳戶的金鑰共用一個清單;沒有帳戶的金鑰有自己的清單。GET /v1/alerts/{id} 讀取一個提醒,DELETE /v1/alerts/{id} 刪除它並停止其傳送。

curl

curl "https://api.waity.ai/v1/alerts" \
  -H "X-Api-Key: $WAITY_API_KEY"

curl -X DELETE "https://api.waity.ai/v1/alerts/al_3k9qx2m7t4p8w1za" \
  -H "X-Api-Key: $WAITY_API_KEY"
狀態接受的值
armed正在等待等候時間降到門檻以下。
fired已觸發的一次性提醒。
expired已過 expires_at 且未觸發。
failing最近一次傳送嘗試失敗;見 last_delivery。只要還有剩餘次數,就會繼續重試。
disabled連續 20 次傳送嘗試失敗。Webhook 恢復正常後,請建立新的提醒。

Webhook

每次傳送都是一個帶 JSON 本文的 POST。先向使用者讀出 warnings,再讀 summary。now.value 在 now.usable_until 之前有效;之後請重新請求 GET /v1/places/{id}。

POST

{
  "type": "wait.under",
  "alert": {
    "id": "al_3k9qx2m7t4p8w1za",
    "under": 30
  },
  "place": {
    "id": "pl_nvk0wkb3ps",
    "name": "Ysleta Passenger Vehicles, Standard",
    "category": "border",
    "url": "https://waity.ai/places/ysleta-passenger-vehicles-standard-kb3ps"
  },
  "now": {
    "value": 25,
    "unit": "min",
    "measured_at": "2026-10-31T13:58:00-06:00",
    "usable_until": "2026-10-31T15:28:00-06:00",
    "basis": "estimate"
  },
  "summary": "About 25 min to enter the US, estimated by the border agency, updated 2 min ago.",
  "warnings": [],
  "links": {
    "place": "https://api.waity.ai/v1/places/pl_nvk0wkb3ps",
    "page": "https://waity.ai/places/ysleta-passenger-vehicles-standard-kb3ps",
    "alert": "https://api.waity.ai/v1/alerts/al_3k9qx2m7t4p8w1za",
    "docs": "https://waity.ai/docs/alerts"
  }
}

每個請求都帶有以下標頭:

驗證簽章

在解析 JSON 之前,以原始位元組檢查簽章,用固定時間比較,並拒絕超過 5 分鐘的 t。

import crypto from "node:crypto";
import express from "express";

const app = express();
const secret = process.env.WAITY_ALERT_SECRET; // whsec_…

// The raw body: the signature covers the exact bytes Waity sent.
app.post("/waity/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const parts = Object.fromEntries(
    (req.get("Waity-Signature") ?? "").split(",").map((p) => p.split("=", 2)),
  );
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${req.body}`)
    .digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) <= 300;
  const ok =
    fresh &&
    typeof parts.v1 === "string" &&
    parts.v1.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
  if (!ok) return res.status(400).end();

  const event = JSON.parse(req.body);
  // Read event.warnings first, then event.summary.
  res.status(204).end();
});

app.listen(3000);

重試

請在 10 秒內以任何 2xx 回應。其他任何回應都算一次失敗嘗試,約 1, 5, 25 分鐘後重試。連續 20 次嘗試失敗後,提醒會被停用。

各方案的限制

每個方案同時可保有一定數量的有效提醒。再多一個會回傳 409 alert_limit,訊息中會寫明你方案的上限。每個提醒請求計為一次呼叫;傳送從不計算在內。沒有帳戶的金鑰按 Free 計算。

方案有效提醒
Free1
Plus10
Pro100
Team1,000

急診室與緊急照護

對於急診室與緊急照護的提醒,每次傳送的 warnings[0] 都是 911 提示,只說一次,與每個急診室回答一樣。

相關內容

接下來 依歷史說明等候預計何時下降。解讀回應 說明了每個欄位,所有欄位見 API 參考。

必要 Cookie 讓網站正常運作,選用的分析 Cookie 協助我們改善網站。詳見隱私權政策與條款。