
## Key self-description

`GET /v1/me`

Returns a self-description of the key that made the request: its type, the bound portal, the tariff and the platform capabilities available on the portal. No scope is needed — the endpoint responds to any valid key and serves as the AI model's starting point for getting acquainted with the portal.

The response shape depends on the key type. How the key is passed in the request — [Passing the key](/docs/keys-auth#passing-the-key).

## Parameters

| Parameter | Type | Required | Values | Description |
|-----------|------|:--------:|--------|-------------|
| `refresh` (query) | string | no | `tariff` | Forces a re-check of the Bitrix24 account plan before the response is built. Works only for keys bound to a Bitrix24 account. Without the parameter the response is served from the server cache. |

## Examples

### curl — personal key

```bash
curl https://vibecode.bitrix24.com/v1/me \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth application

```bash
curl https://vibecode.bitrix24.com/v1/me \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/me', {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data } = await res.json()
console.log('Key type:', data.type, '· portal:', data.portal)
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/me', {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})
const { data } = await res.json()
```

## Response fields

The response describes the key, not a portal entity. The top-level `data.*` blocks are a capability map: some blocks are common to all keys, some appear only for a key of a certain type. The "Key type" column indicates for which key the block is present.

If you are getting to know the key for the first time, four blocks are enough. `type` tells you which key you are working with. `scopes` — which data you have access to. `accessMode` — whether writing is allowed. `capabilities` — which operations are available on this Bitrix24 account and why the rest are denied. The other blocks are needed for a specific task: `deployment` and `infra` when working with servers, `ai` and `webSearch` when calling models, `storage` when uploading files.

| Field | Type | Key type | Description |
|------|-----|-----------|---------|
| `success` | boolean | all | Always `true` on success |
| `data.type` | string | all | Key type: `personal`, `oauth_app` or `management` |
| `data.portal` | string | `vibe_api_`, `vibe_app_` | Domain of the bound Bitrix24 portal |
| `data.tariff` | object | all | Portal tariff: `code`, `name`, `isCommercial`, `wasEverCommercial`, `checkedAt`, `kind` |
| `data.tariff.checkedAt` | string | all | Time of the last tariff check in ISO 8601 format. Updated when called with `?refresh=tariff` |
| `data.scopes` | array | all | Key scopes. Choosing a set — [Scopes](/docs/scopes) |
| `data.accessMode` | string | all | Key access mode: `READWRITE` or `READONLY`. More — [Access mode](/docs/keys-auth/access-mode) |
| `data.capabilities` | object | all | Matrix of available operations. The top-level keys are groups, and each group holds operation slots. The shape of a slot is described below |
| `data.capabilities.apps` | object | all | Operation slots `create` — create an application, `publish` — publish it to the catalog, `bindPlacements` — bind placements. Plus `sourceStorage` — not an operation but a source-storage settings block with its own field set |
| `data.capabilities.apps.sourceStorage` | object | all | Source-storage settings: `enabled`, `requiredBeforeDeploy`, `automaticOnDeploy`, `freshnessWindowMinutes`, `limits.maxBlobBytes`, `endpoint`, `mcpToolName`, `contentTypes`, `docs`. This block carries no `available` or `reason` |
| `data.capabilities.servers` | object | all | Slots `create` — create a server, `deploy` — publish sources, `preview` — issue a preview link, `wake` — wake the server |
| `data.capabilities.agents` | object | all | Slot `create` — create an AI agent |
| `data.capabilities.managedBots` | object | all | Slot `create` — create a managed bot |
| `data.capabilities.aiRouter` | object | all | Slots `chatCompletions` — model calls, `byok` — working with your own provider key |
| `data.capabilities.<group>.<slot>.available` | boolean | all | Whether this key can perform the operation on this Bitrix24 account right now |
| `data.capabilities.<group>.<slot>.reason` | string | all | State code of the slot. It arrives both on `available: true` — `COMMERCIAL`, `TRIAL_ACTIVE` — and on a denial — for example `SESSION_REQUIRED`, `WRITE_BLOCKED_READONLY_KEY`, `BILLING_EXHAUSTED`, `FEATURE_DISABLED`, `INFRA_NOT_PERMITTED`, `SERVER_CREATION_DISABLED`, `SERVER_CREATION_ADMINS_ONLY`, `INT_TARIFF_REQUIRED`, `COMMERCIAL_PLAN_REQUIRED`, `TRIAL_PORTAL_LIMIT`, `PLAN_NOT_ALLOWED_ON_TRIAL`. The set grows — treat an unknown code as a denial and rely on `available` |
| `data.capabilities.<group>.<slot>.userMessage` | string | all | Ready-made text in the user's language. It arrives on a denial — show it as is |
| `data.capabilities.<group>.<slot>.note` | string | all | A condition that `available: true` does not cover: a Bitrix24-side prerequisite, the count of used limit slots, or a free-access restriction |
| `data.webResearch.promptForAgents` | string | all | A ready-made hint for an agent: how to call research and where to find the provider catalogue |
| `data.capabilities.<group>.<slot>.limits` | object | all | Limits in force for the slot — for example `allowedPlans` and `maxPortalTotal` under free access |
| `data.capabilities.<group>.<slot>.alternatives` | array | all | What to do instead of the blocked operation: items with the fields `type`, `description`, `url` or `endpoint` |
| `data.api` | object | all | API usage rules in the `_rules` array, the list of entity API entities in `entityApi`, a link to the full reference |
| `data.rateLimit` | object | all | Rate limits in effect for the key, field `requestsPerSecond`. More — [Rate limits](/docs/keys-auth#request-limits) |
| `data.ai` | object | all | AI Router access: default model, available models, catalog size. More details — [AI](/docs/ai) |
| `data.webSearch` | object | all | Web search providers and their cost. More — [Provider list](/docs/search/providers) |
| `data.webResearch` | object | all | Deep research: `available`, `endpoint`, `providers`, `defaultProvider`, `streaming`, `docs`. More — [Deep research](/docs/search/research) |
| `data.webResearch.providers[].cost` | object | all | Price of one research run with the provider: `research` — the price in Vibe credits (Ꝟ), `currency` — the billing unit. For a provider used with your own key `research` equals `0` |
| `data.storage` | object | all | Object storage: usage, tariffs, upload endpoints. More details — [Storage](/docs/storage) |
| `data.deployment` | object | all | Application deployment contract, depends on the target server type. More details — [Deploy](/docs/infra/deploy) |
| `data.infra` | object | all | Infrastructure: providers, server limit, list of unhealthy servers. More details — [Infrastructure](/docs/infra) |
| `data.feedback` | object | all | Feedback endpoints and limits. More details — [Feedback](/docs/feedback) |
| `data.auth` | object | all | How to pass the key in a request: headers, and for the authorization key — OAuth authorization steps |
| `data.quickstart` | object | all | A short list of first calls to get acquainted with the API |
| `data.docs` | string | all | Link to the full API reference — `GET /v1/guide` |
| `data.errorCodes` | object | all | Error response format and a link to the full code reference |
| `data.changelog` | object | all | Link to the API changelog |
| `data.expiresAt` | string or null | `vibe_api_` | Key expiration. `null` — no limit |
| `data.owner` | object | `vibe_api_` | Key owner: `name`, `userId` |
| `data.portalEmbedding` | object | `vibe_api_` | An explanation that a personal key does not embed the application in the portal interface |
| `data.app` | object | `vibe_app_` | Bound application: `title`, `id` |
| `data.currentUser` | object or null | `vibe_app_` | The Bitrix24 user on whose behalf the request runs. Filled when a session token is passed. Without one it arrives as `null` |
| `data.placements` | object | `vibe_app_` | Embedding the application in the portal interface: available and registered placements, endpoints, request handling order. More — [Embedding the application in the portal](/docs/keys-auth#embedding-an-app-in-the-bitrix24-account) |
| `data.placements.bindPrerequisite` | object | `vibe_app_` | The Bitrix24-side condition without which [binding a placement](/docs/apps/placements/bind) will not go through. The contents of the block depend on the account type |
| `data.placements.bindPrerequisite.subscriptionRequired` | boolean | `vibe_app_` | `false` — a commercial Bitrix24 plan is enough for the bind |
| `data.placements.bindPrerequisite.note` | string | `vibe_app_` | Text describing the condition and how to satisfy it |
| `data.placements.bindPrerequisite.errorCodes` | array | `vibe_app_` | The codes bind will answer with while the condition is unmet — `INT_TARIFF_REQUIRED` and `BITRIX_UNAVAILABLE`. On a self-hosted account `SESSION_REQUIRES_ADMIN` is added to the set |
| `data.oauth` | object | `vibe_app_` | OAuth authorization URL and required parameters |
| `data.oauthTutorial` | object | `vibe_app_` | Step-by-step OAuth authorization order |
| `data.eventDelivery` | object | `vibe_app_` | Server-side receipt of portal events without polling |
| `data.schemaDiscovery` | object | `vibe_app_` | How to read the field schema without a session token |

The management key (`vibe_live_`) returns a different set of blocks — `portals`, `totalAppKeys`, a reduced `capabilities` — and carries no portal data. Description — [Management keys](/docs/management-keys).

## Response example

Personal key (`vibe_api_`) — main fields shown:

```json
{
  "success": true,
  "data": {
    "type": "personal",
    "portal": "mycompany.bitrix24.com",
    "tariff": {
      "code": "en_basic",
      "name": "Basic",
      "isCommercial": true,
      "wasEverCommercial": true,
      "checkedAt": "2026-07-08T08:57:58.270Z",
      "kind": "CLOUD"
    },
    "scopes": ["crm", "task", "tasks", "im", "imbot", "disk", "user"],
    "accessMode": "READWRITE",
    "capabilities": {
      "apps": {
        "create": { "available": true },
        "publish": { "available": true },
        "bindPlacements": { "available": true }
      },
      "servers": {
        "create": { "available": true, "reason": "COMMERCIAL" },
        "deploy": { "available": true, "reason": "COMMERCIAL" },
        "preview": { "available": true },
        "wake": { "available": true }
      },
      "agents": {
        "create": {
          "available": true,
          "reason": "COMMERCIAL",
          "note": "Agent servers count toward the portal's infrastructure limit (currently 2/10)."
        }
      },
      "managedBots": {
        "create": {
          "available": true,
          "reason": "COMMERCIAL",
          "note": "Managed bot servers count toward the portal infrastructure limit."
        }
      },
      "aiRouter": {
        "chatCompletions": { "available": true },
        "byok": { "available": true }
      }
    },
    "owner": { "name": "John Brown", "userId": "1" },
    "expiresAt": null
  }
}
```

The `apps.publish` and `apps.bindPlacements` slots always carry a `note` — it is omitted from the example above, the endpoint returns the full text.

Authorization key (`vibe_app_`) without a session token — blocks shown that a personal key does not have:

```json
{
  "success": true,
  "data": {
    "type": "oauth_app",
    "portal": "mycompany.bitrix24.com",
    "accessMode": "READWRITE",
    "app": { "title": "CRM Dashboard", "id": "f2342f7a-…" },
    "currentUser": null,
    "placements": {
      "available": true,
      "registered": ["LEFT_MENU"],
      "endpoints": [
        "POST https://vibecode.bitrix24.com/v1/placements/bind",
        "POST https://vibecode.bitrix24.com/v1/placements/unbind",
        "GET https://vibecode.bitrix24.com/v1/placements",
        "GET https://vibecode.bitrix24.com/v1/placements/available"
      ],
      "bindPrerequisite": {
        "subscriptionRequired": false,
        "note": "Binding a placement requires a Bitrix24-side prerequisite: the account must be on a commercial Bitrix24 plan…",
        "errorCodes": [
          "INT_TARIFF_REQUIRED",
          "BITRIX_UNAVAILABLE"
        ]
      }
    }
  }
}
```

> ⚠ **`oauth.authorizeUrl` is a template, not a ready-made link.** The `/v1/oauth/authorize` endpoint requires the mandatory `state` parameter (16–512 characters) — a CSRF token per RFC 6749 §10.12 that the **client generates**: create a cryptographically random string, add it to the URL, and verify the value returned in the callback. The server cannot generate `state` for you — otherwise CSRF protection does not work. Opening `authorizeUrl` as is returns `400 INVALID_REQUEST "state: Required"`. Optionally add `redirect_uri` — your callback address, without it the built-in `/oauth/complete` page is used — and `scope`. Full-link example:
>
> ```
> https://vibecode.bitrix24.com/v1/oauth/authorize?app_key=vibe_app_…&state=aAbBcCdDeEfFgGhH&redirect_uri=https://myapp.com/callback
> ```

## Error response example

401 — invalid key:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid API key"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is not passed |
| 401 | `INVALID_API_KEY` | The key is not found |
| 401 | `KEY_INACTIVE` | The key is revoked |
| 401 | `KEY_EXPIRED` | The key's expiration has passed |
| 403 | `IP_NOT_ALLOWED` | Request from an address outside the allowed IP list |

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

**`?refresh=tariff` checks the tariff no more than once per minute.** The parameter forces a live check of the portal's tariff in Bitrix24 and resets the response cache. If the previous check was less than a minute ago, the request returns the already known value without a new check. For a management key the parameter does nothing — such a key is not bound to a portal.

**The response is cached server-side for about 30 seconds.** A change of scopes or access mode is reflected in the response immediately. The tariff, balance and infrastructure state are updated on the first read after the cache expires. A request with `?refresh=tariff` resets the cache, and the next read without this parameter returns a fresh tariff.

**For a key in read-only mode, six `capabilities` slots arrive closed.** They are `apps.create`, `apps.publish`, `apps.bindPlacements`, `servers.create`, `agents.create` and `managedBots.create` — all six return `available: false` and `reason: "WRITE_BLOCKED_READONLY_KEY"`. The remaining slots, including `servers.deploy`, `servers.preview`, `servers.wake` and both `aiRouter` operations, are not affected by the access mode. More — [Access mode](/docs/keys-auth/access-mode).

**Without a key in a browser the endpoint returns HTML.** A `GET /v1/me` request without the `X-Api-Key` header and with the `Accept: text/html` header returns a stub page with status `200`, not JSON. A request with a key or without `text/html` in the `Accept` header always gets the JSON self-description.

## See also

- [Creating and using a key](/docs/keys-auth)
- [API reference for the model](/docs/keys-auth/guide)
- [Access mode](/docs/keys-auth/access-mode)
- [Scopes](/docs/scopes)
- [Management keys](/docs/management-keys)
- [Errors](/docs/errors)
