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

# Token Refresh

> Renew user sessions with refreshAccessToken()

<Info>
  Start with [Authentication](/recipes/authentication) for the initial sign-in flow. This page
  covers what to do after a user session already exists.
</Info>

Access tokens expire. When a protected request returns `401`, use the stored refresh token to get a
new access token without sending the user through sign-in again.

When the SDK client is configured with `authDelivery: "cookie-refresh"`, `refreshAccessToken()`
still works, but the refresh token comes from the API's `HttpOnly` cookie instead of local storage.
The cookie stays scoped to the AGG API host and `/auth` routes only.

## Manual refresh

```typescript theme={null}
try {
  const balances = await client.getManagedBalances();
} catch (err: any) {
  if (err.status === 401 && client.isAuthenticated) {
    await client.refreshAccessToken();

    // Retry the original request after the SDK updates the stored session.
    const balances = await client.getManagedBalances();
  } else {
    throw err;
  }
}
```

## Wrap protected calls

```typescript theme={null}
async function withAutoRefresh<T>(fn: () => Promise<T>): Promise<T> {
  try {
    return await fn();
  } catch (err: any) {
    if (err.status === 401 && client.isAuthenticated) {
      try {
        await client.refreshAccessToken();
        return await fn();
      } catch {
        await client.signOut();
        throw new Error("Session expired. Please sign in again.");
      }
    }

    throw err;
  }
}

const balances = await withAutoRefresh(() => client.getManagedBalances());
```

## React to sign-out

When refresh fails, clear the session and send the user back through authentication:

```typescript theme={null}
client.onAuthStateChange((authenticated) => {
  if (!authenticated) {
    router.push("/sign-in");
  }
});
```

<Note>
  If you are also streaming authenticated WebSocket events, refresh the REST session first and then
  re-authenticate or reconnect the socket. See [User Notifications](/recipes/websocket-notifications).
</Note>
