Zum Inhalt springen

Funktionen

Warte-Alarme

Waity ruft deinen Webhook auf, wenn die Live-Wartezeit eines Orts unter deinen Schwellenwert fällt, damit ein Agent nicht ständig nachfragen muss. Jeder Plan enthält sie, auch Free.

So funktioniert es

Erstelle einen Alarm für einen Ort mit einem Schwellenwert in Minuten und einem https-Webhook. Nach jedem minütlichen Einlesen prüft Waity die Orte, die gerade neue Messwerte bekommen haben, und sendet per POST einen signierten JSON-Body an deinen Webhook, wenn die Wartezeit am oder unter dem Schwellenwert liegt.

Ein Alarm liest dieselbe Live-Antwort wie GET /v1/places/{id}, widerspricht der API also nie. Er löst nur aus, wenn now.usable true ist, die Einheit Minuten ist und now.value höchstens under beträgt. Eine Untergrenze („über 60“), ein veralteter oder pausierter Wert, ein geschlossener Ort oder fehlende Daten lösen nie aus.

Einen Alarm erstellen

POST /v1/alerts mit einem API-Key und einem JSON-Body. Die Antwort ist der Alarm, mit seiner ID und dem Signatur-Secret. Das Secret wird nur einmal angezeigt: Speichere es dort, wo dein Webhook es lesen kann.

FeldWas es erwartet
place_idEin Ort, eine Spur oder eine Abteilung. Ein Flughafen, ein Grenzübergang oder ein Klinikgelände hat keine einzelne Wartezeit, daher wird seine ID abgelehnt, mit den IDs seiner Spuren oder Abteilungen.
underGanze Minuten, von 1 bis 600.
webhook_urlWohin Waity per POST sendet. Nur https; siehe die Regeln unten.
repeatfalse (Standard) löst einmal aus, danach steht der Alarm auf fired. true löst erneut aus, nachdem die Wartezeit über den Schwellenwert plus 5 Minuten gestiegen ist, höchstens einmal alle 30 Minuten.
expires_atOptional, ISO 8601. Standard sind 24 Stunden ab jetzt, höchstens 30 Tage.
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"}'

201Antwort

{
  "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",

Regeln für Webhook-URLs

Damit Alarme keine privaten Netzwerke erreichen, lehnt Waity eine Webhook-URL ab, die:

Waity löst selbst keine Namen auf und folgt nie einer Weiterleitung: Eine 3xx-Antwort zählt als fehlgeschlagene Zustellung.

Auflisten, abrufen und löschen

GET /v1/alerts liefert deine Alarme, die neuesten zuerst, mit Status und letzter Zustellung. Die Keys eines Kontos teilen sich eine Liste; ein Key ohne Konto hat seine eigene. GET /v1/alerts/{id} ruft einen ab, und DELETE /v1/alerts/{id} löscht ihn und beendet seine Zustellungen.

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"
StatusWas es erwartet
armedWartet darauf, dass die Wartezeit unter den Schwellenwert fällt.
firedEin einmaliger Alarm, der ausgelöst hat.
expiredSein expires_at ist verstrichen, ohne dass er ausgelöst hat.
failingDer letzte Zustellversuch ist fehlgeschlagen; siehe last_delivery. Weitere Versuche folgen, solange welche übrig sind.
disabled20 fehlgeschlagene Zustellversuche in Folge. Erstelle einen neuen Alarm, sobald dein Webhook funktioniert.

Der Webhook

Jede Zustellung ist ein POST mit einem JSON-Body. Lies dem Nutzer zuerst warnings vor, dann summary. now.value gilt bis now.usable_until; frag danach erneut GET /v1/places/{id} ab.

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

Jede Anfrage trägt diese Header:

Die Signatur prüfen

Prüfe die Signatur über die Rohbytes, bevor du das JSON parst, vergleiche in konstanter Zeit und lehne ein t ab, das älter als 5 Minuten ist.

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);

Wiederholungen

Antworte innerhalb von 10 Sekunden mit einem beliebigen 2xx. Alles andere ist ein fehlgeschlagener Versuch, der etwa 1, 5, 25 Minuten später wiederholt wird. Nach 20 fehlgeschlagenen Versuchen in Folge wird der Alarm deaktiviert.

Limits pro Plan

Jeder Plan erlaubt eine bestimmte Zahl aktiver Alarme gleichzeitig. Einer mehr wird mit 409 alert_limit beantwortet, mit einer Meldung, die das Limit deines Plans nennt. Jede Alarm-Anfrage zählt als ein Aufruf; Zustellungen zählen nie. Ein Key ohne Konto zählt als Free.

PlanAktive Alarme
Free1
Plus10
Pro100
Team1.000

Notaufnahme und Urgent Care

Bei Alarmen für Notaufnahmen und Urgent Care ist warnings[0] jeder Zustellung die 911-Zeile, einmal gesagt, wie bei jeder Notaufnahme-Antwort.

Siehe auch

Später sagt anhand des Verlaufs, wann eine Wartezeit fallen sollte. Eine Antwort lesen erklärt jedes Feld, und jedes Feld steht in der API-Referenz.

Notwendige Cookies halten die Website am Laufen. Optionale Analyse-Cookies helfen uns, sie zu verbessern. Siehe Datenschutzerklärung und AGB.