跳到主要内容

功能

等待提醒

当某个地点的实时等待降到你的阈值以下时,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 帮助我们改进网站。详见隐私政策和条款。