Skip to content

Endpoint Reference

All SingleSign endpoints require the platform_guid parameter to identify your platform. The base URL for all endpoints is https://api.singlesign.com.


Endpoint Summary

MethodPathDescriptionAuth Required
GET/.well-known/openid-configurationOpenID Connect DiscoveryNo
GET/oauth/authorizeStart authorization flowNo
POST/oauth/tokenExchange code or refresh token for tokensClient auth (confidential) or PKCE (public)
GET/oauth/userinfoGet user profile claimsBearer token
GET/oauth/jwksJSON Web Key Set for token verificationNo
POST/oauth/introspectValidate a tokenClient auth (Basic or POST)
POST/oauth/revokeRevoke a tokenNo (but platform_guid required)

1. Discovery

Retrieve the OpenID Connect configuration for your platform. Use this to dynamically discover all other endpoints and supported features.

GET /.well-known/openid-configuration?platform_guid=<guid>

Parameters

ParameterLocationRequiredDescription
platform_guidQueryYesYour platform identifier

Example

curl "https://api.singlesign.com/.well-known/openid-configuration?platform_guid=YOUR_PLATFORM_GUID"

Response

{
  "issuer": "https://api.singlesign.com",
  "authorization_endpoint": "https://api.singlesign.com/oauth/authorize",
  "token_endpoint": "https://api.singlesign.com/oauth/token",
  "userinfo_endpoint": "https://api.singlesign.com/oauth/userinfo",
  "jwks_uri": "https://api.singlesign.com/oauth/jwks",
  "introspection_endpoint": "https://api.singlesign.com/oauth/introspect",
  "revocation_endpoint": "https://api.singlesign.com/oauth/revoke",
  "scopes_supported": ["openid", "profile", "email", "phone", "address", "offline_access"],
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post", "none"],
  "id_token_signing_alg_values_supported": ["HS512"],
  "subject_types_supported": ["public"]
}

2. Authorize

Redirect the user's browser to this endpoint to start the authorization flow. The user will authenticate and consent, then be redirected back to your redirect_uri with an authorization code.

GET /oauth/authorize

Parameters

ParameterLocationRequiredDescription
platform_guidQueryYesYour platform identifier
response_typeQueryYesMust be code
client_idQueryYesYour application's client ID
redirect_uriQueryYesMust exactly match a registered redirect URI
scopeQueryYesSpace-separated scopes (must include openid)
stateQueryRecommendedRandom string for CSRF protection
code_challengeQueryConditionalPKCE code challenge (required for public clients)
code_challenge_methodQueryConditionalMust be S256 when code_challenge is present
login_hintQueryNoEmail to pre-fill. When sent, SingleSign routes by account existence — existing account → sign-in, no account → sign-up — and the email field is locked (the user cannot change it) through the whole flow
actionQueryNologin or register. Fallback page when no login_hint is sent or account existence can't be determined
promptQueryNologin forces re-authentication even with an active session; select_account forces the account chooser; none never shows UI — the redirect carries error=login_required or error=consent_required when interaction would be needed
max_ageQueryNoMaximum authentication age in seconds. A session authenticated longer ago than this forces a fresh sign-in (email pre-filled)
first_nameQueryNoOptional sign-up pre-fill; editable by the user, ignored for existing accounts
last_nameQueryNoOptional sign-up pre-fill; editable by the user, ignored for existing accounts
phone_numberQueryNoOptional sign-up pre-fill; editable by the user, ignored for existing accounts

Example

# Open this URL in the user's browser
https://api.singlesign.com/oauth/authorize\
  ?platform_guid=YOUR_PLATFORM_GUID\
  &response_type=code\
  &client_id=YOUR_CLIENT_ID\
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback\
  &scope=openid%20profile%20email\
  &state=abc123xyz\
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM\
  &code_challenge_method=S256\
  &action=register\
  &login_hint=invitee%40example.com

Account chooser

If the user's browser already holds one or more SingleSign sessions, the authorize flow shows an account chooser ("Choose an account", similar to Google) instead of silently continuing with whichever account was signed in last. The user can continue as a listed account without re-entering their password, pick a signed-out account (email pre-filled), sign in as somebody else, or sign out. Platforms don't need to change anything to get this behavior; send prompt=select_account to force the chooser, or a locked login_hint to pin a specific account and skip it.

Success Response

Redirect to your redirect_uri:

https://app.example.com/callback?code=AUTHORIZATION_CODE&state=abc123xyz

Error Response

Redirect to your redirect_uri:

https://app.example.com/callback?error=access_denied&error_description=The+user+denied+the+request&state=abc123xyz

3. Token

Exchange an authorization code for tokens, or use a refresh token to get a new access token.

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

Authorization Code Exchange

ParameterLocationRequiredDescription
grant_typeBodyYesauthorization_code
codeBodyYesThe authorization code from the callback
redirect_uriBodyYesSame URI used in the authorize request
client_idBodyYesYour application's client ID
code_verifierBodyConditionalPKCE code verifier (required if code_challenge was sent)
client_secretBodyConditionalRequired for confidential clients
platform_guidBodyYesYour platform identifier

Example: Public Client (PKCE)

curl -X POST "https://api.singlesign.com/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_HERE" \
  -d "redirect_uri=https://app.example.com/callback" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" \
  -d "platform_guid=YOUR_PLATFORM_GUID"

Example: Confidential Client (with secret)

curl -X POST "https://api.singlesign.com/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_HERE" \
  -d "redirect_uri=https://app.example.com/callback" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" \
  -d "platform_guid=YOUR_PLATFORM_GUID"

Refresh Token Exchange

ParameterLocationRequiredDescription
grant_typeBodyYesrefresh_token
refresh_tokenBodyYesThe refresh token
client_idBodyYesYour application's client ID
client_secretBodyConditionalRequired for confidential clients
platform_guidBodyYesYour platform identifier

Example: Refresh

curl -X POST "https://api.singlesign.com/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=REFRESH_TOKEN_HERE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "platform_guid=YOUR_PLATFORM_GUID"

Success Response

{
  "access_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...",
  "id_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "rt_xxxxxxxxxxxxxxxxxxxxxxxx",
  "scope": "openid profile email"
}

Error Response

{
  "error": "invalid_grant",
  "error_description": "The authorization code has expired."
}

4. UserInfo

Retrieve the authenticated user's profile claims. The claims returned depend on the scopes granted to the access token.

GET /oauth/userinfo
Authorization: Bearer <access_token>

Parameters

ParameterLocationRequiredDescription
AuthorizationHeaderYesBearer <access_token>

Example

curl -H "Authorization: Bearer ACCESS_TOKEN_HERE" \
  "https://api.singlesign.com/oauth/userinfo"

Response

{
  "sub": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "human_guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Jane Doe",
  "given_name": "Jane",
  "family_name": "Doe",
  "email": "jane@example.com",
  "email_verified": true,
  "picture": "https://api.singlesign.com/avatars/jane.jpg"
}

Error Response

{
  "error": "invalid_token",
  "error_description": "The access token is expired or invalid."
}

5. JWKS

Retrieve the JSON Web Key Set used to verify token signatures. Cache the response and refresh it periodically or when signature verification fails.

GET /oauth/jwks?platform_guid=<guid>

Parameters

ParameterLocationRequiredDescription
platform_guidQueryYesYour platform identifier

Example

curl "https://api.singlesign.com/oauth/jwks?platform_guid=YOUR_PLATFORM_GUID"

Response

{
  "keys": [
    {
      "kty": "oct",
      "alg": "HS512",
      "use": "sig",
      "kid": "singlesign-key-1"
    }
  ]
}

6. Introspect

Validate a token and retrieve its metadata. This endpoint is intended for confidential clients (server-side applications) that need to verify a token's validity.

POST /oauth/introspect
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>

Parameters

ParameterLocationRequiredDescription
tokenBodyYesThe access token or refresh token to introspect
platform_guidBodyYesYour platform identifier
AuthorizationHeaderYesBasic auth with client_id:client_secret

Example

curl -X POST "https://api.singlesign.com/oauth/introspect" \
  -u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
  -d "token=ACCESS_TOKEN_HERE" \
  -d "platform_guid=YOUR_PLATFORM_GUID"

Active Token Response

{
  "active": true,
  "sub": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "human_guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "client_id": "your-client-id",
  "scope": "openid profile email",
  "token_type": "Bearer",
  "exp": 1740000000,
  "iat": 1739996400
}

Inactive Token Response

{
  "active": false
}

7. Revoke

Revoke an access token or refresh token. After revocation, the token can no longer be used. Always revoke refresh tokens when a user logs out.

POST /oauth/revoke
Content-Type: application/x-www-form-urlencoded

Parameters

ParameterLocationRequiredDescription
tokenBodyYesThe access token or refresh token to revoke
platform_guidBodyYesYour platform identifier

Example

curl -X POST "https://api.singlesign.com/oauth/revoke" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=ACCESS_OR_REFRESH_TOKEN_HERE" \
  -d "platform_guid=YOUR_PLATFORM_GUID"

Response

The revoke endpoint returns 200 OK with an empty body on success, regardless of whether the token was valid. This prevents token existence probing.

HTTP/1.1 200 OK
Content-Length: 0

If the request is malformed:

{
  "error": "invalid_request",
  "error_description": "The 'token' parameter is required."
}

Error Response Format

All endpoints return errors in a consistent format:

{
  "error": "error_code",
  "error_description": "A human-readable description of the error."
}

See the Errors Reference for a complete list of error codes and troubleshooting tips.


Next Steps

Last updated: 2026-08-04