Skip to main content

GET /v1/auth/oauth/:provider/callback

The provider redirects here after the user consents (or denies). Exchanges the authorization code for a user identity, creates a user + organization if needed, and issues a browser session.

::: tip Auth Required: none. Validated state token IS the credential. :::

Request

GET /v1/auth/oauth/:provider/callback?code=...&state=...

Path paramNotes
providerMust match the provider used in /start.
Query paramNotes
codeProvider-issued authorization code.
stateThe state token issued by /start.
errorIf the provider returns an error here, IdentSphere redirects back to the original redirect_to with ?oauth_error=....

Response

307 Temporary Redirect (success)

Location is {public_base_url}{redirect_to} (the path captured at /start). Session cookies are set: identsphere_at, identsphere_rt, identsphere_csrf.

307 Temporary Redirect (provider error)

Location is {public_base_url}{redirect_to}?oauth_error={percent_encoded}. Your app reads oauth_error from the query string to display a message.

Error responses

StatusCodeWhen
400invalid_inputState missing, state expired, provider mismatch between start and callback, or code missing.
401authentication_requiredProvider rejected the code exchange, OR the matched user account is disabled.
404not_foundUnknown provider OR provider not configured.
500internal_errorNetwork, JSON parsing, or DB failure.

Notes

  • New users get a fresh organization (owner role) and have email_verified set to true (the provider already verified the address).
  • Existing users with the same email are signed into their existing organization — no second org is created.
  • An audit entry (auth.oauth.google.linked or auth.oauth.github.linked) is recorded.
  • The state token is single-use; it is invalidated at the top of the callback regardless of outcome.
  • The session is minted at AAL1 with auth_method: "social_oauth".