OAuth, OIDC and SAML endpoints
The reference table of every public protocol endpoint, the grant types of the token endpoint, and the SAML and SCIM surfaces.
All protocol endpoints live on your sign-in domain. Examples use https://accounts.obexal.com, the default domain: if your organization uses a custom domain, it replaces that host everywhere, including in the issuer.
Discovery
Two public documents are the entry point for any integration:
curl https://accounts.obexal.com/.well-known/openid-configuration
curl https://accounts.obexal.com/.well-known/jwks.jsonThe discovery document advertises the exact capabilities of the platform:
| Discovery field | Value |
|---|---|
response_types_supported | code (authorization code flow only) |
grant_types_supported | authorization_code, refresh_token, client_credentials, urn:ietf:params:oauth:grant-type:token-exchange |
code_challenge_methods_supported | S256 |
id_token_signing_alg_values_supported | RS256 (no other algorithm is accepted) |
scopes_supported | openid, profile, email |
token_endpoint_auth_methods_supported | none, client_secret_basic, client_secret_post, private_key_jwt |
dpop_signing_alg_values_supported | ES256, RS256 |
backchannel_logout_supported | true (see below) |
OAuth 2.1 and OIDC endpoints
| Method | Path | Role | Authentication |
|---|---|---|---|
| GET | /.well-known/openid-configuration | OIDC discovery document | None (public) |
| GET | /.well-known/jwks.json | Public signing keys (JWKS) | None (public) |
| GET | /oauth/authorize | Authorization endpoint (code + PKCE) | Browser session (redirects to sign-in if absent) |
| POST | /oauth/par | Pushed authorization requests (RFC 9126) | Client authentication |
| POST | /oauth/token | Token endpoint (all grant types) | Client authentication (see below) |
| GET | /oauth/userinfo | OIDC claims of the user | Access token (Bearer or DPoP scheme) |
| POST | /oauth/introspect | Token introspection (RFC 7662) | Confidential client credentials only |
| POST | /oauth/revoke | Refresh token revocation (RFC 7009, always 200) | Client credentials |
| GET | /oauth/logout | RP-initiated logout (end_session_endpoint) | Browser session (optional, idempotent) |
/oauth/authorize also accepts a request_uri obtained from /oauth/par (single use); the other query parameters are then ignored. /oauth/logout accepts client_id, post_logout_redirect_uri (validated against the client's registered allowlist) and state.
Grant types at the token endpoint
POST /oauth/token takes a form-encoded body and returns JSON with Cache-Control: no-store. The grant_type parameter selects the flow:
| grant_type | Purpose | Specific parameters |
|---|---|---|
authorization_code | Sign a user in | code (required, single use), redirect_uri (exact match with the authorize request), code_verifier (required, PKCE S256) |
refresh_token | Renew tokens, with rotation and reuse detection | refresh_token (required), scope (optional, subset of the original scopes) |
client_credentials | Machine identity, no user | scope (optional, subset of the client's scopes); confidential clients only, no refresh token issued |
urn:ietf:params:oauth:grant-type:token-exchange | Delegated tokens for AI agents (RFC 8693) | subject_token (required), subject_token_type and requested_token_type (optional, access_token URN only), scope (optional downscoping), resource (optional target audience, RFC 8707) |
Client authentication supports client_secret_basic, client_secret_post, private_key_jwt (signed assertion, RFC 7523) and none for public clients, which rely on PKCE alone. On any grant, an optional DPoP header binds the issued token to the client's key (cnf.jkt claim) and the token_type becomes DPoP instead of Bearer. See Advanced client security.
curl -X POST https://accounts.obexal.com/oauth/token \
-d grant_type=client_credentials \
-d client_id=svc-reporting \
-d client_secret="$CLIENT_SECRET"{"access_token": "eyJhbGciOiJSUzI1NiIs...", "token_type": "Bearer", "expires_in": 600, "scope": "reports:read"}Only authorization_code and refresh_token return a refresh token and, with the openid scope, an ID token. Token Exchange responses add issued_token_type. Error responses use the OAuth shape (error, error_description): see Errors and limits, and Validate tokens for consuming what you receive.
Back-channel logout
Back-channel logout is emitted, not received: there is no inbound logout endpoint. When a user's session ends, Obexal POSTs a signed logout_token (JWT, typ: logout+jwt, RS256) to the backchannel_logout_uri registered on each application the user had consented to. Logout is keyed by sub, not by session (backchannel_logout_session_supported: false). See Sessions and logout.
SAML 2.0 endpoints
In the paths below, {tenant} is your organization slug.
Obexal as identity provider (outbound SSO, see SAML IdP):
| Method | Path | Role | Authentication |
|---|---|---|---|
| GET | /saml/idp/{tenant}/metadata | IdP metadata (XML) | None (public) |
| GET, POST | /saml/idp/{tenant}/sso | SSO endpoint, SP-initiated | Browser session (redirects to sign-in if absent) |
| GET | /saml/idp/{tenant}/apps/{appId}/sso | IdP-initiated SSO for one registered app | Browser session |
Obexal as service provider (inbound enterprise SSO, see SAML SP):
| Method | Path | Role | Authentication |
|---|---|---|---|
| GET | /saml/{tenant}/metadata | SP metadata (XML) | None (public) |
| GET | /saml/{tenant}/login | Starts sign-in at the enterprise IdP | None (starts the flow) |
| POST | /saml/{tenant}/acs | Assertion consumer service | Signed SAML assertion from the IdP |
There is no SAML Single Logout (SLO) endpoint, inbound or outbound.
SCIM 2.0
Inbound provisioning is served under /scim/v2 (resource Users only), authenticated by a per-tenant bearer token. The full surface, attribute schema and limits are documented in the SCIM reference.