Skip to content

Data plane API overview

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.

https://<your-tenant-url>

E.g., https://banking-cymmetri.intelliauth.local. Every endpoint in this surface is rooted there.

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.

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.

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.

The per-group topics below cover request shapes, response shapes, scope requirements, and error codes for each endpoint within the group.

GroupPath prefixPurposeTopic
Auth/api/v1/auth/*Sign-in, sign-out, MFA enrolment, WebAuthn ceremonyAuth
OAuth2/oauth2/*Token endpoint, revocation, device authorization, OIDC discoveryOAuth2
Me/api/v1/me/*Self-service: profile, sessions, MFA factors, passwordMe
Users/api/v1/users/*Admin user CRUDUsers
Applications/api/v1/applications/*Admin application managementApplications
Federation/api/v1/federation/*OIDC + SAML connection managementFederation
Groups/api/v1/groups/*Group-based access controlGroups
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.

Limits vary by endpoint family. The most common pattern:

FamilyDefault per-IP limitDefault per-user limit
OAuth2 token60 req/min600 req/hour
Auth (sign-in)30 req/minn/a — per IP
Self-service (/me/*)n/a600 req/hour
Adminn/a6000 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.

Mutating endpoints accept an Idempotency-Key header:

POST /api/v1/users
Idempotency-Key: 7f4e9a3b-2c14-4f5d-9a8e-1b3c5d7e9f0a

A 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.

List endpoints use cursor-based pagination:

GET /api/v1/users?limit=50

Response:

{
"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.

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.