Published 2026-09-01. Binding specification, frozen after publication.
Watchdog watches an x402 endpoint and sends a signed alert the moment a measurable observable changes: it went unreachable, its payability verdict degraded, the declared payTo / networks / asset in its 402 changed, its 402 became self-inconsistent, or it dropped from the discovery catalogue. Every alert is EIP-191 signed and verifiable offline, so it stands as evidence months later. One paid x402 call is a 30-day subscription for one endpoint at 5 dollars. Free tier: one endpoint per verified channel.
Signer 0x57fF0F084Cba33e6761503f90eEF0Da9F159350c, published in the proof manifest as the watchdog service signer. EIP-191 personal_sign over canonical JSON (json.dumps sort_keys true, compact separators, ensure_ascii), the same discipline as settle and preflight.
CHECK_INTERVAL_SECONDS = 900 (every 15 minutes).UNREACHABLE_STREAK_N = 3 (never on a single miss).RECOVERED_STREAK_M = 2.SUBSCRIPTION_DAYS = 30 (counted from verified_at).UNVERIFIED_TTL_HOURS = 72.WEBHOOK_TIMEOUT_SECONDS = 5.Every signed body carries a top-level type: one of alert, registration_receipt, daily_attestation, subscription_expired. Alerts also carry alert_type. Every body is signed except the fail-closed refusals (400, 503). Every object, including every refusal, is closed to undeclared keys.
Each alert carries, verbatim in its own limitations field, what it does NOT mean.
price_changed is reserved for v2 (amount extraction is not yet reliable enough to alert without false positives); in v1 it is neither monitored nor attested.
GET|POST /watchdog/register?endpoint=<https-url>&channel=<email|webhook-url>. Verification is mandatory before any alert and before the subscription clock starts, so the 30 days begin at verified_at. Email: a link/code; webhook: a challenge POST with a nonce the webhook must echo with a 200. Until verified: pending_verification, no alerts, no time consumed. An unverified registration is discarded silently after 72h (the one justified exception to no-silent-death; we never message a channel that never confirmed). Free: first endpoint per verified channel. Paid: 5 dollars USDC on Base via the CDP facilitator, one endpoint for 30 days. In v1 the free endpoint is fixed and cannot be swapped without a paid registration. Renewal extends the expiry with no lost days.
Wiring: /watchdog/register is an open route (free tier and validation). When a paid registration is required it returns the standard x402 402 challenge whose resource is /watchdog/register/paid; the paid registration is settled there (5 dollars USDC on Base via the CDP facilitator). The subscriber-visible behaviour is exactly as described; only the internal route split is stated so there is no doc-to-implementation gap.
https only; resolved on public DNS and rejected if it resolves to any private, loopback, link-local (including 169.254.169.254 metadata), unique-local, or reserved range; redirects never followed; response body ignored except the challenge nonce; re-resolved on every send (no cached IP) to defeat DNS rebinding.
0x57fF0F084Cba33e6761503f90eEF0Da9F159350c; recompute digest from the canonical body first.type matches the shape you expected, channel_ref equals sha256 of your own channel, and subscription_id is yours.observed_at; an alert is evidence at a point in time.Remove digest and signature, canonicalise (keys sorted, compact separators, non-ASCII escaped), sha256 must equal digest, recover the EIP-191 signature over that string; it must equal signer.
The paid /settle, /preflight, /screen, /payable endpoints are unrelated to this service. Signed report manifest at /proof/index.json.