---
title: "B24OAuth Class"
description: "Server-side entry point for talking to the Bitrix24 REST API with an OAuth 2.0 access token (and automatic refresh)."
canonical_url: "https://bitrix24.github.io/b24jssdk/docs/working-with-the-rest-api/oauth"
last_updated: "2026-06-02"
---
# B24OAuth Class

> Server-side entry point for talking to the Bitrix24 REST API with an OAuth 2.0 access token (and automatic refresh).

> [!CAUTION]
> The `B24OAuth` object is intended **exclusively for use on the server**.
> - The `clientSecret`, access token, and refresh token must never appear in browser code.
> - Client-side warning is enabled on both HTTP clients by default; see [`offClientSideWarning`](#offclientsidewarning).
> - For client-side scenarios use [`B24Frame`](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/frame.md).

## Overview

`B24OAuth` is the SDK entry point for [OAuth 2.0 local applications](https://apidocs.bitrix24.com/settings/oauth/index.html). It accepts an existing token pair (issued by Bitrix24 during installation), uses the access token for REST calls, and refreshes the pair through `oauth.bitrix.info` when the access token expires.

The class extends `AbstractB24` and implements [`TypeB24`](https://github.com/bitrix24/b24jssdk/blob/main/packages/jssdk/src/types/b24.ts), so the full REST surface (`actions.v2.*`, `actions.v3.*`, `tools.*`) is available immediately after construction — there is no `await b24.init()` step.

## Creating a B24OAuth Instance

```ts
import { B24OAuth, EnumAppStatus } from '@bitrix24/b24jssdk'

const $b24 = new B24OAuth(
  // 1) Token data received from Bitrix24 (event payload, OAuth handshake, etc.)
  {
    applicationToken: '<your_application_token>',
    userId: 1,
    memberId: '<your_member_id>',
    accessToken: '<your_access_token>',
    refreshToken: '<your_refresh_token>',
    expires: 1745997853,        // unix timestamp, seconds
    expiresIn: 3600,            // seconds
    scope: 'crm,catalog,user_brief',
    domain: 'your_domain.bitrix24.com',
    clientEndpoint: 'https://your_domain.bitrix24.com/rest/',
    serverEndpoint: 'https://oauth.bitrix.info/rest/',
    status: EnumAppStatus.Free
  },
  // 2) Application credentials issued in Bitrix24 → Developers → Applications
  {
    clientId: 'local.xxxxxx.xxxxxx',
    clientSecret: '<your_client_secret>'
  }
)

const response = await $b24.actions.v2.call.make({
  method: 'tasks.task.list',
  params: { select: ['ID', 'TITLE', 'STATUS'] },
  requestId: 'tasks-list'
})
```

### Constructor Signature

```ts-type
constructor(
  authOptions: B24OAuthParams,
  oAuthSecret: B24OAuthSecret,
  options?: { restrictionParams?: Partial<RestrictionParams> }
)
```

### `B24OAuthParams` Fields

| Field | Type | Description |
| --- | --- | --- |
| `applicationToken` | `string` | Application token issued at install time. |
| `userId` | `number` | Identifier of the user the token belongs to. |
| `memberId` | `string` | Portal member id. |
| `accessToken` | `string` | Current access token. |
| `refreshToken` | `string` | Refresh token used by `refreshAuth` . |
| `expires` | `number` | Access token expiration (unix timestamp, **seconds** ). |
| `expiresIn` | `number` | Token lifetime, seconds. |
| `scope` | `string` | Comma-separated scopes (e.g. `crm,catalog,user_brief` ). |
| `domain` | `string` | Portal domain (`xxx.bitrix24.com` ). |
| `clientEndpoint` | `string` | Portal REST root, e.g. `https://xxx.bitrix24.com/rest/` . |
| `serverEndpoint` | `string` | OAuth server, usually `https://oauth.bitrix.info/rest/` . |
| `status` | `TypeEnumAppStatus` | One of `EnumAppStatus.Free/Demo/Trial/Paid/Local/Subscription` . |

### `B24OAuthSecret` Fields

| Field | Type | Description |
| --- | --- | --- |
| `clientId` | `string` | OAuth `client_id` of your application. |
| `clientSecret` | `string` | OAuth `client_secret` of your application. |

## Refresh Token Flow

`B24OAuth` refreshes the access token automatically when:

- a REST call returns `expired_token`, **or**
- `getAuthData()` is called and `expires <= Date.now()`.

The default refresh path calls `GET /oauth/token/` on `serverEndpoint` (typically `https://oauth.bitrix.info/rest/`) with `grant_type=refresh_token`, the supplied `refreshToken`, `clientId`, and `clientSecret`. On success the manager updates `accessToken`, `refreshToken`, `expires`, `expiresIn`, `clientEndpoint`, `serverEndpoint`, `scope`, and `status`.

If the refresh request fails, the SDK throws [`RefreshTokenError`](https://github.com/bitrix24/b24jssdk/blob/main/packages/jssdk/src/oauth/refresh-token-error.ts) (a subclass of `SdkError`) carrying `code`, `description`, and HTTP `status`.

### Persisting Refreshed Tokens

Register a callback so your app can persist the new token pair (DB, secrets manager, etc.):

// @check-ignore: B24OAuth-specific method, ambient $b24 is typed as B24Frame

```ts
$b24.setCallbackRefreshAuth(async ({ authData, b24OAuthParams }) => {
  await tokenStore.save({
    accessToken: b24OAuthParams.accessToken,
    refreshToken: b24OAuthParams.refreshToken,
    expires: b24OAuthParams.expires,
    expiresIn: b24OAuthParams.expiresIn,
    memberId: authData.member_id
  })
})
```

Remove with `$b24.removeCallbackRefreshAuth()`.

### Custom Refresh Logic

If your app fetches refresh tokens from a separate service (e.g. centralized token broker), supply a `CustomRefreshAuth` function. The SDK will call it instead of hitting `oauth.bitrix.info`:

// @check-ignore: B24OAuth-specific method, ambient $b24 is typed as B24Frame

```ts
import type { HandlerRefreshAuth } from '@bitrix24/b24jssdk'

$b24.setCustomRefreshAuth(async (): Promise<HandlerRefreshAuth> => {
  const fresh = await tokenBroker.fetch()
  return {
    access_token: fresh.accessToken,
    refresh_token: fresh.refreshToken,
    expires: fresh.expires,
    expires_in: fresh.expiresIn,
    client_endpoint: fresh.clientEndpoint,
    server_endpoint: fresh.serverEndpoint,
    member_id: fresh.memberId,
    scope: fresh.scope,
    status: fresh.status,
    domain: fresh.domain
  }
})
```

Remove with `$b24.removeCustomRefreshAuth()`.

## Methods

### `initIsAdmin`

```ts-type
initIsAdmin(requestId?: string): Promise<void>
```

Calls the `profile` REST method once and caches whether the authenticated user has admin rights. Required before reading [`auth.isAdmin`](#getter-auth) — the getter throws `Error('isAdmin not init. You need call B24OAuth::initIsAdmin().')` when called too early.

// @check-ignore: B24OAuth-specific method, ambient $b24 is typed as B24Frame

```ts
await $b24.initIsAdmin('boot:isAdmin')
if ($b24.auth.isAdmin) {
  // ...
}
```

### `setCallbackRefreshAuth` / `removeCallbackRefreshAuth`

```ts-type
setCallbackRefreshAuth(cb: CallbackRefreshAuth): void
removeCallbackRefreshAuth(): void
```

Register / unregister a callback executed after every successful refresh. See [Persisting Refreshed Tokens](#persisting-refreshed-tokens).

### `setCustomRefreshAuth` / `removeCustomRefreshAuth`

```ts-type
setCustomRefreshAuth(cb: CustomRefreshAuth): void
removeCustomRefreshAuth(): void
```

Register / unregister a custom refresh implementation. See [Custom Refresh Logic](#custom-refresh-logic).

### `offClientSideWarning`

```ts-type
offClientSideWarning(): void
```

Disables the runtime warning emitted when `B24OAuth` is detected in a browser environment. Use only when you proxy the OAuth tokens through a server-side wrapper.

### `getTargetOrigin` / `getTargetOriginWithPath`

```ts-type
getTargetOrigin(): string
getTargetOriginWithPath(): Map<ApiVersion, string>
```

Return the portal origin (e.g. `https://xxx.bitrix24.com`) and the per-version REST endpoints derived from `clientEndpoint`.

### `getHttpClient` / `setHttpClient` / `setRestrictionManagerParams` / `getLogger` / `setLogger` / `destroy`

Inherited from `AbstractB24` — same shape as on `B24Hook` and `B24Frame`. See:

- [Limiters](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/limiters.md) — `setRestrictionManagerParams`.
- [Logger](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/logger.md) — `getLogger` / `setLogger`.

## Getters

### `auth`

Returns the [`AuthOAuthManager`](https://github.com/bitrix24/b24jssdk/blob/main/packages/jssdk/src/oauth/auth.ts) instance, which implements [`AuthActions`](https://github.com/bitrix24/b24jssdk/blob/main/packages/jssdk/src/types/auth.ts):

- `getAuthData()` — returns current `AuthData` or `false` if the access token has expired (the next REST call will trigger an automatic refresh).
- `refreshAuth()` — manual refresh; throws `RefreshTokenError` on failure.
- `getUniq(prefix: string)` — returns `<prefix>_<memberId>`.
- `isAdmin` — requires `initIsAdmin()` first.

### `isInit`

```ts-type
get isInit(): boolean
```

Always `true` immediately after construction.

## Error Handling

// @check-ignore: top-level return in error-handling illustration

```ts
import { B24OAuth, RefreshTokenError } from '@bitrix24/b24jssdk'

try {
  const response = await $b24.actions.v3.call.make({
    method: 'tasks.task.get',
    params: { id: 1, select: ['id', 'title'] },
    requestId: 'task-get-1'
  })
  if (!response.isSuccess) {
    // Handle REST-level errors
    console.error(response.getErrorMessages())
  }
} catch (error) {
  if (error instanceof RefreshTokenError) {
    // Refresh token is dead — re-authorize the application
    console.error('OAuth refresh failed:', error.message)
    return
  }
  throw error
}
```

## FAQ

**Q: Where do I get the initial token pair?**

Bitrix24 sends them when your local application is installed and again on the [`ONAPPINSTALL` / `ONAPPUPDATE`](https://apidocs.bitrix24.com/api-reference/events/index.html) events. Persist them and pass to `B24OAuth` on every server start.

**Q: Why is `expires` in seconds, not milliseconds?**

Bitrix24 returns Unix timestamps in seconds. The SDK converts internally; you must pass seconds in `B24OAuthParams.expires`.

**Q: Can I share one B24OAuth instance across requests?**

Yes — and you should. Sharing keeps the limiter state and the in-memory access token consistent. Persist the refreshed token pair via `setCallbackRefreshAuth` so a restart reuses the latest tokens.

**Q: What about read-only methods that don't need admin rights?**

You can skip `initIsAdmin()` if your code never reads `auth.isAdmin`. REST calls themselves do not depend on it.

## Sitemap

See the full [sitemap](/b24jssdk/sitemap.md) for all pages.
