API reference
KYE Protocol™ Status API
7 operations · status.yaml
Public status surface for status.kyeprotocol.com (Cloudflare Pages Functions). No authentication — this is the status page everyone checks when something is down. Per constitution §35 STREAMING-LOGS the incident data is written event-driven by the runtime (the kye-incident-detector Worker when a §13 Resilience Loop drift event crosses a severity threshold), never hand-edited; these endpoints read the canonical D1 tables and serve cached JSON / RSS views.
Status
GET/api/componentsAggregated component-status report
Returns a kye.status.report.v1 payload aggregated from the canonical component inventory, recent health rows in D1 (kye_status_components), and unresolved incidents (kye_status_incidents). Overall status is the worst-case of all components. Served through a 60-second KV cache to prevent thundering-herd polling; the x-cache response header reports HIT or MISS. CORS-open (Access-Control-Allow-Origin: *) so any surface can embed the status widget.
Responses
200Status report (cached up to 60s)
GET/api/incidentsLive incident list
Reads the canonical incidents D1 table (event-driven writes per §35 — never hand-edited) and returns a filterable JSON list, newest first, with a 15-second edge cache.
Parameters
| name | in | type | description |
|---|---|---|---|
limit | query | integer | |
since | query | string | Only incidents with started_at >= this ISO timestamp |
component | query | string | Filter by component_id |
status | query | string | Filter by incident severity state |
Responses
200Incident list500query_failed — the D1 read raised503db_binding_missing — KYE_DB not bound on the Pages project
GET/feed.xmlRSS 2.0 incident feed
RSS 2.0 feed of the 50 most recent incidents, regenerated on each request from the live incidents D1 table with a 60-second edge cache. Per §35, downstream consumers (RSS readers, status aggregators, on-call channels) subscribe to this feed instead of polling the HTML page. If the D1 read fails the endpoint emits an empty but valid feed rather than a 5xx — status RSS is critical infrastructure.
Responses
200RSS 2.0 XML document
Subscriptions
GET/api/subscribeDescribe the subscribe contract
Self-describing helper — returns the expected POST body shape for /api/subscribe (field names, requiredness, semantics) so the form and third-party integrators can introspect the contract without reading source.
Responses
200Machine-readable description of the POST contract
POST/api/subscribeSubscribe to incident + maintenance notifications
Stores a subscription row in D1 (status_subscriptions, migration 013) and sends a confirmation email through the canonical §38 Comms Engine template status.subscribe.confirmation.v1. Idempotent — an email that is already subscribed returns the existing subscription id with already_subscribed: true instead of creating a duplicate. Spam controls: a honeypot field (website) silently accepts and ignores bot submissions, and submissions are rate-limited to 5 per day-salted IP hash per 24h window.
Request body (required)
| field | type | description |
|---|---|---|
email required | string | |
accept required | boolean | Must be true — privacy + transactional-email acceptance |
components | array | Optional component-id filter; empty or missing = all components |
consent_marketing | boolean | Opts into the quarterly status digest |
Responses
200Subscribed (or already subscribed — idempotent)400invalid_body, invalid_email, or terms_not_accepted429rate_limited — more than 5 subscriptions from the same IP hash in 24h500handler_exception — unexpected failure (message included, truncated to 500 chars)503not_provisioned — KYE_DB unbound or migration 013_status_subscriptions.sql not applied
/api/subscribeCORS preflight
CORS preflight for the subscribe form. Allows origin https://status.kyeprotocol.com with methods GET, POST, OPTIONS and the content-type request header; preflight result cacheable for 86400 seconds.
Responses
204Preflight accepted (no body)
GET/api/status/unsubscribeOne-click unsubscribe
One-click unsubscribe for status notifications, linked from every status.subscribe.confirmation.v1 email (RFC 8058 spirit — GET by design, since the link is clicked straight from an email client and the id token is an unguessable kye:status-sub:<uuid>). Idempotent: re-hitting an already-unsubscribed token returns ok: true with already: true. The suppression is recorded to the audit chain (event_family internal.status.unsubscribe) when AUDIT_CHAIN_BASE_URL is configured; emission failures are logged loudly, never swallowed.
Parameters
| name | in | type | description |
|---|---|---|---|
id required | query | string | Subscription id token from the email's unsubscribe link |
Responses
200Unsubscribed (idempotent)400missing_token — id absent or not a kye:status-sub:<uuid>404unknown_token — no live subscription with that id500handler_exception — unexpected failure503not_provisioned — KYE_DB unbound or migration 013_status_subscriptions.sql not applied