> ## Documentation Index
> Fetch the complete documentation index at: https://apidocs.cacolombia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth 2.0 Provider Callback — GET /v1/oauth/:provider

> The OAuth 2.0 provider callback endpoint. Validates the state token, exchanges the authorization code for a session, and sets access and refresh cookies.

After a user grants consent on the provider's authorization page, the provider automatically redirects them to this endpoint with a short-lived `code` and the original `state` token appended as query parameters. You do not call this endpoint directly — you configure it as the **redirect URI** when registering your OAuth application with Discord or Roblox, and the provider calls it on your behalf.

## Endpoint

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

## Path Parameters

<ParamField path="provider" type="string" required>
  The OAuth provider completing the flow. Must be one of:

  * `discord`
  * `roblox`
</ParamField>

## Query Parameters

<ParamField query="state" type="string" required>
  The opaque state token originally issued by `POST /v1/oauth/:provider`. The server validates this value against its cache to confirm the callback belongs to a legitimate, unexpired authorization request.
</ParamField>

<ParamField query="code" type="string" required>
  The short-lived authorization code issued by the provider after the user consents. The server exchanges this code for the user's access and refresh tokens on your behalf — you never handle the provider tokens directly.
</ParamField>

## Behavior

When the server receives a valid callback it:

1. Looks up the `state` value in its server-side cache to retrieve the original `redirectUrl` and associated user context.
2. Exchanges the `code` with the provider (Discord or Roblox) for that provider's access and refresh tokens.
3. Fetches the user's profile from the provider and resolves or creates the corresponding CA Colombia user record.
4. Issues a fresh pair of CA Colombia session tokens (or refreshes any existing tokens found in your cookies).
5. Sets two `HttpOnly` cookies on the response:
   * **Access token** — valid for **24 hours**.
   * **Refresh token** — valid for **8 days**.
6. Redirects your browser to the original `redirectUrl` with the `state` query parameter appended so your application can verify the round-trip.

## Cookies Set

| Cookie        | Lifetime | Purpose                                              |
| ------------- | -------- | ---------------------------------------------------- |
| Access token  | 24 hours | Authenticates subsequent API requests                |
| Refresh token | 8 days   | Obtains a new access token without re-authenticating |

The cookies are `HttpOnly` and scoped to the CA Colombia domain. Your client-side JavaScript cannot read them directly; they are forwarded automatically by the browser on each request when you use `credentials: 'include'`.

## After a Successful Callback

Your browser is redirected to:

```
{redirectUrl}?state={state}
```

You can read the `state` parameter on your callback page to confirm the flow completed successfully and then update your application UI accordingly.

## Error Handling

<Warning>
  This endpoint does **not** return JSON error responses. If anything goes wrong — an invalid or expired `state`, a bad authorization `code`, an unresolvable user, or a missing IP address — the server redirects the browser to the site root (`/`) instead. Check the final redirect destination to detect failures; a redirect to the root indicates the OAuth flow did not complete successfully.
</Warning>

Common reasons a callback might fail:

* The `state` token has expired or was never issued (the original `POST /v1/oauth/:provider` was never called).
* The `code` provided by the provider has already been used or has expired.
* You are attempting to link a Roblox account but no CA Colombia user account exists for the session yet (Roblox linking requires an existing account).
* The request originated from an IP address that could not be resolved.

If your users are landing on the root instead of your `redirectUrl`, initiate a fresh OAuth flow by calling `POST /v1/oauth/:provider` again.

<Note>
  For **Roblox** OAuth specifically, the user must already have a CA Colombia account (created via a prior Discord login) before linking their Roblox identity. Attempting a Roblox flow without an existing account will result in a redirect to the root.
</Note>
