Reference
HTTP API reference
A readable map of the issuing service HTTP API, grouped by area — Runtime, Admin, Platform, Auth, Plans, Webhooks — with method, path, and how each is authenticated.
A readable map of the issuing service’s HTTP API, grouped by area. This page is for finding the right endpoint and knowing how it’s authenticated; the machine-readable OpenAPI spec ships with the service for full request/response schemas, field types, and examples.
$BASE is your issuing service URL (e.g. https://keyright.delta1labs.com).
Authentication at a glance
Every non-runtime endpoint is gated by one of these. All admin/platform auth uses the X-Admin-Token header (a session token from dashboard login is presented the same way).
| Auth | Header(s) | Who |
|---|---|---|
| none | — | end-customer runtime calls (activation, validate, trial) |
| tenant token | X-Admin-Token: <team/session/env-admin token> | a vendor managing their own tenant |
| platform token | X-Admin-Token: <KEYRIGHT_PLATFORM_TOKEN> (+ X-Tenant for /admin/*) | the platform operator |
| session | X-Admin-Token: <session token from /auth/*> | a signed-in dashboard user |
| HMAC | X-Keyright-Signature | payment-provider webhooks |
| cron secret | X-Cron-Secret | the external notification scheduler |
Roles behind a tenant token are capability-gated (owner ⊃ admin ⊃ support/billing ⊃ viewer); an endpoint’s minimum role is noted below where it matters. See Admin dashboard for the role model.
Runtime (/v1/*) — no auth, called by your app / customer
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/activate | Activate a key on a machine → consumes a seat, returns a signed lease. |
| POST | /v1/validate | Re-validate / refresh a key+machine without consuming a new seat. |
| POST | /v1/free-seat | Release the seat this machine holds on a key. |
| POST | /v1/trial | Self-service trial: mint (or return) a trial key for a product and email it. CORS-open. See Self-service free trials. |
Admin (/admin/*) — tenant token
Manage one tenant’s products, licenses, and team. With the platform token these require an X-Tenant header naming the target tenant.
Products & tiers
| Method | Path | Purpose |
|---|---|---|
| GET | /admin/products | List products (with tiers, license counts, trial settings). |
| POST | /admin/products | Create/update a product (name, slug, optional trialDays/trialTier/trialSeats). |
| POST | /admin/products/{slug}/trial | Enable/disable a product’s self-service trial. |
| POST | /admin/products/{slug}/tiers | Create/update a per-product tier (seats + entitlement template). |
| GET | /admin/tiers | List tenant-wide tier templates. |
| POST | /admin/tiers | Create/update a tenant-wide tier template. |
Licenses
| Method | Path | Purpose |
|---|---|---|
| POST | /admin/licenses | Issue a license (auto-generates a key unless you pass id). |
| GET | /admin/licenses[?product=] | List/filter licenses. |
| POST | /admin/licenses/{id}/revoke | Revoke a license (takes effect on the next online check). |
| POST | /admin/licenses/{id}/renew | Extend expiry / change seats, no new key. |
| POST | /admin/licenses/{id}/transfer | Transfer ownership to a new licensee (audited history). |
| GET | /admin/licenses/{id}/transfers | The license’s ownership chain. |
| POST | /admin/licenses/{id}/deactivate | Release a specific machine’s seat. |
| POST | /admin/licenses/{id}/offline-lease | Sign an offline lease for an air-gapped machine id. |
| GET | /admin/licenses/{id}/activations | Machines a license is active on (device metadata + geo). |
| POST | /admin/licenses/bulk-revoke | Revoke many by id, per-item results. |
| POST | /admin/licenses/bulk-seats | Change seat counts in bulk, per-item results. |
| GET | /admin/revocation-list | Build + sign a distributable offline revocation list. |
Team
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET/POST | /admin/team | owner | List / invite team members (invite emails a one-time token). |
| POST | /admin/team/{id} | owner | Enable/disable a member. |
| POST | /admin/team/{id}/set-password | owner | Provision a member’s dashboard password. |
Workspace, reporting & integration
| Method | Path | Purpose |
|---|---|---|
| GET | /admin/overview | Home dashboard: subscription summary, counts, per-product breakdown, trend, upcoming renewals. |
| GET | /admin/account | Tenant + plan + usage + the integration block (base URL, signing public key, webhook URL). |
| GET | /admin/stats | Per-product totals (licenses, active seats, expiring-soon, revoked). |
| GET | /admin/usage | Per-license allocated/used seats + totals (usage-based billing). |
| GET | /admin/export[?product=] | Full licenses + activations bundle. |
| GET | /admin/audit | Attributable audit log of mutating actions. |
| GET | /admin/public-key | The tenant’s signing public key to embed in your product. |
| POST | /admin/workspace | Owner: workspace name, logo, onboarding flag. |
| POST | /admin/webhook-secret/rotate | Owner: rotate this tenant’s fulfillment webhook secret. |
| POST | /admin/billing/checkout | Owner: open a Lemon Squeezy checkout to upgrade the plan. |
| POST/GET | /admin/resellers, /admin/resellers/{id} | Manage resellers (capped, product-scoped issuers). |
Platform (/platform/*) — platform token
The multi-tenant operator surface. Disabled (503) when KEYRIGHT_PLATFORM_TOKEN is unset (single-tenant self-host).
| Method | Path | Purpose |
|---|---|---|
| POST | /platform/tenants | Create a company/tenant → returns initial owner token, signing public key, webhook secret. |
| GET | /platform/tenants[?slug=] | List tenants. |
| POST | /platform/tenants/{id} | Enable/disable, set plan, subscription status. |
| POST | /platform/tenants/{id}/signing-key | Import (Nebula’s PKCS#8) or generate a tenant signing key. |
| POST | /platform/tenants/{id}/rotate-signing-key | Rotate a tenant’s signing key. |
| POST | /platform/tenants/{id}/rotate-webhook-secret | Rotate a tenant’s webhook secret. |
| GET | /platform/plans | Full plan catalog (incl. non-public plans). |
| POST | /platform/plans/{key} | Create/update a plan’s pricing, quotas, and features. |
Auth (/auth/*) — dashboard sign-in → session token
These mint a session token you then present as X-Admin-Token to the /admin/* endpoints above. Login is per-tenant (pass X-Tenant; defaults to default).
| Method | Path | Purpose |
|---|---|---|
| POST | /auth/login | Email + password → an MFA challenge. |
| POST | /auth/mfa | Email + password + TOTP code → session token. |
| POST | /auth/sso | Exchange a validated OIDC ID token for a session token. |
| POST | /auth/session | Exchange a Supabase Auth access token (native / social) for a session token. |
| GET | /auth/oauth/{provider} → /auth/oauth/{provider}/callback | Native Google / GitHub OAuth on your own domain. |
Plans (/plans) — public
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /plans | none | Public pricing catalog (plans marked public), for a pricing page or signup. |
Webhooks (/webhooks/*) — HMAC
Fulfillment triggers: a payment provider (or a thin adapter) POSTs a normalized event, HMAC-signed over the raw body in X-Keyright-Signature. “Paid” mints a license (idempotent per order ref); “refund”/“cancel” revokes it. Payment processing itself is out of scope.
| Method | Path | Purpose |
|---|---|---|
| POST | /webhooks/fulfill/{slug} | Per-tenant webhook; tenant is taken from the route and verified by that tenant’s secret. |
| POST | /webhooks/fulfill | Legacy deployment-wide webhook (single-tenant, KEYRIGHT_WEBHOOK_SECRET). |
Operational
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /health | none | Liveness/version probe. |
| GET | /branding | none | White-label brand name/logo/color for any UI. |
| POST | /internal/notifications/run | cron secret | Run the daily expiry/seat-limit scan (for scale-to-zero hosts). |
| various | /portal/* | magic link | Self-service customer portal (view licenses, re-download key/file, free seats). |
The dashboard itself is served at /dashboard — see Admin dashboard.