# Token Management

The Deva SDK handles OAuth tokens automatically, including retrieval, storage, and refresh. This document covers both access token retrieval and refresh processes.

***

## Retrieve Access Token

The access token is automatically obtained when a user logs in through the SDK. You can retrieve it using the `useDeva` hook.

### Using the useDeva Hook

The access token is available through the `useDeva` hook:

```tsx
import { useDeva } from "@bitplanet/deva-sdk";

function MyComponent() {
  const { accessToken, isAuthenticated } = useDeva();

  if (!isAuthenticated) {
    return <div>Please log in</div>;
  }

  console.log("Access Token:", accessToken);
  return <div>Token retrieved</div>;
}
```

### When You Need the Access Token

#### SDK Components (No Token Needed)

The SDK automatically includes the access token in all API calls. You don't need to manually retrieve or pass the token when using SDK components like `ChannelFeed` or `Intercom`.

#### Custom API Calls (Token Required)

You need the access token when making direct API calls to Deva endpoints outside the SDK:

```tsx
import { useDeva } from "@bitplanet/deva-sdk";

function MyComponent() {
  const { accessToken } = useDeva();

  const fetchCustomData = async () => {
    const response = await fetch("https://www.deva.me/api/custom-endpoint", {
      headers: {
        "Authorization": `Bearer ${accessToken}`
      }
    });
    const data = await response.json();
    return data;
  };

  return <button onClick={fetchCustomData}>Fetch Data</button>;
}
```

***

## Token Refresh

Access tokens have a short lifetime (typically 15 minutes). When they expire, they must be refreshed using a refresh token to maintain user sessions without requiring re-login.

### Automatic Refresh (SDK)

The **Deva SDK handles token refresh automatically**. You don't need to manually refresh tokens when using the SDK.

#### How It Works

1. **Background Monitoring** - The SDK checks token expiration every \~1 second (with random stagger to prevent simultaneous requests)
2. **Automatic Refresh** - When the token is about to expire, the SDK requests a new one
3. **Seamless Updates** - New tokens are stored automatically
4. **No Interruption** - Your app continues working without user intervention

Learn more about the [OAuth Token Refresh](/authentication/oauth-integration.md#token-refresh-flow) flow.

#### What You Need to Do

**Nothing.** The SDK manages the entire refresh lifecycle:

```tsx
import { useDeva } from "@bitplanet/deva-sdk";

function MyComponent() {
  const { accessToken, isAuthenticated } = useDeva();

  // The token is always fresh - no manual refresh needed
  // SDK refreshes automatically before expiration

  return <div>Token: {accessToken}</div>;
}
```

### Manual Refresh (Advanced)

For server-side applications or custom implementations, you can manually refresh tokens using the token endpoint.

#### Endpoint

```
POST {content_server_url}/oidc/token
Content-Type: application/json
{
    "refresh_token": "{refresh_token}",
    "client_id": "{client_id}",
    "expires_in": 120
}
```

#### Request Parameters

| Parameter       | Type   | Required | Description                                                                 |
| --------------- | ------ | -------- | --------------------------------------------------------------------------- |
| `client_id`     | string | Yes      | Your application's client ID                                                |
| `refresh_token` | string | Yes      | The refresh token received during login                                     |
| `expires_in`    | number | No       | Custom token expiration time in seconds (default: 900 seconds / 15 minutes) |

#### Response

```json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "new-refresh-token",
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 900,
  "expires_at": "2025-10-31T10:17:47.273514Z",
}
```

#### Response Fields

| Field           | Description                                  |
| --------------- | -------------------------------------------- |
| `access_token`  | New access token for API calls               |
| `refresh_token` | New refresh token (replace the old one)      |
| `id_token`      | New ID token with user information           |
| `expires_in`    | Token lifetime in seconds (900 = 15 minutes) |
| `expires_at`    | Token expiration timestamp                   |

***

## Token Lifecycle

### Automatic Management

* **Obtained**: When user completes login
* **Stored**: Automatically in browser storage
* **Refreshed**: Automatically before expiration
* **Cleared**: When user logs out

### Token Properties

* **Format**: JWT (JSON Web Token)
* **Lifetime**: Typically 15 minutes
* **Usage**: Include in `Authorization: Bearer {token}` header

### When Refresh Happens

#### SDK Behavior

* **Proactive**: Refreshes before token expires (30 seconds buffer)
* **Frequency**: Checks every \~1 second with random stagger
* **Timing**: Refreshes when token expiration is detected
* **Storage**: Automatically updates stored tokens

#### Manual Refresh Timing

If implementing manual refresh:

* Refresh before the access token expires
* Don't wait until API calls fail
* Store the new refresh token for next time
* Each refresh token can only be used once

***

## Important Notes

### Refresh Token Lifecycle

* **One-Time Use**: Each refresh token is valid for one refresh only
* **New Token**: Every refresh returns a new refresh token
* **Replace Old Token**: Always replace the old refresh token with the new one
* **Long Lifetime**: Refresh tokens last much longer than access tokens (days/weeks)

### Security

**Do Not Store Manually** The SDK manages token storage automatically. You don't need to save the token to localStorage or sessionStorage yourself.

**Token Expiration** Access tokens expire after a short time. The SDK automatically refreshes them using the refresh token. Always retrieve the token when needed rather than storing it in component state.

**Best Practices**

* Never expose tokens in console logs in production
* Never send tokens to third-party services
* Always use HTTPS in production
* **Store Securely**: Keep refresh tokens secure (SDK handles this automatically)
* **Revoke on Logout**: Refresh tokens are revoked when user logs out

### Error Handling

**Invalid Refresh Token**

* The refresh token has expired or been revoked
* User must log in again
* SDK handles this automatically by clearing auth state

**Client ID Mismatch**

* The `client_id` doesn't match the refresh token
* Verify you're using the correct credentials from your Deva app settings

***

## Related Documentation

* [Authentication Flow](/core-concepts/authentication-flow.md) - How authentication works
* [OAuth Integration](/authentication/oauth-integration.md) - Complete OAuth flow details
* [Login Implementation](/authentication/login-implementation.md) - Implement login functionality
* [Logout Handling](/authentication/logout-handling.md) - Token revocation on logout
* [Deva SSO](/authentication/deva-sso.md) - Why use Deva authentication


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sdkdocs.deva.me/authentication/token-management.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
