Skip to content

API Reference

Explore and integrate against the complete admin and protocol API — documented live from the running server.

What it is

HelixIAM publishes its full API as OpenAPI, generated directly from the running server, so the reference is always exactly in step with the version you are running. Browse it interactively, or pull the spec to generate a typed client in your language of choice.

Resource URL
Interactive docs /swagger-ui.html
OpenAPI spec /v3/api-docs
# Fetch the machine-readable spec
curl https://auth.example.com/v3/api-docs -o helix-openapi.json

The spec covers both the admin API (realms, applications, users, roles, scopes, identity providers, sessions, webhooks, SCIM targets, import/export) and the protocol endpoints (OIDC, SAML, account).

Generate a client

Point any OpenAPI generator at the spec to scaffold a typed SDK:

openapi-generator-cli generate \
  -i helix-openapi.json \
  -g typescript-fetch \
  -o ./helix-client

Use standard OIDC or a generated client

For login flows, integrate over standard OIDC with any library — no HelixIAM SDK required. For admin automation, generate a typed client from this OpenAPI spec in your language of choice. A first-party TypeScript SDK is in development.

Dynamic Client Registration

Applications can register themselves programmatically via Dynamic Client Registration (DCR) at:

POST /connect/register

DCR is protected by an initial access token issued by an administrator. Present it to register a new client and receive its credentials and a registration access token for later management.

POST /realms/acme/connect/register
Authorization: Bearer <initial-access-token>
Content-Type: application/json

{
  "client_name": "Acme Web",
  "redirect_uris": ["https://app.example.com/callback"],
  "grant_types": ["authorization_code", "refresh_token"]
}

Registration metadata

Besides the RFC 7591 basics, registration accepts and returns these OpenID Connect metadata (v1.1.0-rc.14):

Metadata Admin API field Notes
jwks jwks A JWK Set by value, instead of jwks_uri; the two are mutually exclusive. 1 to 10 public signing keys
id_token_signed_response_alg idTokenSignatureAlg RS256, PS256 or ES256
userinfo_signed_response_alg userinfoSignedResponseAlg Userinfo is answered as a signed JWT
logo_uri, policy_uri, tos_uri logoUri, policyUri, tosUri https only; shown on the sign-in and consent pages
request_uris requestUris At most 10 https URLs a request object may be fetched from
initiate_login_uri initiateLoginUri https only

A registration without scope gets openid, plus offline_access for a client of the refresh_token grant. A response that issues a client_secret carries client_secret_expires_at: 0. Response types with id_token or token need the implicit grant, which the realm administrator must allow for registration (never by default). Details: OIDC client settings and OpenID Connect flows.

Mint initial access tokens carefully

Treat initial access tokens like onboarding credentials: scope them, time-box them, and hand them only to trusted provisioning systems.

Endpoint catalog

The tables below are generated from the running server's OpenAPI spec (/v3/api-docs). Helix exposes two API surfaces that authenticate differently — see Authenticating to the API:

Surface Path prefix Auth
Admin API /admin/realms/{realm}/… Admin session + CSRF (writes need X-XSRF-TOKEN)
Protocol /realms/{realm}/… OAuth2 / OIDC bearer tokens

Admin API

All paths below are relative to /admin/realms/{realm}.

Users

Method & path Purpose
GET /users · POST /users List / create users
GET · PUT · DELETE /users/{userId} Read / update / delete a user
GET · POST /users/{userId}/roles List / assign user role mappings
DELETE /users/{userId}/roles/{roleId} Unassign a role
GET /users/{userId}/credentials List a user's credentials
DELETE /users/{userId}/credentials/{type}/{id} Revoke a credential
PUT /users/{userId}/password Reset a user's password
GET · PUT /users/{userId}/required-actions Get / set required actions
POST /users/{userId}/impersonate Impersonate a user
GET /users/{userId}/gdpr/export Export a user's personal data
GET /users/{userId}/gdpr/consents List a user's consent records
DELETE /users/{userId}/gdpr Erase a user (right to be forgotten)
POST /users/import Bulk-import users

Clients

Method & path Purpose
GET /clients · POST /clients List / create OIDC clients
GET · PUT · DELETE /clients/{id} Read / update / delete a client
GET · POST /clients/{id}/secret Reveal / regenerate the client secret
GET · POST /clients/{clientId}/roles · DELETE .../roles/{name} Client roles
GET · POST /clients/{clientId}/mappers · PUT · DELETE .../mappers/{mapperId} Protocol mappers
GET · POST · DELETE /clients/{clientId}/service-account/roles Service-account role mappings
GET · PUT /clients/{clientId}/allowed-resources Resource-indicator allow-list (RFC 8707)
GET · PUT /clients/{clientId}/authz/settings Authorization Services (UMA) settings
GET · POST /clients/{clientId}/authz/resources · DELETE .../resources/{name} UMA resources
GET · POST /clients/{clientId}/authz/policies · DELETE .../policies/{name} UMA policies
GET · POST /clients/{clientId}/authz/permissions · DELETE .../permissions/{name} UMA permissions
GET · POST /clients/{clientId}/authz/scopes · DELETE .../scopes/{name} UMA scopes
POST /clients/{clientId}/authz/evaluate Evaluate an authorization request

Roles

Method & path Purpose
GET /roles · POST /roles List / create realm roles
DELETE /roles/{roleId} Delete a realm role
PUT /roles/{roleId}/default Set the realm's default role

Groups

Method & path Purpose
GET /groups · POST /groups List / create groups
PUT · DELETE /groups/{groupId} Update / delete a group
GET /groups/{groupId}/members · PUT · DELETE .../members/{userId} Group membership
GET /groups/{groupId}/roles · PUT · DELETE .../roles/{roleId} Group role mappings

Organizations

Method & path Purpose
GET /organizations · POST /organizations List / create organizations
GET · PUT · DELETE /organizations/{orgId} Read / update / delete an organization
GET /organizations/{orgId}/members · PUT · DELETE .../members/{userId} Organization membership

Client scopes

Method & path Purpose
GET /client-scopes · POST /client-scopes List / create client scopes
GET · DELETE /client-scopes/{scopeId} Read / delete a client scope
PUT · DELETE /client-scopes/{scopeId}/claims/{claimId} Attach / detach a claim mapper

Claims

Method & path Purpose
GET /claims · POST /claims List / create claim mappers
PUT · DELETE /claims/{claimId} Update / delete a claim mapper

Identity providers

Method & path Purpose
GET /identity-providers · POST /identity-providers List / create identity providers
GET · PUT · DELETE /identity-providers/{alias} Read / update / delete a provider

Webhooks

Method & path Purpose
GET /webhooks · POST /webhooks List / create subscriptions
PUT · DELETE /webhooks/{id} Update / remove a subscription

Applications

Method & path Purpose
GET /applications · POST /applications List / create applications
GET · PUT · DELETE /applications/{name} Read / update / delete an application

Agents (AI / non-human identity)

Method & path Purpose
GET /agents · POST /agents List / create agents
GET · PUT · DELETE /agents/{id} Read / update / delete an agent
POST /agents/{id}/activate · /suspend · /revoke Lifecycle transitions
GET /agents/owner-review Owner attestation / review queue

SAML clients

Method & path Purpose
GET /saml-clients · POST /saml-clients List / register SAML relying parties
GET · PUT · DELETE /saml-clients/{entityId} Read / update / delete a SAML client
POST /saml-clients/import · /import-url Import from metadata (body / URL)

Keys

Method & path Purpose
GET /keys List realm signing keys
GET /keys/access Whether the signed-in admin may change keys (realm-admin)
POST /keys/import Import a private key + certificate chain (PENDING)
POST /keys/csr Generate a PENDING key and a CSR (purpose: all, access, id or saml; empty = all). In a custody realm the key is generated in the realm's backend
GET /keys/{keyId}/csr Download a key's CSR
PUT /keys/{keyId}/certificate Attach a CA-signed certificate chain
POST /keys/{keyId}/activate Activate a PENDING key (?force=true skips the staging time)
DELETE /keys/{keyId} Retire a key (never the ACTIVE RS256 key)
GET /settings/signing · PUT /settings/signing Realm signing algorithms (defaultAlg, samlAlg)
POST /keys/rotate Generate and activate a new key

Key custody (HSM / KMS)

See Key custody. Changing a profile needs a master-realm administrator.

Method & path Purpose
GET /key-custody The realm's profile (STANDARD, PROTECTED, HIGH), backend, backend health (backendHealthy, backendReachable, kekQuarantined), the backend's isolation (backendIsolation: level shared or dedicated, realmCount, dedicatedToRealm, allowsRealm; never other realms' ids), requireDedicatedBackendForHigh, kekReleaseState (DISABLED, DESTROYING or null), and keys per purpose with their custody
PUT /key-custody Move the realm: {"profile", "backendId"}; 202 with the planned keys and when each starts signing. 400 on backendId when the backend cannot serve the realm's algorithms, is dedicated to other realms (backendRealmNotAllowed) or, with require-dedicated-backend-for-high, is not the realm's alone for High assurance (backendNotDedicated); 400 on profile, naming each one, while an enabled SAML service provider asks for an algorithm the target cannot sign (RSA-SHA1 outside Standard, RSA-SHA512 in High assurance) or, for High assurance, a wallet connection still signs with a software verifier key; 409 with code kekRotationRunning during an unfinished key-encryption key rotation, or kekReleasePending while the realm's key-encryption key is being released on a key store that no longer serves it
GET /key-custody/kek-rotation The realm's latest key-encryption key rotation ({"rotation": null} when none): state (REWRAPPING, DISABLING, DONE, FAILED, ABANDONED), paused, rowsDone/rowsTotal, lastErrorCode/lastError/lastErrorKeys, KEK references and times. Any administrator of the realm. A paused rotation answers 503 temporarily_unavailable with Retry-After, code kekRotationPaused and the rotation
POST /key-custody/kek-rotation Start (202) a rotation of a Protected realm's key-encryption key, or get the one running (200); resumes a stopped one (202). Master-realm administrators only (403). 409 with code: kekRotationNotProtected, kekRotationNoKek, kekRotationDbEncryptionKek, kekRotationChanged, kekRotationRefused; 400 with code backendRealmNotAllowed when the realm's backend no longer serves it (no KEK is made); 503 when the backend cannot be reached
DELETE /key-custody/kek-rotation Abandon a stopped rotation that moved no key (200; the realm's key-encryption key is the earlier one again). Master-realm administrators only. 409 kekRotationNotStopped, kekRotationNewKekInUse or kekRotationUnlabelledKeys (keys written by an earlier release without a recorded KEK: resume instead); 400 backendRealmNotAllowed when the realm's backend no longer serves it
PUT /key-custody/key-store-policy Set the realm's key-store policy: {"policy": "any" \| "sovereign"}; 200 with realmId, keyStorePolicy and changed. Master-realm administrators only (403). 409 keyStorePolicyConflict when the realm's current key store or a live key breaks the policy; 400 on policy when missing or unknown. GET /key-custody also answers keyStorePolicy and backendStoreClass; PUT /key-custody takes an optional keyStorePolicy, and refuses with the code keyStorePolicy a change the policy forbids
POST /key-custody/kek-release/finish Finish a release of the realm's key-encryption key that is stuck at destroying (no server can finish it). Master-realm administrators only (403). 200 with destroyedInBackend and keks (forgotten ones are to be removed in the key store by hand); 409 kekReleaseNotDestroying when there is nothing to finish
POST /verifier-keys/generate Generate a wallet verifier key (ES256 / ES384) in a backend: {name, algorithm, backendId}
POST /verifier-keys/{name}/csr The verifier key's CSR, signed in the backend: {subject, dnsNames}
PUT /verifier-keys/{name}/certificate Attach the CA-issued chain: {certificateChainPem}
GET /verifier-keys Verifier keys that can sign; ?pending=true adds keys waiting for a certificate

Credential issuer keys (HSM / KMS)

Paths are relative to the realm (/admin/realms/{realm}), as in the other tables. Writes need a realm administrator. See Key custody: credential issuer keys. Every answer to a GET carries the realm's profile in the X-Helix-Custody-Profile header.

Method & path Purpose
GET /credential-issuance/keys List issuer keys: id, kid, status, source, subject, issuer, notBefore, notAfter, fingerprint, chainPem, csrPem, createdAt, activatedAt, rotatedAt, custody, backendId (never a reference or key material)
POST /credential-issuance/keys/generate Generate a test key certified by the realm's development CA. 400 code devCaRefused in High assurance; 409 code devCaSoftware while a software CA would certify a backend key
POST /credential-issuance/keys/import Import {privateKeyPem, certificateChainPem}. 400 on privateKeyPem, code softwareKeyRefused, in High assurance
POST /credential-issuance/keys/csr Generate a PENDING key and its CSR: {subject, dnsNames}. In Protected and High assurance the key is generated in the realm's backend
PUT /credential-issuance/keys/{keyId}/certificate Attach the CA-signed chain: {certificateChainPem}
POST /credential-issuance/keys/{keyId}/activate · POST /credential-issuance/keys/{keyId}/retire Activate a PENDING key / retire a key (the ACTIVE key: 409)
GET /credential-issuance/keys/ca The development CA: {certificatePem, custody}
DELETE /credential-issuance/keys/ca Retire the development CA: 204; 404 when there is none; 409 while an ACTIVE or PENDING generated key chains to it

An unreachable backend is 503 temporarily_unavailable with Retry-After.

eID SP keys (HSM / KMS)

Paths are relative to the realm too, for eID connections (eid, digid, eherkenning, eidas). They need manage-identity-providers; a connection that is authoritative for the BSN (DigiD, eIDAS) also needs a realm administrator for every write. See Key custody: eID SP keys.

Method & path Purpose
GET /identity-providers/{alias}/sp-keys The connection's keys: id, usage, status, rsaBits, keyTransport, custody, backendId, subject, issuer, notAfter, fingerprint, chainPem, csrPem, createdAt, activatedAt; the realm's custody profile in the X-Helix-Custody-Profile response header
GET /identity-providers/{alias}/sp-keys/algorithms What this scheme and backend allow: rsaBits, keyTransport ({method, digest, mgf} list), signatureAlgorithms, defaultKeyTransport, separateKeys
POST /identity-providers/{alias}/sp-keys/csr Generate a key in the realm's backend and its CSR: {usage: SIGNING \| DECRYPTION \| SIGNING_DECRYPTION, rsaBits, keyTransport, subject, dnsNames}; 201. 400 on usage for SIGNING_DECRYPTION on eIDAS; 400 on keyTransport when the backend cannot honour the combination; 409 code tooManyPending above the pending cap
PUT /identity-providers/{alias}/sp-keys/{keyId}/certificate Attach the CA-signed chain: {certificateChainPem}
POST /identity-providers/{alias}/sp-keys/{keyId}/activate · POST /identity-providers/{alias}/sp-keys/{keyId}/retire Activate (200, the key) / retire (204; 404 for an unknown key; 409 for the ACTIVE key: activate its successor first)

Clear a pasted key with clearSpSigningPrivateKey or clearSpDecryptionPrivateKey set to true in the provider's update body. A High-assurance realm refuses pasted keys (code pastedKeyInHighAssurance).

SAML metadata signing

Method & path Purpose
GET /saml-idp/metadata-settings {signed, validityHours, lastError} (view-clients)
PUT /saml-idp/metadata-settings {"signed": true, "validityHours": 168}; both fields required, validity 1 to 720 hours. signed: true makes one probe signature first: 400 on fieldErrors.signed when the key cannot sign, 503 when the backend is unreachable (manage-clients)

Off by default. See Key custody: SAML metadata signing.

Sessions

Method & path Purpose
GET /sessions List active sessions
DELETE /sessions/{id} Revoke a session
GET /sessions/service-accounts List service-account sessions

Authentication flows

Method & path Purpose
GET /flows · POST /flows List / create authentication flows
GET · PUT · PATCH · DELETE /flows/{alias} Read / save / rename / delete a flow
GET · PUT /flow Get / save the browser sign-in flow
GET /authenticators List available authenticators

Admin roles (RBAC)

Method & path Purpose
GET /admin-roles List admin roles
PUT /admin-roles/{roleId} Set an admin role's permissions
GET /admin-roles/permissions List assignable admin permissions

Messaging (SMS / email / push)

Method & path Purpose
GET · PUT /messaging/providers List / save channel providers
DELETE /messaging/providers/{channel}/{driver} Remove a provider
POST /messaging/providers/{channel}/test Send a test message
GET · PUT /messaging/templates List / save message templates
POST /messaging/templates/preview Preview a rendered template
GET · POST /messaging/push-tokens List / register push tokens

SCIM targets (outbound provisioning)

Method & path Purpose
GET /scim-targets · POST /scim-targets List / register downstream SCIM targets
PUT · DELETE /scim-targets/{id} Update / remove a target

Import / export

Method & path Purpose
GET /export Export the realm
POST /import Import a realm
POST /import/keycloak Import from a Keycloak export
POST /users/import Bulk-import users

Realm settings & operations

Method & path Purpose
GET · PUT /settings Read / update realm settings. Creating a realm: 400 on realmId for an id that ends in -kek or starts with another realm's id followed by -kek (fieldErrorCodes.realmId = realmIdKek), and, while a key store is bound to realms, for an id that is another realm's id followed by -, the start of one, or differs from one only in case (fieldErrorCodes.realmId = realmIdPrefix). A realm import reports such a refusal as a failed realm entry with that code
GET · PUT /subject-claim Read / set the subject-claim strategy
GET · PUT /provisioning Read / update DCR & provisioning config
POST /provisioning/initial-access-tokens Mint a DCR initial access token
GET /endpoints Realm endpoint URLs
GET /health Realm health
GET /events Query the audit-event log
POST /user-federation/{alias}/sync Trigger an LDAP sync
GET/POST /workload-identity · GET/PUT/DELETE /workload-identity/{id} Workload identity federation configs

Global admin endpoints

A few endpoints are server-wide rather than realm-scoped: GET /admin/metrics/summary (Prometheus-style summary), GET /admin/audit/config, and GET /admin/key-custody/plugins (the custody plugins the server loaded: type, pluginVersion, spiVersion, file, sha256Prefix; master-realm administrators only), the database encryption key rotation under /admin/database-encryption (GET the state; POST /rotation to start, POST /rotation/pause, /rotation/resume and /rotation/retry; master-realm administrators only) and GET /admin/key-custody/backends (the configured key custody backends: id, type, storeClass (software, sovereign, hyperscaler or plugin), algorithms, health, latency, and isolation: isolation shared or dedicated with its realms ids, and when there is something to say realmBinding, prefixOverlaps (realm, overlapsWith, isolationEnforced) and warnings; never their settings; master-realm administrators only).

Protocol endpoints (bearer / public)

These run under the realm prefix /realms/{realm}/… and authenticate with bearer tokens (or their own onboarding credential), not an admin session.

Method & path Auth Purpose
/account/** User bearer token End-user self-service — see Account console
/scim/v2/** Per-realm SCIM token SCIM 2.0 provisioning — see SCIM
POST /connect/register · GET/PUT/DELETE /connect/register/{clientInternalId} Initial / registration access token Dynamic Client Registration (RFC 7591)
POST /workload-identity/token Workload JWT Exchange a workload JWT for a Helix token
POST /agent/delegation/token Client / bearer On-behalf-of agent delegation (RFC 8693)
POST /device/enroll · /device/enroll/start Enrollment token Device / MFA enrollment
GET /push/{id} · POST /push/{id}/approve · /deny Session Push-based MFA approval
GET /qr/{id} · POST /qr/{id}/confirm Session QR-based device confirmation
POST /tx · GET /tx/{id} · POST /tx/{id}/sign · /consume Bearer Signing / consent transactions
GET /saml/idp/metadata Public SAML 2.0 IdP metadata
GET /.well-known/oauth-protected-resource Public RFC 9728 protected-resource metadata

Standard OIDC/SAML endpoints

The usual protocol endpoints — /authorize, /token, /userinfo, /logout, /.well-known/openid-configuration, JWKS — are advertised by the realm's discovery document. See the OIDC quickstart.

Discovery additions in 1.1.0-rc.14

/realms/{realm}/.well-known/openid-configuration also states:

  • scopes_supported (openid, profile, email, address, phone) and address in claims_supported;
  • request_parameter_supported, request_uri_parameter_supported and require_request_uri_registration (all true), with request_object_signing_alg_values_supported (RS256);
  • userinfo_signing_alg_values_supported;
  • response_modes_supported: query and form_post, plus fragment where the implicit and hybrid flows are advertised;
  • frontchannel_logout_supported and frontchannel_logout_session_supported (true);
  • check_session_iframe, only in a realm where a client uses session management;
  • the implicit and hybrid response types and the implicit grant, only in a realm where a client has that grant or registration may add it.

See OpenID Connect flows.

See also