The data plane API is what your application calls at runtime. Sign-in lives here. Tokens live here. The user, application, MFA, and audit surfaces all live here. Every IntelliAuth tenant exposes the same endpoints; tenant identity comes from the subdomain.
The control plane API (the topic next to this one) is a different surface — it manages organisations, tenants themselves, and platform-level settings. You almost never talk to it from a user-facing app.
Base URL
Section titled “Base URL”https://<your-tenant-url>E.g., https://banking-cymmetri.intelliauth.local. Every endpoint in this surface is rooted there.
Authentication
Section titled “Authentication”Most endpoints require a bearer token:
Authorization: Bearer <access-token>A small set of endpoints are public (the OAuth2 token + discovery endpoints, the well-known JWKS document); they are marked public in their per-endpoint topic.
Versioning
Section titled “Versioning”Endpoints under /api/v1/ are stable. Breaking changes go to /api/v2/ (which does not exist today). Patch-level changes — new optional fields, new endpoints — are not breaking and ship without a version bump.
The OAuth2 endpoints (/oauth2/*, /.well-known/*) do not carry an /api/v1/ prefix — they follow OAuth / OIDC conventions instead.
Response envelope
Section titled “Response envelope”Every JSON response uses a consistent envelope:
{ "data": { ... }, "meta": { ... }}data is the resource (or an array for list endpoints). meta carries pagination cursors, totals, and any operation-specific extras.
Error responses use:
{ "error": "<machine-readable-code>", "message": "<human-readable-message>", "details": { ... }, "request_id": "req_01HZX..."}Always check error and status, never just parse for data. Logging request_id makes support tickets dramatically faster to triage.
Endpoint groups
Section titled “Endpoint groups”The per-group topics below cover request shapes, response shapes, scope requirements, and error codes for each endpoint within the group.
| Group | Path prefix | Purpose | Topic |
|---|---|---|---|
| Auth | /api/v1/auth/* | Sign-in, sign-out, MFA enrolment, WebAuthn ceremony | Auth |
| OAuth2 | /oauth2/* | Token endpoint, revocation, device authorization, OIDC discovery | OAuth2 |
| Me | /api/v1/me/* | Self-service: profile, sessions, MFA factors, password | Me |
| Users | /api/v1/users/* | Admin user CRUD | Users |
| Applications | /api/v1/applications/* | Admin application management | Applications |
| Federation | /api/v1/federation/* | OIDC + SAML connection management | Federation |
| Groups | /api/v1/groups/* | Group-based access control | Groups |
| Resources | /api/v1/resources/* | Resource and relation-based access control (ReBAC) | Resources |
Webhooks have their own dedicated topic — they're the integrator's hook into platform events. Breach-incident management, threat-intelligence feeds, reports, and tenant-admin audit reads live in the tenant admin console and are not REST surfaces; integrators react to them via webhooks.
Rate limits
Section titled “Rate limits”Limits vary by endpoint family. The most common pattern:
| Family | Default per-IP limit | Default per-user limit |
|---|---|---|
| OAuth2 token | 60 req/min | 600 req/hour |
| Auth (sign-in) | 30 req/min | n/a — per IP |
Self-service (/me/*) | n/a | 600 req/hour |
| Admin | n/a | 6000 req/hour |
When rate-limited, the response is 429 Too Many Requests with Retry-After in the headers and error: rate_limited in the body. The platform's tenant policy can override these limits.
Idempotency
Section titled “Idempotency”Mutating endpoints accept an Idempotency-Key header:
POST /api/v1/usersIdempotency-Key: 7f4e9a3b-2c14-4f5d-9a8e-1b3c5d7e9f0aA retry with the same key within 24 hours returns the same response without re-applying the mutation. Use this for any mutating call that could time out — it lets you retry safely.
Pagination
Section titled “Pagination”List endpoints use cursor-based pagination:
GET /api/v1/users?limit=50Response:
{ "data": [...], "meta": { "next_cursor": "eyJpZCI6InVzcl8wMUhaWCJ9", "limit": 50 }}Pass cursor=<next_cursor> on the next call to get the next page. When next_cursor is null, you've reached the end.
Cursors are opaque; treat them as black boxes. Decoding or constructing cursors by hand is not supported and may break across releases.
Request IDs
Section titled “Request IDs”Every response includes an X-Request-Id header. Log it. When opening a support ticket, quote it — it lets the platform team find the exact request in the audit trail.