gtfs-edge poller GET /status[?date=YYYY-MM-DD] — all agencies (stats for date, default today) GET /status/:agency/:feed — one feed (also accepts ?date=) GET /healthz — 200 ok / 503 + unhealthy count and reason codes (admin token: per-feed detail) GET /compaction — per-feed compaction status GET /marts — per-agency newest marts service_date POST /start/:agency/:feed — set first alarm POST /poke/:agency/:feed — force immediate poll POST /stop/:agency/:feed — clear alarm POST /compact/:agency/:feed — force a catch-up compaction POST /preflight — check a candidate feed (JSON body: agencyId, timezone, rt.url[, rt.auth], static.url[, advanceDelayMs]) POST /preflight/:agency[?advanceDelayMs=N] — re-check a registered agency POST /rollup — run daily marts for all agencies POST /rollup/:agency[?date=YYYY-MM-DD] — daily (no date) or backfill (date) one agency GET /registry — every agency record (+ whether each secret binding is set) GET /registry/history[?limit=N] — most recent changes, newest first GET /registry/:agency — one agency record PUT /registry/:agency — create or replace (JSON body: name, shortName, timezone, staticUrl, enabled, feeds[, version]) DELETE /registry/:agency[?version=N] — remove; its poller alarms stop, nothing in R2 is deleted POST /registry/republish — rewrite _registry.json in gtfs-marts from the current records GET /registry/pins — origin each secret binding is pinned to (set on first use) PUT /registry/pins/:binding — move a pin ({ origin }); DELETE clears it. Admin token only, not proxied by the dashboard