Watchdog API

Slot-Kapazität, benannte Empfänger, Alarme und signierte Webhooks.

Zuletzt aktualisiert: 30.09.2026

Kapazität kaufen, dann Watches erstellen

Nutze GET /api/x402/pricing und den Abo-Quote-Endpunkt für aktuelle Produkte, Watch-Typen, Signale, Standardwerte und Rabatte. Bezahlte Typen verbrauchen ihre jeweilige Produktkapazität; kostenlose Typen haben Limits je Wallet. Pausierte Watches zählen weiterhin. Kaufe mit spend; erstelle oder ändere Watches mit write. Das Erstellen einer Watch ist kein Abo-Kauf.

curl 'https://ftso.app/api/x402/subscriptions/quote?product=watchdog-slot&quantity=5&periods=12' \
  -H 'authorization: Bearer fbx_READ_TOKEN'
curl -X POST 'https://ftso.app/api/x402/subscriptions' \
  -H 'authorization: Bearer fbx_SPEND_TOKEN' \
  -H 'content-type: application/json' \
  -H 'Idempotency-Key: purchase_20260930_001' \
  -d '{"product":"watchdog-slot","quantity":5,"periods":12,"autoRenew":true}'

Auto-Renew wiederholt gekaufte Menge und Laufzeit zum aktuellen Preis. Das Einschalten erfordert spend, das Abschalten write. Vor einem Kauf kann die Zustimmung zu bestehenden Bedingungen nötig sein. Ein einmaliger Test ist unter POST /api/x402/subscriptions/trial verfügbar, sofern die Voraussetzungen erfüllt sind.

Watch erstellen und bearbeiten

curl -X POST 'https://ftso.app/api/x402/watches' \
  -H 'authorization: Bearer fbx_WRITE_TOKEN' \
  -H 'content-type: application/json' \
  -H 'Idempotency-Key: watch_20260930_001' \
  -d '{"type":"feed-move","label":"FLR swing",
       "config":{"chainId":14,"symbol":"FLR","percent":2.5,"windowMinutes":60},
       "signals":{"price-move":{"enabled":true}}}'

curl -X PATCH 'https://ftso.app/api/x402/watches/7' \
  -H 'authorization: Bearer fbx_WRITE_TOKEN' -H 'content-type: application/json' \
  -d '{"action":"pause"}'

PATCH unterstützt config, signals, routing, label, cooldownSeconds, messageTemplate, webhookUrl, rotateSecret und pause-/resume-Aktionen. Config-Änderungen setzen den Monitoring-Zustand zurück. Signal-Overrides werden feldweise zusammengeführt; null setzt einen Override zurück. signalsMode: replace ersetzt Overrides; ein leeres signals-Objekt mit dem Standard merge verändert nichts. Secret-Rotation und erste Webhook-Einrichtung geben ein Secret zurück: Speichere es sicher. Ein Replay desselben Schlüssels kann es während der 24-stündigen Idempotency-Aufbewahrung erneut liefern.

Empfänger und Routing

Benannte Empfänger können von mehreren Watches verwendet werden. Maschinen-Clients können Eingabekanäle erstellen; verknüpfte Kanäle folgen ihren eigenen Prüfungs- und Berechtigungsregeln. Discord-Verknüpfung bleibt sessiongebunden. Ausstehende Empfänger dürfen weder Alarme noch Tests erhalten. Alte Kanal-Endpunkte adressieren den ältesten Empfänger ihres Typs; nutze Empfänger-IDs für genaue Steuerung. Webhook-URLs werden beim Lesen maskiert: Ein ausgelassenes Ziel erhält es, eine bewusste Entfernung mit leerem Wert/null löscht es. Schreibe keine Anzeigemaske als neue URL zurück.

curl -X POST 'https://ftso.app/api/x402/recipients' \
  -H 'authorization: Bearer fbx_WRITE_TOKEN' -H 'content-type: application/json' \
  -d '{"name":"Ops","type":"webhook","target":{"url":"https://example.com/hooks/ftsobest"}}'
# Use the returned recipient id in routing.
curl -X PATCH 'https://ftso.app/api/x402/watches/7' \
  -H 'authorization: Bearer fbx_WRITE_TOKEN' -H 'content-type: application/json' \
  -d '{"routing":{"default":["inapp",12],"groups":{"alerts":[12]}}}'

Eine Signalgruppen-Route überschreibt den Watch-Standard; Standardempfänger sind die Rückfallebene. Konto-/Systemereignisse erreichen immer die Glocke und ausdrücklich gesetzte Standardempfänger. Die Glockenzustellung von Signalalarmen kann abgeschaltet werden. Ruhezeiten halten persönliche Kanäle zurück; Gruppen, Webhooks und Glocke liefern weiter. Ein Watch-Cooldown unterdrückt Wiederholungen desselben Ereignisses, nicht ein anderes Ereignis oder seine Erholung.

Nachrichtenvorschau und Ruhezeiten

curl -X PUT 'https://ftso.app/api/x402/settings' \
  -H 'authorization: Bearer fbx_WRITE_TOKEN' -H 'content-type: application/json' \
  -d '{"quietHours":{"start":"22:00","end":"07:00","timezone":"Europe/Berlin"},"notificationLocale":"de"}'
curl -X POST 'https://ftso.app/api/x402/message-preview' \
  -H 'authorization: Bearer fbx_READ_TOKEN' -H 'content-type: application/json' \
  -d '{"watchId":7,"notificationLocale":"de","scope":"wallet","messageTemplate":null}'

Vorlagen enthalten title, body und appendDetails. Watch-Vorlagen überschreiben Wallet-Vorlagen; null stellt den Standard wieder her. Platzhalter sind reine Textersetzungen, kein ausführbares Markup. Zulässige Platzhalter: {watch}, {type}, {title}, {severity}, {emoji}, {network}, {identity}, {round}, {epoch}, {details}, {time}, {link}. Eine Vorschau stellt keine Nachricht zu.

Alarm-Verlauf

curl 'https://ftso.app/api/x402/alerts?page=0&pageSize=20&watchId=7&severity=warning&delivery=failed&sort=time&direction=desc' \
  -H 'authorization: Bearer fbx_READ_TOKEN'
curl 'https://ftso.app/api/x402/alerts/export?watchId=7' \
  -H 'authorization: Bearer fbx_READ_TOKEN'

Der Verlauf verwendet nullbasierte Seiten mit pageSize bis 100. Der Export verwendet dieselben Filter und liefert höchstens 5.000 CSV-Zeilen. Watch- und Kontolisten verwenden stattdessen limit/cursor. Fremde Watch- oder Alarm-IDs liefern 404. Das Löschen einer Watch entfernt nicht ihren Alarm-Verlauf. Das Löschen von Alarmen ist eine ausdrückliche write-Operation; Auswahl und maxId begrenzen das beabsichtigte Verlaufsfenster.

Webhook-Payload und Prüfung

Payload v2 ergänzt die v1-Form um payloadVersion: 2, signal und group. Technische Felder bleiben unverändert, auch wenn gerenderte Texte übersetzt werden. Lies das v2-Schema und akzeptiere zusätzliche Felder in Ereignisdaten. Dedupliziere anhand deliveryId. Die erzeugte Ereignisliste unten umfasst katalogisierte Signal- und Recovery-Ereignisse; Kontonachrichten und Kanaltests sind separate Systemereignisse.

Dieses gekürzte v2-Beispiel zeigt die Hülle; data enthält typspezifische Fakten. Das v1-Schema verwendet dieselben grundlegenden Felder für Zustellung, Alarm, Watch, Ereignis, severity, firedAt und data ohne die drei v2-Ergänzungen. rendered und renderedMessage können übersetzte Anzeigetexte liefern; nutze deliveryId zur Deduplizierung.

{
  "payloadVersion": 2,
  "deliveryId": "unique-delivery-id",
  "alertId": 41,
  "watchId": 7,
  "label": "FLR swing",
  "type": "feed-move",
  "event": "feed-move.threshold",
  "signal": "price-move",
  "group": "alerts",
  "severity": "warning",
  "firedAt": "2026-09-30T12:00:00.000Z",
  "data": {}
}
import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody is the exact request body Buffer, not parsed/re-serialized JSON.
const timestamp = req.headers["x-watchdog-timestamp"];
const signature = req.headers["x-watchdog-signature"];
if (
  typeof timestamp !== "string" ||
  !/^\d+$/.test(timestamp) ||
  typeof signature !== "string" ||
  Math.abs(Date.now() / 1000 - Number(timestamp)) > 300
)
  throw new Error("invalid");
const expected = Buffer.from(
  "sha256=" +
    createHmac("sha256", secret)
      .update(timestamp + ".")
      .update(rawBody)
      .digest("hex"),
);
const received = Buffer.from(signature);
if (received.length !== expected.length || !timingSafeEqual(expected, received))
  throw new Error("invalid");

Die Prüfung verwendet X-Watchdog-Signature und X-Watchdog-Timestamp; X-Watchdog-Payload-Version bezeichnet den Payload-Vertrag. Antworte erst nach Prüfung von Signatur und Zeitnähe. Bestätige doppelte deliveryIds, ohne Wirkungen zu wiederholen. Die Watchdog-Nutzerdokumentation beschreibt den übergeordneten Ablauf.

Webhook-Ereignisse

  • credits.low-balance
  • credits.recovered
  • feed-move.threshold
  • fsp.balance-low
  • fsp.balance-low.recovered
  • fsp.fast-updates
  • fsp.fast-updates.recovered
  • fsp.fdc-bitvote
  • fsp.fdc-bitvote-length
  • fsp.fdc-bitvote-length.recovered
  • fsp.fdc-bitvote.recovered
  • fsp.fdc-consensus
  • fsp.fdc-consensus.recovered
  • fsp.fdc-reveal-offence
  • fsp.fdc-reveal-offence.recovered
  • fsp.fdc-signature
  • fsp.fdc-signature.recovered
  • fsp.fdc-submit1
  • fsp.fdc-submit1.recovered
  • fsp.ftso-commit
  • fsp.ftso-commit.recovered
  • fsp.ftso-reveal
  • fsp.ftso-reveal.recovered
  • fsp.ftso-signature
  • fsp.ftso-signature.recovered
  • fsp.mc-anchor
  • fsp.mc-anchor.recovered
  • fsp.mc-fdc
  • fsp.mc-fdc.recovered
  • fsp.mc-uptime
  • fsp.mc-uptime.recovered
  • fsp.monitoring
  • fsp.monitoring.recovered
  • fsp.not-in-policy
  • fsp.not-in-policy.recovered
  • fsp.registration
  • fsp.registration.recovered
  • fsp.reveal-offence
  • fsp.reveal-offence.recovered
  • fsp.rewards-unclaimed
  • fsp.rewards-unclaimed.recovered
  • fsp.signature-grace
  • fsp.signature-grace.recovered
  • fsp.signature-mismatch
  • fsp.signature-mismatch.recovered
  • fsp.tx-failed
  • fsp.tx-failed.recovered
  • fsp.validator-not-listed
  • fsp.validator-not-listed.recovered
  • provider.eligibility-lost
  • provider.recovered
  • provider.unregistered
  • signing.done
  • signing.missed
  • signing.rewards-open
  • signing.rewards-reminder
  • signing.uptime-open
  • wallet-balance.moved