REST API reference
Every endpoint in the Kimezu protocol. Examples are curl; the canonical machine-readable spec is OpenAPI 3.1 and is downloadable below.
Authentication
All API endpoints (except OIDC discovery and JWKS) require a Bearer token. Three kinds of token authenticate against the API:
- Operator token — long-lived, scoped to one operator account. Required for tenant management, application registration, audit reads.
- Session token — short-lived JWT issued by
/authorize. Authenticates as a user or group; respects the session'scanclaim. - Agent token — bearer token for an agent; exchanges for a session JWT via
/v1/agents/token.
Pass the token in the Authorization header: Authorization: Bearer <token>. Cross-tenant operator calls must also send X-Tenant-Id to disambiguate.
Tenants
A tenant is one branded surface — sign-in domain, theming, payment profile, region. Operators create, configure and decommission tenants here.
Returns up to 200 tenants per page; use ?page=<n> for pagination. Tenants are returned in creation order.
Query parameters
| Name | Type | Description |
|---|---|---|
| page | integer | 1-indexed page number. Default 1. |
| status | string | Filter: active, dormant, archived. |
| region | string | Filter: eu-west, eu-central. |
Provisions the tenant, allocates the OIDC issuer URL, signs the first set of JWKS keys, and emits a tenant.created webhook.
Body parameters
| Name | Type | Description |
|---|---|---|
| tenant_id | string | Slug, lowercase, kebab-case. Must be unique within the operator. |
| display_name | string | Human-readable name. Shown in operator console and webhook payloads. |
| domain | string | Primary authentication domain — e.g. auth.tenant.eu. |
| region | string | eu-west or eu-central. Region is immutable after creation. |
| brand | object | Theming bundle (see Theming kit). |
| methods | array | Enabled sign-in methods. Default: ["password","magic-link"]. |
Returns the full tenant record including the theming bundle, OIDC issuer URL, JWKS URI, and current key rotation state.
Partial updates. Only fields included in the request body are changed. Region cannot be changed; create a new tenant and migrate.
Soft-deletes the tenant. Users can no longer sign in, but identity records are retained for the audit-retention period before hard deletion. The action is irreversible after the retention window.
Applications
An application is a system that asks Kimezu to verify users. Each application has client credentials and a list of permitted redirect URIs.
Requires X-Tenant-Id header. Returns applications in creation order with their last_seen_at timestamps — useful for spotting stale integrations.
Body parameters
| Name | Type | Description |
|---|---|---|
| name | string | Human-readable. Shown on consent screens and in the audit log. |
| redirect_uris | array | Allowed callback URLs. Exact match — no wildcards. |
| scopes | array | OIDC/OAuth scopes requested. Standard: openid, profile, email. |
| type | string | web (default, with client_secret) or spa (PKCE-only). |
Response. Returns the client_id and client_secret. The secret is shown once and never recoverable — store it before closing the response.
Issues a new client_secret and keeps the previous one valid for a grace window of 24 hours, so you can deploy without downtime.
Existing sessions issued to the application stop validating on the next JWKS refresh (or immediately via push-revoke). Audit entry is automatic.
Users
Read and write operations on user records. Most endpoints accept the opaque sub claim as the identifier; user PII is intentionally hard to look up by, to keep operator workflows blind to user data where possible.
Returns the full user record: sub, display name, email (if permitted by the tenant's PII visibility policy), groups, roles, last sign-in timestamp.
Used by operator-driven onboarding and migration scripts. The created user receives a magic-link email to complete setup. Tenants can disable admin-created users in their configuration.
Invalidates every refresh token issued to the user. Access tokens already in flight expire at their natural exp (max 15 minutes). For instant cutoff, pair with a push-revoke webhook handler in your application.
Groups
Groups are collections of users with shared ownership, permissions or payment context. Groups are tenant-scoped; the same group ID does not exist across tenants.
Body parameters
| Name | Type | Description |
|---|---|---|
| group_id | string | Slug. Unique within the tenant. |
| display_name | string | Human-readable. |
| owners | array | subs of initial owner users. |
| payment_profile | string | Optional. Attach a payment profile at creation. |
Membership change propagates within the access-token lifetime. For instant propagation, listen for the group.member.added webhook and clear your local cache.
Revokes the user's permissions inherited through this group. Refresh tokens are invalidated for this user; new access tokens reflect the change.
Sessions
Sessions are produced by the OIDC /token endpoint. The session resource here is for inspection and termination — not minting.
Returns metadata about an active session — actor, tenant, application, last refresh time, MFA factor used. Does not return the access token itself.
Invalidates the refresh token; access tokens already issued expire at their exp. Use this to handle stolen-token incidents from the operator console.
Authorization decisions
Most authorization is done locally by reading the JWT's can claim. For ownership-aware decisions, applications can ask Kimezu directly.
Body parameters
| Name | Type | Description |
|---|---|---|
| action | string | Permission string, e.g. publish:article. |
| resource | string | Resource ID, opaque to Kimezu. |
| owner | string | Owner subject (user or group sub) for ownership-aware decisions. |
Response. { "allow": true, "reason": "editor-role" } or { "allow": false, "reason": "missing-grant" }. The reason string is stable and safe to display to operators.
Agents
Non-human identities with revocable API tokens and owner-scoped permissions.
Body parameters
| Name | Type | Description |
|---|---|---|
| owner | string | sub of the user or group that owns the agent. |
| audience | string | Application(s) the agent can call. |
| can | array | Permission subset. Each must be held by the owner. |
| display_name | string | Human-readable label for the audit log. |
Response. Returns the agent record and the bearer token. The token is shown once — store it now or rotate.
The agent calls this with its bearer token and receives a short-lived JWT carrying actor_type: "agent". Subsequent calls to consuming apps use the JWT, not the agent token.
Immediately invalidates the agent's API token and all outstanding session JWTs. Push-revoke webhook fires within ~50ms.
Payment profiles
Stored routing for where money goes when a resource generates a payment. Kimezu never moves money; it tells your application where money should be sent.
Body parameters
| Name | Type | Description |
|---|---|---|
| profile_id | string | Slug, unique within tenant. |
| owner | string | User or group sub. |
| country | string | ISO 3166 alpha-2. |
| vat_id | string | EU VAT ID (VIES-validated if provided). |
| providers | array | One or more provider records (Stripe / Mollie / PayPal). |
Returns provider routing details for the resource's owner. Your application uses these to create the actual charge — Kimezu does not call Stripe / Mollie / PayPal on your behalf.
Your application reports the result of a payment for VAT and OSS recording. Kimezu computes the treatment (applied / reverse-charge / outside-EU scope) from the buyer's country and VAT ID, stores it, and emits an audit entry.
Audit
Read-only access to the tamper-evident audit log. Operators can export per-tenant for SIEM ingestion.
Query parameters
| Name | Type | Description |
|---|---|---|
| since | string | ISO 8601 timestamp. Default: 24 hours ago. |
| until | string | ISO 8601 timestamp. Default: now. |
| event | string | Filter: session.create, permission.grant, etc. |
| actor | string | Filter by actor sub. |
| format | string | json (default), csv, jsonl. |
Returns the current chain head hash. Anyone holding a copy of your audit log can recompute the chain and verify it matches — without trusting us.
OIDC discovery
The OIDC discovery document for a tenant is at the tenant's authentication domain. It lists all OIDC endpoints, supported scopes, response types, JWKS URI and signing algorithms.
Standard OIDC 1.0 discovery. Refresh on a sensible cache schedule (we suggest 24 hours; the URL itself is cacheable). Your OIDC client library reads this — you almost never read it by hand.
JWKS document. Includes kid-keyed RSA public keys. Kimezu rotates the active signing key every 24 hours (older keys remain in the JWKS until all tokens signed by them have expired).
Error catalogue
Every API error returns a stable error code in the response body plus a human-readable message. Codes are namespaced by resource.
| Code | HTTP | Meaning | Retry? |
|---|---|---|---|
| auth.token.expired | 401 | Access token past its exp. | Refresh, then retry |
| auth.token.invalid | 401 | Bad signature, wrong issuer, or revoked. | Re-authenticate |
| authz.denied | 403 | Caller lacks the required permission. | Do not retry |
| tenant.not_found | 404 | Tenant ID unknown or archived. | Do not retry |
| tenant.duplicate | 409 | Tenant ID already in use. | Pick a different ID |
| application.redirect_mismatch | 400 | Redirect URI does not match registered set. | Do not retry |
| user.not_found | 404 | Unknown sub. | Do not retry |
| agent.grant_exceeds_owner | 422 | Agent permission set is not a subset of the owner's. | Adjust grant |
| payment.profile_not_found | 404 | Profile ID unknown for this tenant. | Do not retry |
| vat.vies_unreachable | 503 | EU VIES verification service unreachable. | Retry with backoff |
| rate.limited | 429 | Rate limit exceeded. Honour the Retry-After header. | Retry per header |
| server.error | 500 | Unexpected. We were paged. | Retry with backoff |
| server.maintenance | 503 | Planned maintenance window. | Retry after the Retry-After header |
Full machine-readable list with example payloads is in errors.yaml (downloadable). Codes are stable across minor versions; deprecations get a 90-day notice.