---
title: "OAuth2 provider callback endpoint"
method: GET
path: "/signin/provider/{provider}/callback"
tags: ["authentication", "excludeme"]
---

# OAuth2 provider callback endpoint

`GET /signin/provider/{provider}/callback`

Handles the callback from OAuth2 providers after user authorization. Processes the authorization code and creates a user session.
This endpoint is where the signin-vs-signup decision (from the signed `flow` state claim) and the `AUTH_DISABLE_AUTO_SIGNUP` gate are actually enforced: on a `flow=signin` state with an unknown user and the flag enabled, the user is redirected with `error=invalid-email-password`; on a `flow=signup` state with an existing user, the user is redirected with `error=user-already-exists`.

## Path parameters

- `provider` 'apple' | 'github' | 'google' | 'linkedin' | 'discord' | 'spotify' | 'twitch' | 'gitlab' | 'bitbucket' | 'workos' | 'azuread' | 'entraid' | 'strava' | 'facebook' | 'windowslive' | 'twitter', required

## Query parameters

- `code` string
- `id_token` string
- `state` string, required
- `oauth_token` string
- `oauth_verifier` string
- `error` string
- `error_description` string
- `error_uri` string

## Response `default`

An error occurred while processing the request

- ErrorResponse — Standardized error response
  - `status` integer, required — HTTP status error code
  - `message` string, required — Human-friendly error message
  - `error` 'default-role-must-be-in-allowed-roles' | 'disabled-endpoint' | 'disabled-user' | 'user-already-exists' | 'email-already-verified' | 'forbidden-anonymous' | 'internal-server-error' | 'invalid-email-password' | 'invalid-request' | 'locale-not-allowed' | 'password-too-short' | 'password-in-hibp-database' | 'redirectTo-not-allowed' | 'role-not-allowed' | 'signup-disabled' | 'unverified-user' | 'user-not-anonymous' | 'invalid-pat' | 'invalid-refresh-token' | 'invalid-ticket' | 'disabled-mfa-totp' | 'no-totp-secret' | 'invalid-totp' | 'mfa-type-not-found' | 'totp-already-active' | 'invalid-state' | 'oauth-token-echange-failed' | 'oauth-profile-fetch-failed' | 'oauth-provider-error' | 'invalid-otp' | 'otp-too-many-attempts' | 'cannot-send-sms' | 'provider-account-already-linked', required — Error code identifying the specific application error

## Other responses

- `302` — Redirect to client application after successful authentication

## Changes

- **2026-06-24** `0fc5fd589dbf` — 1 warning
  - added the new `otp-too-many-attempts` enum value to the `error` response property for the response status `default`
- **2026-04-20** `b39086c84b43` — 1 warning, 1 info
  - added the new `user-already-exists` enum value to the `error` response property for the response status `default`
  - removed the `email-already-in-use` enum value from the `error` response property for the response status `default`
- **2025-11-11** `484d9f1a422a` — 1 warning
  - added the new `provider-account-already-linked` enum value to the `error` response property for the response status `default`
- **2025-10-28** `ca6d11a13264` — 1 info
  - `path` request parameter `provider` was reactivated
- **2025-10-09** `2bb5c4e40463` — 1 warning, 4 info
  - added the new `email-already-in-use` enum value to the `error` response property for the response status `default`
  - `path` request parameter `provider` was deprecated
  - removed the `otp-too-many-attempts` enum value from the `error` response property for the response status `default`
  - removed the `provider-account-already-linked` enum value from the `error` response property for the response status `default`
  - …1 more

[Change history](https://skmtc.dev/nhost/apis/nhost-authentication-api/changes/signin/provider/:provider/callback/get.md)

---

[API](https://skmtc.dev/nhost/apis/nhost-authentication-api.md) · [All operations](https://skmtc.dev/nhost/apis/nhost-authentication-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/nhost/nhost-authentication-api/revisions/a5c0d88b55c4/schema)
