> ## 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.

# Refresh Token

> Exchange the current session for a short-lived server-side token used to construct authenticated redirect URLs without exposing the bearer token in the URL.

# Refresh Token

Issues a short-lived, opaque server-side token tied to the authenticated customer's session. The portal uses this token exclusively to build redirect URLs that require the customer to land in an authenticated state on the legacy server-rendered side of Nexudus — for example, when opening a file download or navigating to a server-rendered page from within the React portal. The token is placed in the URL (`?t=`) and is **not** the bearer token itself.

<Note>
  This is not an OAuth token-refresh operation. It does not rotate the bearer token or the `refresh_token` held by the client. Use `POST /api/token`
  with `grant_type=refresh_token` to renew an expiring bearer token instead.
</Note>

## Authentication

Requires a valid customer bearer token.

## Request Body

This endpoint accepts no body parameters. Send the request with no body; authentication is established entirely via the `Authorization` header.

## Response

Returns an `ActionConfirmation` envelope.

<ResponseField name="WasSuccessful" type="boolean" required>
  `true` when a server-side token was issued successfully. The component rendering the authenticated link should remain disabled until this is `true`.
</ResponseField>

<ResponseField name="Value" type="string | null">
  The short-lived opaque token string. Append this as the `t` query parameter when constructing authenticated redirect URLs, e.g.
  `/user/login?server=true&t={Value}&redirectUrl=...`. `null` when `WasSuccessful` is `false`.
</ResponseField>

<ResponseField name="Status" type="number">
  HTTP-style status code mirrored in the response body. `200` on success, `500` on failure.
</ResponseField>

<ResponseField name="Message" type="string | null">
  Human-readable message. Usually `null` on success.
</ResponseField>

<ResponseField name="Errors" type="any">
  Validation or server errors. `null` on success.
</ResponseField>

## Examples

### Successful token refresh

```http theme={null}
POST /api/sys/users/token/refresh
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
```

```json theme={null}
{
  "WasSuccessful": true,
  "Value": "a3f8c2d1e5b74091bc6e2f3a4d5c6b7e",
  "Status": 200,
  "Message": null,
  "Errors": null
}
```

### Using the token in a redirect URL

Once `WasSuccessful` is `true`, construct the authenticated URL as follows:

```
{NativeHomeUrlWithLanguage}/user/login?server=true&t={Value}&redirectUrl={encodeURIComponent(targetPath)}
```

For example:

```
https://app.example.com/en/user/login?server=true&t=a3f8c2d1e5b74091bc6e2f3a4d5c6b7e&redirectUrl=%2Fen%2Finvoices%2Fdownload%2F42
```

## TypeScript Integration

```typescript theme={null}
import endpoints from '@/api/endpoints'
import { useTypedData } from '@/api/fetchData'
import { createShape } from '@/helpers/shape-helper'
import { ActionConfirmation } from '@/types/ActionConfirmation'

const endpoint = endpoints.system.auth.refresh()

// Request only the two fields needed to build the redirect URL
const shape = createShape<typeof endpoint.type>()(['Value', 'WasSuccessful'])

const { resource: tokenData } = useTypedData(httpClient, endpoint, shape, { method: 'post' })

// tokenData?.WasSuccessful === true means the link is ready to use
// tokenData?.Value is the opaque token to embed in the redirect URL
const wrappedUrl = `${business.NativeHomeUrlWithLanguage}/user/login?server=true&t=${tokenData?.Value}&redirectUrl=${encodeURIComponent(href)}`
```

## Usage in Portal

| Context                                                       | Source file                            |
| ------------------------------------------------------------- | -------------------------------------- |
| Authenticated redirect links (e.g. file downloads, PDF views) | `src/components/AuthenticatedLink.tsx` |

## Error Responses

<ResponseField name="401 Unauthorized" type="error">
  The bearer token is missing, expired, or invalid. The customer must sign in again via `POST /api/token`.
</ResponseField>

## Related Endpoints

| Method | Endpoint                   | Description                                                             |
| ------ | -------------------------- | ----------------------------------------------------------------------- |
| `POST` | `/api/token`               | Exchange email and password (or a refresh token) for a new bearer token |
| `POST` | `/api/sys/users/exchange`  | Exchange a server-issued JWT for a bearer token                         |
| `GET`  | `/api/auth/media/customer` | Obtain a short-lived JWT for accessing protected media files            |
