Skip to content

OpenID Connect endpoints

Every protocol address of a realm — discovery, JWKS, authorization, token, UserInfo, introspection, revocation, end session and device authorization — with parameters and examples.

Each realm is an OpenID Provider of its own. Its issuer is {base}/realms/{realm} and every endpoint sits under it, so a client configured with the issuer finds the rest through discovery. The examples on this page use the realm acme on the shared platform:

IssuerPlain text
https://authio.api.hyperio.tech/realms/acme

On a Dedicated environment, replace the host with your environment’s API address. A token issued by one realm is never accepted by another.

Endpoints at a glance

EndpointMethodPath under the issuerRate limit
DiscoveryGET/.well-known/openid-configurationNone
JWKSGET/protocol/openid-connect/certsNone
AuthorizationGET/protocol/openid-connect/auth300 per minute
TokenPOST/protocol/openid-connect/token50 per minute
UserInfoGET, POST/protocol/openid-connect/userinfo300 per minute
IntrospectionPOST/protocol/openid-connect/introspect50 per minute
RevocationPOST/protocol/openid-connect/revoke50 per minute
End sessionGET/protocol/openid-connect/logout50 per minute
Device authorizationPOST/protocol/openid-connect/device/auth50 per minute

Limits count each caller per realm. A refused request gets 429 with a Retry-After header. Responses that carry credentials — token, introspection, revocation, UserInfo, device authorization — are sent with Cache-Control: no-store.

Discovery

The provider metadata is served at three addresses, so a client finds it whichever convention it follows: OpenID Connect Discovery appends the suffix to the issuer, while RFC 8414 inserts it after the host, the form MCP clients try first.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/.well-known/openid-configuration
curl https://authio.api.hyperio.tech/.well-known/oauth-authorization-server/realms/acme
curl https://authio.api.hyperio.tech/.well-known/openid-configuration/realms/acme

The document describes the realm as it is configured, not a generic catalogue:

FieldValue
scopes_supported, grant_types_supportedEverything the realm’s clients allow, together.
code_challenge_methods_supportedThe PKCE methods the realm’s clients allow; S256 when none is set.
response_types_supportedcode
response_modes_supportedquery, web_message
display_values_supportedpage, popup
token_endpoint_auth_methods_supportedclient_secret_basic, client_secret_post, none — the same for introspection and revocation.
id_token_signing_alg_values_supportedRS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512
subject_types_supportedpublic
acr_values_supported1, 2, 3
prompt_values_supportednone, login, select_account, consent
authorization_response_iss_parameter_supportedtrue
frontchannel_logout_supported, backchannel_logout_supportedtrue, with their _session_supported counterparts.
client_id_metadata_document_supportedtrue only when the realm accepts clients that register from a metadata document URL.

There is no dynamic client registration endpoint, and signed request objects (request, request_uri) are not supported. Discovery answers 404 for a realm that does not exist.

JWKS

The public keys that verify the realm’s tokens, as a JWK Set (RFC 7517). Every token names the key that signed it in its kid header. Keys rotate on a schedule, so cache the set and fetch it again when a token names a kid you do not have.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/certs

Authorization endpoint

Starts a sign-in with the authorization code flow. The browser is sent here, the hosted login runs the client’s sign-in steps, and the browser comes back to your redirect_uri with a code.

ParameterRequiredNotes
client_idYesThe client ID, such as acme-web.
redirect_uriYesMust equal one of the client’s registered redirect URIs: scheme, host, port, path and query.
response_typeYescode, the only one supported.
scopeYesSpace-separated. Must include openid unless the client is plain OAuth 2.0, and every scope must be enabled on the client. Add offline_access for a refresh token.
code_challenge, code_challenge_methodWhen PKCE is on — the defaultS256 or plain, as the client allows. A challenge without a method is refused.
stateRecommendedReturned unchanged with the response.
nonceRecommendedCopied into the ID token.
promptNonone, login, select_account or consent. none cannot be combined with another value.
max_ageNoSeconds since the last sign-in after which the person signs in again.
id_token_hint, login_hintNoAn ID token this realm issued to the client; an identifier to prefill on the sign-in screen.
acr_valuesNo1 single factor, 2 multi-factor, 3 phishing-resistant. A preference: it never refuses the sign-in.
resourceNoOne resource server URI (RFC 8707), which becomes the access token’s audience.
organizationNoThe alias of the organization the sign-in is for.
ui_localesNoPreferred languages for the screens, most preferred first.
response_mode, displayNoquery (the default) and page; web_message and popup for a sign-in in a popup window.
Authorization requestPlain text
https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/auth
  ?client_id=acme-web
  &response_type=code
  &redirect_uri=https%3A%2F%2Fapp.acme.com%2Fcallback
  &scope=openid%20profile%20email%20offline_access
  &state=af0ifjsldkj
  &nonce=n-0S6_WzA2Mj
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

The response carries code, state and iss (RFC 9207). The code is valid for 30 seconds and only once: presenting it again revokes the session it was issued in. Until the redirect_uri is proven, errors are shown on an error page rather than redirected; after that they come back to the redirect_uri with error, error_description, state and iss.

Token endpoint

Exchanges a grant for tokens. The body is application/x-www-form-urlencoded. A confidential client authenticates with HTTP Basic (client_secret_basic, the default) or with client_id and client_secret in the body (client_secret_post) — only the method registered on the client is accepted, and Basic wins when both are sent. A public client sends only its client_id and relies on PKCE. Private key JWT client authentication is not supported.

Supported grants

Grantgrant_typeRefresh token
Authorization codeauthorization_codeWith offline_access
Refresh tokenrefresh_tokenRotated on each use by default
Client credentialsclient_credentialsNo
PasswordpasswordOnly when the client allows it
Device codeurn:ietf:params:oauth:grant-type:device_codeWith offline_access
Token exchangeurn:ietf:params:oauth:grant-type:token-exchangeNo
Personal access tokenpersonal_access_tokenNo

Each grant must be enabled on the client. An unknown grant gets unsupported_grant_type; a known one the client has not enabled gets unauthorized_client.

Authorization codeBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/token \
  -u "acme-web:$CLIENT_SECRET" \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  --data-urlencode redirect_uri=https://app.acme.com/callback \
  -d code_verifier="$CODE_VERIFIER"
Response fieldWhen
access_token, token_type, expires_inAlways. token_type is Bearer.
id_tokenWhen a person signs in with the openid scope; on refresh, when the client is set to reissue it.
refresh_token, refresh_expires_inWhen a refresh token is issued.
scopeThe scopes granted.
issued_token_typeToken exchange only.

Device authorization

Starts the device flow (RFC 8628) for input-constrained devices. The client authenticates as at the token endpoint and must have the device code grant enabled.

StartBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/device/auth \
  -d client_id=acme-cli \
  --data-urlencode "scope=openid profile offline_access"
Response fieldValue
device_codeWhat the device polls the token endpoint with.
user_codeEight characters shown as XXXX-XXXX, for the person to type.
verification_uri{issuer}/device, where the person types the code.
verification_uri_completeThe same page with the code filled in, for a QR code.
expires_inSeconds until the codes expire: 10 minutes.
intervalSeconds to wait between polls: 5.

While the person decides, polling answers authorization_pending; polling too fast answers slow_down; after 10 minutes, expired_token; a denied request, access_denied. See Device flow.

UserInfo

Returns the current claims of the person behind an access token: always sub, plus the claims the token’s profile, email and phone scopes allow, read fresh on every call. A token without openid gets 403 with insufficient_scope; an invalid one, 401 with invalid_token, both with a WWW-Authenticate header.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Introspection

Tells an API whether a token is still active (RFC 7662), including revocation, ended sessions and suspended users that a signature check alone cannot see. The caller authenticates as a client. The answer is always 200: {"active": false} for any token that is not valid, with no reason given.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/introspect \
  -u "acme-web:$CLIENT_SECRET" \
  -d token="$ACCESS_TOKEN" \
  -d token_type_hint=access_token

An active token returns active, scope, client_id, username, token_type, exp, iat, nbf, sub, aud, iss and jti, plus authorization claims such as roles, acr, amr, sid and the organization. With token_type_hint=api_key the client asks about one of its consumers’ API keys instead: an active key returns sub (the consumer), client_id, scope, consumer_name, credential_id, credential_type and consumer_resource_access.

Revocation

Invalidates a token you no longer need (RFC 7009), typically at sign-out. The caller authenticates as a client, and every well-formed request gets 200, even for an unknown or expired token. Revoking ends the session behind the token, which also invalidates its refresh tokens; the person stays signed in to the realm’s other applications.

TerminalBash
curl https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/revoke \
  -u "acme-web:$CLIENT_SECRET" \
  -d token="$REFRESH_TOKEN" \
  -d token_type_hint=refresh_token

End session

Signs the person out of the realm (RP-Initiated Logout). Send the browser here with:

ParameterNotes
id_token_hintAn ID token this realm issued; an expired one is accepted. Without a valid hint nothing is ended and the person sees a confirmation screen instead.
client_idThe client signing out; read from the hint when omitted.
post_logout_redirect_uriWhere to go afterwards. Followed only when registered on the client, compared exactly like a redirect URI.
stateReturned unchanged.
ui_localesPreferred languages for the screens.
Sign-out requestPlain text
https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/logout
  ?id_token_hint=ID_TOKEN
  &post_logout_redirect_uri=https%3A%2F%2Fapp.acme.com%2F
  &state=af0ifjsldkj

Clients that registered a back-channel or front-channel logout URI are told whenever one of their sessions ends — at sign-out, but also when an administrator revokes it or the user is suspended. See Sessions and SSO.

Other addresses under a realm

AddressWhat it is for
/realms/{realm}/deviceThe page where people type a device code — the verification_uri.
/realms/{realm}/broker/{alias}/callbackThe redirect URI to register at an external identity provider. Accepts GET and POST.
/realms/{realm}/connections/callbackThe redirect URI to register at a connected-account provider.
/realms/{realm}/clients/{client}/webauthn/...Passkey ceremonies used by the hosted pages.

Errors

Protocol endpoints answer errors with the fields of RFC 6749 §5.2, plus Authio’s own error_code to match a report against the logs:

401 UnauthorizedJSON
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials. The provided client_secret is not valid.",
  "error_code": "InvalidClientCredentials"
}

Every error value and the codes behind it are listed in Error codes.

Next steps