> Source: https://wexa.ai/docs/sdks-and-apis/refresh-session

# refresh-session

Trade an SDK session's refresh token for a new access token and a new refresh token. The old refresh token stops working at once. A refresh token works exactly once: if one is presented a second time, Wexa treats it as stolen and ends the whole session, so log the user in again. `refresh-session` is not on the MCP server.

**Refresh a session**

**REST API**

```bash
curl -sS https://fabric.wexa.ai/v1/auth/refresh \
  -H "content-type: application/json" \
  -d '{"refresh_token": "'"$FABRIC_REFRESH_TOKEN"'"}'
```

```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
  "refresh_token": "fab_srt_ixnbhT…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "session_id": "sess_Ss5LcvniPbkIkWERMiY8YUAO"
}
```

**TypeScript SDK**

```ts
// Resolves to { accessToken, refreshToken, expiresAt }
const tokens = await fabric.auth.refresh()
```

**Python SDK**

```python
# Returns {"access_token", "refresh_token", "expires_at"}
tokens = fabric.auth.refresh()
```

## Parameters

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `refresh_token` | string | Required | The newest refresh token of the session. A missing one is refused (400). One from an ended session, or already used or expired, is refused (401, `invalid_grant`). The SDKs send it for you and take no arguments. |

**Errors**

- `AuthError` (401): the session has ended (`invalid_grant`): it was logged out, revoked by an admin or by the user, ended by a password reset, password change, suspension or account removal, or the refresh token was already used or has expired. Log the user in again.
- `ForbiddenError` (403): the user is no longer a member of the project, or the call came from a browser origin that is not allowed.
- `UpstreamError` (502): the account service behind the gateway could not be reached. The refresh token is not used up, so retrying later can help.

**Show full response**

A real response, captured from a live call to `refresh-session`. The session id stays the same; both tokens are new. The tokens are cut short here:

**Result of refresh-session**

**REST API**

```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
  "refresh_token": "fab_srt_ixnbhT…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "org_id": "6a79a770b6c128ccc24bfca8",
  "project_id": "6aa9beb7ec8121a43b6c791b",
  "session_id": "sess_Ss5LcvniPbkIkWERMiY8YUAO",
  "grants": ["fabric:query.read", "fabric:docs.read", "fabric:orchestrate.read", "fabric:model.run"]
}
```

**TypeScript SDK**

```ts
{
  accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…',
  refreshToken: 'fab_srt_ixnbhT…',
  expiresAt: 1790257200
}
```

**Python SDK**

```python
{
 "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
 "refresh_token": "fab_srt_ixnbhT…",
 "expires_at": 1790257200.0
}
```

`grants` is shortened here; the real response lists every grant the user's current role gives, or the narrowed list from [login](/docs/sdks-and-apis/login).

**More details**

Both SDKs refresh for you shortly before the access token runs out, and again if a call comes back with an expired token, so you only call it yourself when you want to control the timing. Save every new pair: the SDKs pass it to your token callback.

`ConfigurationError` is raised in the SDK when the client was built with an API key, which has nothing to refresh.

Not a governed tool: it runs before any tool call. Each refresh checks the user's membership and role in the project again.

See [login](/docs/sdks-and-apis/login) and [logout](/docs/sdks-and-apis/logout). When and how to use sessions is in [Authentication](/docs/get-started/authentication).

Every tool call works the same way: [How every tool call works](/docs/sdks-and-apis/how-every-tool-call-works).
