Skip to content

Admin API

The management API behind the console: base URL, authentication with API secrets or bearer tokens, the response envelope, pagination, rate limits and the resource groups.

Everything the console does goes through the admin API, so anything you configure on screen can also be scripted: realms, clients, users, roles, webhooks and the rest. It is a JSON API on the same host as the protocol endpoints, under /api/v1/admin.

Base URL

Base URLPlain text
https://authio.api.hyperio.tech/api/v1/admin

On a Dedicated environment, use your environment’s API address with the same paths, and credentials created in that environment’s own console. The version is part of the path; v1 is the current one.

In paths, {realm} is the realm ID (acme), {client} is the client ID (acme-web), and identifiers such as {userId} are GUIDs. A realm or client of another account answers as if it did not exist.

Authentication

CredentialHeaderUse it for
API secretx-api-key: <secret>Scripts, CI pipelines and integrations.
Bearer tokenAuthorization: Bearer <access token>Calls made for a person signed in to the console, or with a token your script obtains from an account secret. The token must be issued by the platform realm authio to its client authio; tokens issued by your own realms are refused here.

The credentials of a client’s consumers are not accepted by the admin API: they act inside their client, while the admin API works at the level of the account. A consumer’s API key is validated by your own API at the realm’s introspection endpoint with token_type_hint=api_key — see API keys. A PUT on a consumer never changes its type: leaving type out keeps it, and another type is refused with ValidationFailed on type.

API secrets

  1. Create the secret

    In the console, open API secrets and choose New secret. Choose the type API key, give it a name and, if you want it to stop working on its own, an expiry date.

  2. Allow only what the caller needs

    Pick the roles and scopes the secret may use. They are the most it can ever do, whatever else the account allows.

  3. Copy the value

    The value is shown once, at creation. Keep it in a secret manager, and create a separate secret for each integration so you can revoke one without the others.

TerminalBash
curl https://authio.api.hyperio.tech/api/v1/admin/realms/acme \
  -H "x-api-key: $AUTHIO_API_KEY"

Only active, unexpired secrets of type API key authenticate, and only for realms and clients of the account that owns them. Every attempt, accepted or refused, is written to the access log. A call to a realm or client the account does not reach (another account’s, or one that does not exist) gets 403 with errorCode Forbidden, as a signed-in person would; a missing, unknown, deleted or expired secret gets 401 from the next call.

A machine credential of the account cannot impersonate anyone: an API key, a personal access token or a token exchanged with the account’s client secret gets 403 with errorCode ImpersonationActorNotAPerson from POST /api/v1/admin/realms/{realm}/users/{userId}/impersonate, whatever roles it carries. Impersonation is support work, done by a person signed in to the console, whose name the audit trail keeps. The refused attempt is still recorded, with the credential as its actor.

Bearer tokens from an account secret

A script that prefers short-lived bearer tokens can exchange an account secret for one. Create a secret of type Client secret in API secrets, with the roles the script needs, and present it to the platform realm’s token endpoint with the client credentials grant:

TerminalBash
curl https://authio.api.hyperio.tech/realms/authio/protocol/openid-connect/token \
  -u "authio:$AUTHIO_ACCOUNT_SECRET" \
  -d grant_type=client_credentials

The access token it returns carries only the roles and scopes allowed on the secret and never outlives the secret’s own expiry. Send it as Authorization: Bearer to the admin API.

Permissions

Each endpoint requires a permission made of a resource — realm, client, user, role, scope, secret, audit, account and a few others — and an action: read, write (create), update or delete. A caller holds what all of its roles grant together. Missing or invalid credentials get 401; valid credentials without the permission get 403. See Team and access for the roles of the console.

Response envelope

Responses are JSON in camelCase, with empty fields left out. A success wraps the result in data:

200 OK (shortened)JSON
{
  "statusCode": "OK",
  "success": true,
  "data": {
    "id": "6f1c2a7e-3b4d-4e8f-9a10-5c6d7e8f9a0b",
    "realmId": "acme",
    "name": "Acme",
    "status": "Active"
  }
}
FieldWhat it holds
successWhether the request succeeded.
statusCodeThe HTTP status, repeated in the body.
dataThe result, on success.
paginationTakes the place of data on paged lists.
notificationsMessages for people. On a validation error there is one per refused field, with field — its camelCase path in the request body — and code, the rule that refused it.
errorCodeOn errors: a stable code to branch on. See Error codes.
requestIdOn errors: the request’s identifier, also sent on every response in the X-Request-Id header.
Branch on the HTTP status and errorCode, never on the message. Messages are written for people and may change.

Pagination and filtering

Lists that page share the same query parameters and answer with pagination instead of data.

ParameterDefaultNotes
pageNumber1Values below 1 read as 1.
pageSize10At most 200; larger values read as 200.
searchTerm—Free text matched against the resource’s text fields.
status—Restricts the list to one status, such as Active.
sortByCreation dateThe field to order by; an unknown field falls back to the creation date.
sortDirectiondescasc or desc.
createdFrom, createdTo—A creation-date range. createdFrom is inclusive, createdTo exclusive.
RequestBash
curl "https://authio.api.hyperio.tech/api/v1/admin/realms/acme/clients?pageNumber=1&pageSize=20&sortDirection=asc" \
  -H "x-api-key: $AUTHIO_API_KEY"

Rate limits

Most endpoints allow 300 requests per minute per caller. Sensitive ones — creating or changing API secrets, imports, impersonation and a few others — allow 50. Above those, the API applies overall ceilings per caller and per realm. A refused request gets 429 with a Retry-After header, in seconds, and errorCode TooManyRequests.

Request IDs and retries

Every response carries an X-Request-Id header. Send your own — up to 128 characters of letters, digits, -, _, : and . — to follow a call across your logs and ours, and quote it when you contact support.

The API takes no idempotency key. If a create times out, read the resource back before sending it again: creating a realm or client whose ID is already taken is refused with 409 and AlreadyExists.

Rotating secrets

Two endpoints generate a new value and return it once: POST /realms/{realm}/clients/{client}/client-secret/rotate for a client’s secret, and POST /secrets/{id}/rotate for an account credential — an API key, a personal access token or an account client secret. Both take an optional JSON body that says what becomes of the previous value. Without one, the previous value is refused at once and the tokens issued with it keep working until they expire.

FieldTypeWhat it does
previousValueValidForMinutesinteger, optionalMinutes the previous value keeps authenticating, from 0 to the environment’s maxPreviousValueValidForMinutes. 0 or absent refuses it at once.
revokeIssuedTokensboolean, optionalThe previous value leaked: it is refused at once, the access tokens issued with it before the rotation turn inactive at introspection and are refused by Authio’s own APIs, and their refresh tokens stop working. For a client’s secret, people signed in to the client sign in again.

A period above 0 and revokeIssuedTokens: true exclude each other. Sending both, or a period out of range, gets 400 with errorCode ValidationFailed, and the notification names the refused field (revokeIssuedTokens or previousValueValidForMinutes).

Keep the old secret for an hourBash
curl -X POST https://authio.api.hyperio.tech/api/v1/admin/realms/acme/clients/acme-web/client-secret/rotate \
  -H "x-api-key: $AUTHIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"previousValueValidForMinutes": 60}'

The answer carries the new value once — clientSecret, clientSecretLastFour and clientSecretRotatedAt for a client, the secret with its value for an account credential — and rotation, which says what became of the previous one. Times are UTC.

Field of rotationWhat it holds
modeImmediate (refused at once), Overlap (still accepted for a while) or Compromise (refused at once, with its tokens revoked).
previousValueValidUntilUntil when the previous value still authenticates; only for Overlap.
issuedTokensRevokedBeforeTokens issued with the previous value before this instant are revoked; only for Compromise.

Reads follow the last rotation: a client’s clientConfiguration carries previousClientSecretValidUntil and issuedTokensRevokedBefore, and every API secret carries previousValueValidUntil and issuedTokensRevokedBefore. The …ValidUntil field is set only while the previous value still authenticates; a cached read can outlive it, so compare it with the current time before relying on it.

GET /secrets/rotation-policy answers maxPreviousValueValidForMinutes, the longest the environment lets a previous value keep working (currently 1440, a day). It is open to anyone holding secret:read, secret:write or secret:update, and the console offers only the overlaps within it.

Revoking issued tokens reaches only what asks Authio. A resource server that validates JWTs locally, by their signature alone, cannot see the revocation and keeps accepting those tokens until they expire — standard OAuth behaviour. Have it use introspection where a revocation must take effect at once.

Every rotation is recorded in the change trail with details holding mode, previous_value_valid_until and issued_tokens_revoked_before. A client’s secret rotation also raises admin_resource_updated on the realm’s webhooks, with the same details.

Resource groups

Paths are relative to /api/v1/admin.

GroupBase pathsWhat it covers
Realms/realms, /realms/{realm}Realms, their status and identity configuration.
Clients/realms/{realm}/clients, /realms/{realm}/clients/{client}Clients and, under each, its secret, consumers, scopes, roles, signing keys, claim mappers, allowed IPs and identity providers.
Realm users/realms/{realm}/usersThe people of a realm, their roles, connected accounts and impersonation.
Roles/realms/{realm}/roles, /realms/{realm}/clients/{client}/roles, /rolesRoles of a realm, of a client, and the account’s own.
Scopes/scopes, /realms/{realm}/scopes, /realms/{realm}/clients/{client}/scopesThe scope catalogue, scopes exclusive to a realm and the scopes a client allows.
Organizations/realms/{realm}/organizationsB2B organizations, their members, domains and identity providers.
Resource servers/realms/{realm}/resource-serversThe APIs and MCP servers tokens are issued for.
Identity providers/realms/{realm}/identity-providersExternal identity providers and their role mappings.
Sessions/realms/{realm}/sessionsOpen sessions, to read and revoke.
Webhooks/realms/{realm}/webhooks, /realms/{realm}/clients/{client}/webhooksWebhook subscriptions per realm and per client, with {webhookId}/rotate-secret, {webhookId}/test and deliveries; a client’s webhooks also expose metrics, events and {webhookId}/deliveries/{deliveryId}/replay. See the event types.
Delegation/realms/{realm}/delegation-grantsDelegation grants used by token exchange.
Connected accounts/realms/{realm}/connection-providers, /realms/{realm}/connectionsConnection providers and the accounts people connected.
Suspensions/suspensions, /realms/{realm}/clients/{client}/users/{userId}/suspensionsUser suspensions.
API secrets/secretsThe account’s secret vault, with {id}/rotate and rotation-policy (see Rotating secrets).
Audit/audit-trail, /access-logsChanges made through the admin API — see the change trail — and sign-ins and token issuance.
Account/accountThe account and its team.
Import/import, /import/{resourceType}, /import/translate, /import/migrate?dryRun=true, /realms/{realm}/clients/{client}/users/importImporting configuration and users, and migrating from other providers, with a dry run first.

The routes the console uses to follow and operate a Dedicated environment live on the shared platform, under /api/v1/dedicated/instance, and need the account permissions to read and update the account.

Next steps