Para agentes de IA: markdown desta página — /docs-content-en/keys-auth/me.md índice da documentação — /llms.txt
Os artigos da documentação estão disponíveis atualmente em inglês.
Key self-description
GET /v1/me
Returns a self-description of the key that made the request: its type, the bound Bitrix24 account, that account's plan and the platform capabilities available on it. No scope is needed — the endpoint responds to any valid key and serves as an AI model's starting point for exploring the Bitrix24 account.
The response shape depends on the key type. How the key is passed in the request — Passing the key.
Parameters
| Parameter | Type | Required | Values | Description |
|---|---|---|---|---|
refresh (query) |
string | no | tariff |
Forces a live 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
curl https://vibecode.bitrix24.com/v1/me \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl https://vibecode.bitrix24.com/v1/me \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
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
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 an entity on the Bitrix24 account. 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 shows which key types each block appears for.
If this is your first look at the key, 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.portalId |
string | vibe_api_, vibe_app_ |
Stable identifier of the bound Bitrix24 portal. Unlike the domain, it survives a rename or a move of the portal — use it whenever local data is split per account. A key with no portal never reaches this response: it gets 401 NO_PORTAL, so the field is never empty in a successful response |
data.tariff |
object | all | Bitrix24 account plan: code, name, isCommercial, wasEverCommercial, checkedAt, kind |
data.tariff.name |
string · null | all | Human-readable edition name — meant for display, not for comparison in code. May be null. Details below |
data.tariff.wasEverCommercial |
boolean | all | The account has been seen on a commercial plan. The flag is not one-way — see below |
data.tariff.checkedAt |
string | all | Time of the last ATTEMPT to check the plan against Bitrix24, ISO 8601. Updated when called with ?refresh=tariff — including when the check failed and the plan could not be read. A SUCCESSFUL check is marked by a separate response header, X-Tariff-Checked-At (see Infrastructure), and that header may be absent from the very same response. If the field is present but the header is not, the check was attempted and the plan could not be read |
data.scopes |
array | all | Key scopes. Choosing a set — Scopes |
data.api.scopeRequirements |
object | all | Map of the key's scopes: what it lacks and what each missing scope would open. A pre-flight check instead of calling blind. Details below |
data.api.scopeRequirements.granted |
object | all | Granted scopes, split into bitrix24 and platform — they are obtained differently |
data.api.scopeRequirements.coverage |
object | all | Map completeness: entities is always complete, paths is complete or partial. When paths is partial, the path list is incomplete, and the absence of a path from unlocks does NOT prove the path is ungated |
data.api.scopeRequirements.missing |
object | all | Missing scopes. Each carries entities — entities it would open, unlocks — paths (at most five, the rest in unlocksRemaining next to truncated), howToObtain — how to get it |
data.api.scopeRequirements.unobtainable |
object | all | Scopes this key cannot obtain, and why. Two reasons: a personal webhook key carries no app-context scopes, and some scopes are minted by the platform itself and are not available to a user on any surface |
data.api.scopeRequirements.aliases |
object | all | Spellings Bitrix24 treats as one scope (task and tasks) |
data.accessMode |
string | all | Key access mode: READWRITE or READONLY. More — 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, limits.maxBlobBytes, endpoint, mcpToolName, contentTypes, docs. The freshnessWindowMinutes field is added only when the platform checks the snapshot's age before publishing. This block carries no available or reason fields |
data.capabilities.servers |
object | all | Slots create — create a server, deploy — publish sources, preview — work with access tokens: a preview link and a Bearer token for an end-to-end (E2E) check, 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. On .com, infrastructure and key issuance additionally require a Vibe+ plan (INT_VIBE_PLUS_REQUIRED). 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, how much of a limit is already used, 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 catalog |
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 entities exposed by the entity API in entityApi, a link to the full reference |
data.rateLimit |
object | all | Call-rate limits: requestsPerSecond — the Bitrix24 account limit, shared across all of its keys, edgeRequestsPerSecondPerIp — the platform edge limit per client IP address. More — Request limits |
data.ai |
object | all | AI Router access: default model, available models, catalog size. More — AI Router |
data.webSearch |
object | all | Web search providers and their cost. More — Provider list |
data.webResearch |
object | all | Deep research: available, endpoint, providers, defaultProvider, streaming, docs. More — Deep 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, pricing, upload endpoints. More — Storage |
data.deployment |
object | all | Application deployment contract — depends on the target server type. More — Deploy API |
data.deployment.primary |
string | all | The placement model the platform treats as primary for this account: galaxyApp — an app inside a galaxy, standalone — a dedicated virtual machine |
data.deployment.galaxyApp |
object | all | The contract for deploying into a galaxy. During trial access, the block arrives only when stored state shows a suitable host. This is an advisory assessment: POST /v1/infra/servers makes the final live-capacity check |
data.deployment.placementNote |
string | all | Why the galaxy is unavailable and how to deploy in that state. During trial access, the field distinguishes the absence of a host from an existing but unsuitable host. The field is absent when Galaxy mode is disabled, see Galaxy app |
data.deployment.limits |
object | all | The publication limits in force: the body and archive ceilings, the per-step time budget, the number of log lines, the ceiling on concurrent inline-body publications |
data.deployment.limits.uploadInlineMax |
string | all | The HTTP body ceiling for a publication with an inline archive, as a string with its unit — for example 96MB. Above it, 413 INLINE_SOURCE_TOO_LARGE arrives. See Deploy |
data.deployment.limits.uploadInlineMaxArchive |
string | all | The same ceiling expressed as the size of the archive itself — for example 72MB. It is about a third lower than uploadInlineMax: the contents travel as base64 and are heavier than the source bytes. The value comes from the same constant as the refusal, so you do not need to recompute the ceiling yourself |
data.deployment.limits.uploadUrlMax |
string | all | The ceiling for publishing by link and by a stored version — 500MB. Those paths are streamed and do not fall under the inline body ceiling |
data.infra |
object | all | Infrastructure: providers, server limit, list of unhealthy servers, servers of other teams the key owner is on. More — Infrastructure |
data.infra.collaboratorServers |
object | all | Servers where the key owner is on the development team rather than owning them: total — how many memberships there are in total, count — how many rows fit into the response, items — the rows themselves. These servers do not count towards infra.limits — the machines belong to someone else. The same servers arrive in GET /v1/infra/servers carrying the access.via: "collaborator" block |
data.infraState |
object | all | Whether infrastructure is stopped over an unpaid balance. The strings inside the block are machine-readable; the client writes the human-facing text |
data.infraState.frozen |
boolean | all | Whether servers, deploys and storage are stopped over an unpaid balance. On true the 402 ACCOUNT_FROZEN refusal arrives on calls paid for from the Vibe credits balance, while requests to your own Bitrix24, AI within the plan's monthly quota and the paid period of a Cowork/Code subscription keep working. Until the narrowed refusal reaches your Bitrix24 account, true means "almost everything is stopped": the self-description, the guide, the spec, four Feedback conversation calls — filing a ticket, listing tickets, reading one ticket and commenting on it — and the revocation of your own Cowork/Code key keep working; everything else answers 402 ACCOUNT_FROZEN. The full list is in Error codes |
data.infraState.reason |
string or null | all | The stop reason code: DEBT, or null when nothing is stopped |
data.infraState.topupUrl |
string or null | all | The top-up address for your Vibecode account, or null when there is nothing to top up |
data.feedback |
object | all | Feedback endpoints and limits. More — 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 for exploring the API |
data.b24Credentials |
object | vibe_api_ |
Whether the key can call Bitrix24: ready. When ready: false it also carries reason, plus paywallCode and upgradeUrl for plan-related reasons. The hint field arrives when the access state is worth re-reading. The block is absent for a key that is not bound to a Bitrix24 account and for a key with no Bitrix24 scopes — the flag does not apply there. The reason values and the action for each — Error codes |
data.b24Credentials.ready |
boolean | vibe_api_ |
true — the key carries credentials for calls to the Bitrix24 account, false — it does not, and any such call returns 401 TOKEN_MISSING |
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 error code reference |
data.changelog |
object | all | Link to the API changelog |
data.expiresAt |
string or null | vibe_api_ |
Key expiration date. null — no expiration |
data.owner |
object | vibe_api_ |
Key owner: name, userId |
data.portalEmbedding |
object | vibe_api_ |
The embedding flow through POST /v1/apps → OAuth authorization → POST /v1/apps/:id/publish, plus the personal-key boundaries: it does not call placements/bind directly and is not itself a transparent-auth credential |
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 Bitrix24 account interface: available and registered placements, endpoints, how incoming requests are handled. More — Embedding an app in the Bitrix24 account |
data.placements.bindPrerequisite |
object | vibe_app_ |
The Bitrix24-side condition without which binding a placement will not succeed. The contents of the block depend on the account type |
data.placements.bindPrerequisite.subscriptionRequired |
boolean | vibe_app_ |
false — a commercial Bitrix24 plan is enough to bind a placement |
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 the bind call returns while the condition is unmet — INT_TARIFF_REQUIRED and BITRIX_UNAVAILABLE. On a self-hosted account, SESSION_REQUIRES_ADMIN is added to the set. Regardless of account type the set also carries PLACEMENT_APP_GRANT_MISSING, PLACEMENT_OPTIONS_REQUIRED and PLACEMENT_NOT_REST_BINDABLE — refusals about a specific placement rather than about account access |
data.oauth |
object | vibe_app_ |
OAuth authorization URL and required parameters |
data.oauthTutorial |
object | vibe_app_ |
Step-by-step OAuth authorization walkthrough |
data.eventDelivery |
object | vibe_app_ |
Receiving Bitrix24 account events on your server 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 Bitrix24 account data. Description — Management keys.
Response example
Personal key (vibe_api_) — main fields shown:
{
"success": true,
"data": {
"type": "personal",
"portal": "mycompany.bitrix24.com",
"portalId": "8c3d1e04-…",
"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, but the endpoint returns the full text.
Authorization key (vibe_app_) without a session token — showing the blocks a personal key does not have:
{
"success": true,
"data": {
"type": "oauth_app",
"portal": "mycompany.bitrix24.com",
"portalId": "8c3d1e04-…",
"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 portal must be on a commercial Bitrix24 plan…",
"errorCodes": [
"INT_TARIFF_REQUIRED",
"BITRIX_UNAVAILABLE"
]
}
}
}
}
oauth.authorizeUrlis a template, not a ready-made link. The/v1/oauth/authorizeendpoint requires thestateparameter (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 generatestatefor you — otherwise CSRF protection does not work. OpeningauthorizeUrlas is returns400 INVALID_REQUEST "state: Required". Optionally addredirect_uri(your callback address — without it the built-in/oauth/completepage is used) andscope. 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:
{
"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 missing |
| 401 | INVALID_API_KEY |
The key was not found |
| 401 | KEY_INACTIVE |
The key is revoked |
| 401 | KEY_EXPIRED |
The key has expired |
| 401 | KEY_NOT_FOUND |
The key was deleted while the request was being processed |
| 403 | IP_NOT_ALLOWED |
Request from an address outside the allowed IP list |
Full list of common API errors — Errors.
Known specifics
?refresh=tariff checks the plan no more than once per minute. The parameter forces a live check of the Bitrix24 account plan 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 Bitrix24 account.
The response is cached server-side for about 30 seconds. A change of scopes or access mode is reflected in the response immediately. The plan, 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 an up-to-date plan.
For a key in read-only mode, nine capabilities slots come back closed. They are apps.publish, apps.bindPlacements, servers.create, servers.deploy, servers.wake, agents.create, managedBots.create and both aiRouter operations — all nine return available: false and reason: "WRITE_BLOCKED_READONLY_KEY". For a read-only key the response root also carries writeRestriction — the WRITE_BLOCKED_READONLY_KEY code, the scope it applies to, and a link to the access-mode page. The field is present only while the restriction is in force: a platform administrator may lift it, and then the field disappears from the response along with the restriction itself. Inside the field an exceptions list names the routes that check the mode themselves and therefore partly succeed; today that is POST /v1/apps, where a read-only key creates an application in the same mode, plus two non-GET addresses that are not writes: DELETE /v1/cowork/key (emergency key revocation) and DELETE /v1/infra/servers/{id}/lock (releasing a stuck lock, pointed at by the recoveryAction field of an EXEC_BUSY response). A management key carries the field too, but nothing lifts it there: the write block for such keys is unconditional. The field exists because the response names writing endpoints in some thirty places (storage, feedback, source-storage and cowork hints): those are addresses, not permissions. Per-operation availability is in capabilities.
apps.create does NOT come back closed: such a key can create an application in READONLY mode, and the ban on READWRITE is spelled out in that slot's note field. Reads are not affected by the mode — servers.preview, for one. More — Access mode.
The plan name is for display, not for comparison. The data.tariff.name field is assembled at read time and can change without the plan itself changing. The platform picks it in this order. If the plan code is known to the edition catalog — from there, in English. Otherwise the license name as Bitrix24 reported it, in the account's language. Otherwise the previously stored name. Otherwise null. Three things follow. First, null is a normal value, not an error. Second, the name does not depend on who asks — neither Accept-Language nor the key owner's interface language changes it. Third, the plan code is never substituted for the name — when there is no name, you get null, not pro100. Branch your logic on data.tariff.code, isCommercial, and kind. The labels of known editions have also been refined — three of them: the demo edition is now Trial period, Project is now Project — legacy free, and NFR is now NFR — partner licence.
The wasEverCommercial flag is not one-way. A plan downgrade does not withdraw trust: the switch to a free plan does not clear the value by itself. Yet the flag is not one-way — the platform brings it in line with the facts when no grounds for it are found, and that has already happened on both cloud and self-hosted portals. Do not build logic on this field that assumes the transition can only go one way — check capabilities in the same response instead.
The downward correction does not reach every account. The flag is kept when the account has a completed payment behind it, when it moved from a trial period to a paid plan, or when the license region of a self-hosted account could not be determined. That last case is not a failure — trust is not withdrawn over a state that was not read in full. See Connecting a self-hosted Bitrix24.
Determine the placement model from the deployment block, not from the account plan. On the free Bitrix24 plan a new galaxy is not created. When Galaxy mode is enabled but there is no host, deployment.galaxyApp is absent, deployment.primary is standalone, and deployment.placementNote describes the two-step path. It is available only while capabilities.servers.create.available in the same response is true; select an allowed plan ID from capabilities.servers.create.limits.allowedPlans. When Galaxy mode is disabled, placementNote is absent, a one-shot request carrying source returns 400 SOURCE_AT_CREATE_GALAXY_ONLY, and the same capabilities slot decides whether the two-step path is available. When an existing host passes the advisory stored-state check, the galaxyApp block is present and a one-shot create carrying source is worth trying. This is not a guarantee: only POST /v1/infra/servers checks live capacity.
When an existing host fails the advisory check, the galaxyApp block is absent. While capabilities.servers.create.available is false, placementNote rules out a two-step dedicated-machine create: with trial enforcement active, the occupied slot returns 402 TRIAL_PORTAL_LIMIT. To retry one-shot creation, wait for the host to recover, ask an administrator to repair it, or upgrade the plan. After removing the host, re-read GET /v1/me and use the two-step path advertised there. Follow the hint in the actual POST response. The call sequence — Create a server and Deploy API.
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.
Scope requirements map
Until now the only way to learn a key's boundary was to make the call: the request went out and came back with a 403 SCOPE_DENIED refusal naming the missing scope. The list of available entities showed only what was open, while what was closed was simply absent — and absence alone could not distinguish "no such entity in the product" from "it exists but your key cannot reach it".
The data.api.scopeRequirements block answers that before the call:
{
"granted": { "bitrix24": ["imbot"], "platform": ["vibe:ai", "vibe:search"] },
"missing": {
"bitrix24": {
"crm": {
"entities": ["deals", "contacts", "companies", "leads"],
"unlocks": ["/v1/duplicates/find", "/v1/addresses"],
"unlocksRemaining": 41,
"truncated": true,
"howToObtain": "reissue-key"
}
},
"platform": {}
}
}
Bitrix24 binds its scopes to a key when the key is issued, so their howToObtain is reissue-key: adding a scope in the settings of an already-issued key is not enough; the key has to be reissued. Vibecode scopes are edited in your Vibecode account.
The map describes the platform-side scope check only. It does not promise the call will succeed. A scope granted in your Vibecode account after the key was issued shows up in the map, but Bitrix24 does not honour it and answers
BITRIX_ACCESS_DENIED. Refusals by key kind, ownership, read-only mode, account freeze and plan are separate axes and are not described in the map. The_notefield inside the block carries the same warning.
Path coverage is not complete yet, and the map says so itself. A
coverage.pathsvalue ofpartialmeans some custom routes still lack a machine-checked verdict, sounlocksandunlocksRemainingunder-report. Absence of a path from the list does NOT prove the path is ungated: if a call still answers with a scope refusal, trust the refusal, not the map. The entity list is always complete.
The refusal has not changed: a call without the required scope still returns 403 SCOPE_DENIED naming that scope. The map is a pre-flight check, not a replacement for the refusal.