API reference
KYE Protocol™ Admin Root Endpoints
3 operations · admin-root.yaml
Root-level (non-/api/v1) endpoints on admin.kyeprotocol.com. These are NOT Clerk-session endpoints: /email-action is authenticated by a signed single-use email-action token in the request itself (constitution §27 §4 Dual-Channel Admin + §27 §7 Email-Action Token), and /webhooks/stripe is authenticated by Stripe's v1 webhook signature (constitution §27 §8 — Stripe baked in). The /api/v1 owner console is documented separately in admin.yaml.
EmailAction
GET/email-actionExecute a one-click signed email-action token
The single canonical entry point for ALL signed email-action token clicks — commercial-lifecycle, expert-review, consultant approval, key rotation, deploy gate. The flow: (1) verify the token's signature via the canonical email-action-token library; (2) enforce single-use via the email_action_token_used D1 table (UNIQUE on token_hash — a re-click renders an "already taken" page without re-dispatching); (3) resolve the admin domain from the workflow_id prefix (kye:commercial-workflow:*, kye:expert-review:*, kye:consultant:*, kye:key-rotation:*, kye:deploy-gate:*, and the other registered prefixes); (4) dispatch — expert-review actions are applied inline as a D1 UPDATE, every other domain is enqueued onto its queue binding for the lifecycle agent; (5) record the use and render a confirmation page. Because these URLs are clicked by humans, every outcome (missing / expired / re-used token, unknown domain, dispatch failure, success) is an HTML page, not a JSON error: 200 for success and already-used, 400 for every failure. Authenticated by the token itself — no bearer auth.
Parameters
| name | in | type | description |
|---|---|---|---|
token required | query | string | Signed single-use email-action token (opaque signed payload) |
Responses
200Action recorded (or token already used — original action remains in effect); HTML confirmation page400Token missing, invalid, expired, or workflow domain unknown; HTML error page
POST/email-actionExecute an email-action token submitted via form POST
Identical semantics to GET /email-action — the handler delegates POST to the GET logic. POST exists for forms that submit the token in the body rather than the URL, which avoids email-client link rewriting / tracking parameters corrupting the signed GET URL. The token is still read from the token query parameter of the submitted form action. Same single-use enforcement, domain dispatch and HTML confirmation/error rendering as GET. Authenticated by the token itself — no bearer auth.
Parameters
| name | in | type | description |
|---|---|---|---|
token required | query | string | Signed single-use email-action token (opaque signed payload) |
Responses
200Action recorded (or token already used); HTML confirmation page400Token missing, invalid, expired, or workflow domain unknown; HTML error page
Webhooks
POST/webhooks/stripeReceive and dispatch Stripe webhook events
Verifies the Stripe-Signature header (Stripe's documented v1 Stripe's published webhook-signature scheme (300-second timestamp tolerance), constant-time comparison) against STRIPE_WEBHOOK_SIGNING_SECRET, then translates the event into a commercial-lifecycle transition request enqueued onto KYE_LIFECYCLE_QUEUE — the lifecycle agent is the only code path that mutates commercial_workflows state. Handled events: invoice.paid / invoice.payment_succeeded (the ONLY signal that advances a workflow toward access provisioning, §27 §6 payment-gate hard-lock), invoice.payment_failed (with failure_code mapped to the canonical taxonomy), invoice.payment_action_required (3DS/SCA), invoice.voided, invoice.marked_uncollectible, charge.refunded, charge.dispute.created, customer.subscription.deleted, plus the read-model-only checkout.session.completed and customer.subscription.updated projections. Unhandled event types are acknowledged with {ignored: true} so Stripe does not retry. Authenticated by the Stripe signature — no bearer auth.
Parameters
| name | in | type | description |
|---|---|---|---|
Stripe-Signature required | header | string | Stripe v1 signature header (t=<unix_ts>,v1=<hex_sig>,…) |
Request body (required)
| field | type | description |
|---|---|---|
id required | string | |
type required | string | |
livemode | boolean | |
data | object |
Responses
200Event acknowledged — dispatched to the lifecycle queue, or ignored (unhandled type)400Body is not valid JSON or the event envelope is malformed401Stripe-Signature header missing, stale, or signature mismatch503Signing secret unset or queue dispatch failed — Stripe should retry