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

# Exchange JWT

> Exchange a short-lived JWT issued by a Nexudus server-side flow for a bearer token that authenticates subsequent API requests.

# Exchange JWT

Converts a one-time JWT — issued during sign-up, email verification, password reset, or magic-link flows — into a standard bearer token and refresh token pair. The portal calls this immediately after any server-side operation that returns a raw JWT, so the customer is signed in without ever entering their password.

<Note>
  This endpoint is intended for server-issued JWTs passed back to the client (e.g. as part of a sign-up response). It is **not** for exchanging a
  customer's email and password — use `POST /api/token` for credential-based sign-in.
</Note>

## Authentication

No authentication required. The JWT in the `token` parameter acts as the credential.

## Query Parameters

<ParamField query="token" type="string" required>
  The short-lived JWT to exchange. URL-encode this value. Obtained from server-side flows such as the sign-up response (`Token` field) or a magic-link
  email.
</ParamField>

<ParamField query="validForInMinutes" type="number" required>
  Lifetime of the issued bearer token in minutes. The portal passes `1440` (24 hours) for standard sign-in sessions.
</ParamField>

## Response

<ResponseField name="token" type="string">
  Bearer token to include in the `Authorization` header of all subsequent authenticated requests.
</ResponseField>

<ResponseField name="token_type" type="string">
  Token scheme. Always `bearer`.
</ResponseField>

<ResponseField name="expires_in" type="number">
  Lifetime of the bearer token in seconds.
</ResponseField>

<ResponseField name="refresh_token" type="string">
  Token used to obtain a new bearer token after it expires without requiring the customer to re-authenticate.
</ResponseField>

## Examples

### Exchange a JWT after sign-up

```http theme={null}
POST /api/sys/users/exchange?token=eyJhbGciOiJSUzI1NiJ9...&validForInMinutes=1440
```

```json theme={null}
{
  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 86400,
  "refresh_token": "7kMpQxRtZn2"
}
```

## TypeScript Integration

```typescript theme={null}
import endpoints from '@/api/endpoints'
import { ExchangedToken } from '@/states/useAuthContext'

// `rawJwt` is the `Token` field returned by e.g. the sign-up endpoint
const response = await httpClient.post<ExchangedToken>(endpoints.system.auth.login(rawJwt))

if (response.data.token) {
  await saveSession({
    tokenResponse: {
      access_token: response.data.token,
      token_type: response.data.token_type,
      expires_in: response.data.expires_in,
      refresh_token: response.data.refresh_token,
    },
  })
}
```

The endpoint key `endpoints.system.auth.login(token)` builds the URL as:

```
/api/sys/users/exchange?token=${encodeURIComponent(token)}&validForInMinutes=1440
```

## Usage in Portal

| Context                                        | Source file                                           |
| ---------------------------------------------- | ----------------------------------------------------- |
| Magic-link / email-verification sign-in        | `src/states/useAuthContext.tsx` (`exchangeToken`)     |
| Sign-up flow — embedded checkout (`/checkout`) | `src/views/checkout/SignupUserPage.tsx`               |
| Sign-up flow — public checkout (`/join`)       | `src/views/public/checkout/components/SignupForm.tsx` |

## Error Responses

<ResponseField name="400 Bad Request" type="error">
  The `token` parameter is missing, malformed, or has already been used. The JWT issued by Nexudus flows is single-use and expires quickly.
</ResponseField>

<ResponseField name="401 Unauthorized" type="error">
  The JWT signature is invalid or it was issued for a different Nexudus space.
</ResponseField>

## Related Endpoints

| Method | Endpoint                               | Description                                                    |
| ------ | -------------------------------------- | -------------------------------------------------------------- |
| `POST` | `/api/token`                           | Exchange a customer's email and password for a bearer token    |
| `POST` | `/api/sys/users/token/refresh`         | Obtain a new bearer token using a refresh token                |
| `GET`  | `/api/sys/users/impersonate`           | Issue an impersonation token for a specific customer           |
| `POST` | `/api/sys/users/startPasswordReset`    | Trigger the password-reset email (returns a JWT for this flow) |
| `POST` | `/api/sys/users/completePasswordReset` | Complete password reset and exchange the resulting JWT         |
