---
title: "Exchange an OAuth Code"
method: POST
path: "/v2/register-temp/exchange-code"
tags: ["register-temp"]
---

# Exchange an OAuth Code

`POST /v2/register-temp/exchange-code`

## Request

- Base URL: `https://api.stuut.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.stuut.ai/v2/register-temp/exchange-code`
- Auth: HTTP bearer

Verifies an auth0 authorization code. For a new identity, returns a registration token
plus prefill suggestions for the registration form. If the email already belongs to an
account/tenant, the exchange has already produced a valid session, so the user is logged
in directly: returns ExistingAccountSession (with the session tokens + refresh cookie)
instead, and the frontend goes straight into the app. Discriminate by which response
shape comes back (registration_token vs. access_token).

## Request body

- ExchangeCodeRequest: Exchange an auth0 authorization code (hosted-login / social callback) for a registration token. The IdP has already verified the email.
  - `authorization_code` string, required: The auth0 authorization code to exchange.
  - `redirect_uri` string, required: The redirect URI the code was issued for.

## Response `200`

Successful Response

- union
  - RegistrationTokenResponse: A short-lived token proving a verified identity, plus prefill suggestions for the registration form. Pass the token (and the final org/profile details) to ``/register``.
    - `registration_token` string, required: Opaque token to pass to /register.
    - `email` string, required: The verified email address.
    - `given_name` string, nullable, required: Suggested given name (from the IdP for oauth; null for email/password).
    - `family_name` string, nullable, required: Suggested family name (from the IdP for oauth; null for email/password).
    - `suggested_organization` OrganizationSuggestion, required: Prefill values for the registration form, derived from the verified email's domain and brand intelligence.
      - `display_name` string, nullable, required: Suggested organization display name.
      - `name` string, nullable, required: Suggested (deduped) unique tenant identifier.
      - `logo_url` string, nullable, required: Suggested brand logo URL, if one was found.
    - `joinable_organization` JoinableOrg, required: An existing organization the verified email can join instead of (or in addition to) founding a new one — either via a pending invite or because the org auto-provisions the email's domain. Surfaced so the frontend can offer 'join organization vs. create new'.
      - `organization_id` string, required: ID of the joinable org — pass as `organization` to /register to join it (the email is already verified, so this fully identifies eligibility).
      - `organization_name` string, required: Display name of the organization.
      - `organization_logo_url` string, nullable, required: Logo of the organization, if it has one.
  - ExistingAccountSession: Returned by /exchange-code when the OAuth identity already belongs to an account: the code exchange already produced a valid session, so the user is logged in directly instead of registering. The frontend redirects into the app rather than the reg form (discriminate from RegistrationTokenResponse by the access_token field).
    - `email` string, required: The verified email address.
    - `access_token` string, required: Bearer access token for the session.
    - `expires_at` string, required: ISO-8601 timestamp when the access token expires.
    - `id_token` string, nullable, required: OIDC id token, if issued.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/stuut/apis/stuut-api.md) - [All operations](https://skmtc.dev/stuut/apis/stuut-api/llms.txt) - [OpenAPI document](https://skmtc.dev/stuut/apis/stuut-api/revisions/ff0ad16a55ff?raw)
