#Error codes
Reference of Vibe API error codes: the unified response format, the full code list, common causes, and how to fix them. Applies to all /v1/... endpoints.
#Error response format
Every error response is returned in a unified shape. error is an object.
{
"success": false,
"error": {
"code": "ENTITY_NOT_FOUND",
"message": "Item not found"
}
}
| Field | Type | Req. | Description |
|---|---|---|---|
success |
boolean | yes | Always false on error |
error.code |
string | yes | Machine-readable error code. Use it to distinguish error types in client code |
error.message |
string | yes | Error description in the backend language (Russian or English) |
error.hint |
string | no | Developer hint: what to try next, which limits to watch |
error.userMessage |
string | no | Message for the end user in Russian. Appears in billing, infrastructure, and tariff errors |
error.warning |
string | no | Appears on repeated identical errors on the same key. A signal that the client code most likely has a bug |
error.retryAfter |
number | no | Seconds until the next attempt. Appears in 429 (rate-limit) and 504 (queue timeout) |
Example response with extra fields (429 RATE_LIMITED):
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "QUERY_LIMIT_EXCEEDED",
"hint": "Wait 1-2 seconds and retry. Use POST /v1/batch to combine up to 50 calls in 1 request.",
"retryAfter": 2
}
}
The Retry-After HTTP header mirrors the error.retryAfter value for compatibility with the HTTP standard.
#Code summary table
The table covers the core codes that appear on any Vibe API endpoint. Domain codes (BOT_NOT_FOUND, SERVER_NOT_RUNNING, AGENT_LIMIT_REACHED, and similar) are documented on the pages of their respective sections.
#Authorization and keys
| Code | HTTP | When it occurs |
|---|---|---|
MISSING_API_KEY |
401 | Request without the X-Api-Key header |
INVALID_API_KEY |
401 | Key not found in the system or its format is unrecognized |
INVALID_APP_KEY |
401 | A vibe_app_* key was passed without an accompanying Authorization: Bearer ... |
TOKEN_EXPIRED |
401 | The OAuth token has expired |
TOKEN_REFRESH_FAILED |
401 | Failed to refresh the OAuth token on the Bitrix24 side |
WRONG_KEY_TYPE |
401 | The key type does not match the endpoint: e.g. a management key on an entity route |
#Permissions and scopes
| Code | HTTP | When it occurs |
|---|---|---|
SCOPE_DENIED |
403 | The key lacks the required scope (e.g. crm for deals, imbot for bots) |
WRITE_BLOCKED_READONLY_KEY |
403 | The key is in read-only mode, but the call performs a write |
INFRA_FORBIDDEN_FOR_COWORK_KEY |
403 | A Co-work subscription key (vibe:cowork) — data-plane only: provision / deploy / exec / upload / server lifecycle and catalog publishing are forbidden. Use a project key with deploy permissions |
INFRA_SCOPE_REQUIRED |
403 | The key lacks the vibe:infra scope — infrastructure management is unavailable. Add the scope or use a key with infrastructure permissions |
KEY_POLICY_READONLY_REQUIRED |
403 | The portal policy allows regular users to create read-only keys only — issuing a write-enabled key was rejected |
MANAGEMENT_KEY_READ_ONLY |
403 | A management key without write permissions attempts a POST/PATCH/DELETE |
MANAGEMENT_KEY_NO_ENTITY_ACCESS |
403 | A management key accesses an entity endpoint — an APP key with the required scope is needed |
BITRIX_ACCESS_DENIED |
403 | Bitrix24 returned ACCESS_DENIED: the user lacks permission for the operation or entity |
OAUTH_REQUIRED |
403 | The endpoint requires a user context — a vibe_app_* key + Bearer token is needed |
WAITLIST_PENDING |
403 | The account is awaiting waitlist activation |
#Request validation
| Code | HTTP | When it occurs |
|---|---|---|
VALIDATION_ERROR |
400 | The body or query failed schema validation. message contains per-field details |
INVALID_PARAMS |
400 | Bitrix24 returned INVALID_PARAMS or the route handler found an invalid parameter value |
INVALID_REQUEST |
400 | The request structure does not match the required one (e.g. calls in /v1/batch is an empty array or contains more than 50 elements) |
MISSING_PARAMS |
400 | A required parameter explicitly listed in the endpoint schema was not passed |
MISSING_REQUIRED_FILTER |
400 | A required filter for list endpoints that need context (timelines, task-comments, and similar) was not passed |
INVALID_FILTER_FIELD |
400 | Filter on a non-existent entity field |
UNKNOWN_SORT_FIELD |
400 | Sort on a non-existent field (for entities whose sort validator is active) |
BATCH_LIMIT_EXCEEDED |
400 | The request contains more than 50 elements in a bulk operation (vipchats, task-comments, and similar) |
INVALID_EVENT |
400 | The portal event subscription code does not match the ^[A-Z][A-Z0-9_]+$ format. See Portal event subscriptions |
INVALID_APP_PATH |
400 | The appPath delivery path does not start with / or contains control characters. See Portal event subscriptions |
#Portal event subscription preconditions
| Code | HTTP | When it occurs |
|---|---|---|
NOT_OAUTH_APP |
400 | The server is not backed by an OAuth app with an application_token — an event subscription cannot be registered |
NO_USER_TOKEN |
400 | The app has no OAuth token — authorize the app on the portal first |
The full operation reference — Portal event subscriptions.
#Resource not found
| Code | HTTP | When it occurs |
|---|---|---|
ENTITY_NOT_FOUND |
404 | A CRM entity record with the given id does not exist. The canonical code for /v1/deals/:id, /v1/contacts/:id, and similar |
NOT_FOUND |
404 | GET /:id only: Bitrix24 returned success, but result is empty (applies to several smart methods) |
Domain *_NOT_FOUND codes (BOT_NOT_FOUND, SERVER_NOT_FOUND, AGENT_NOT_FOUND, PORTAL_NOT_FOUND, USER_NOT_FOUND, FILE_NOT_FOUND, SUBSCRIPTION_NOT_FOUND) are documented on the pages of their respective sections.
#State conflicts
| Code | HTTP | When it occurs |
|---|---|---|
CONFLICT |
409 | The current resource state is incompatible with the request |
ALREADY_EXISTS |
409 | A record with these key fields already exists |
EVENT_BOUND_ELSEWHERE |
409 | A portal event is already bound to another server of the same OAuth app. See Portal event subscriptions |
#Billing and tariff
Occur on endpoints that create and wake infrastructure (servers, agents, managed bots). The response includes userMessage in Russian for display in the client interface.
| Code | HTTP | When it occurs |
|---|---|---|
BILLING_EXHAUSTED |
402 | The balance dropped into the red zone, the account is frozen. A top-up is required |
ACCOUNT_FROZEN |
402 | The billing account is frozen for other reasons |
COMMERCIAL_PLAN_REQUIRED |
402 | Free Bitrix24 plan, the trial period is unavailable or already used |
TRIAL_EXPIRED |
402 | The 14-day trial period has ended |
TRIAL_PORTAL_LIMIT |
402 | The overall per-portal server limit was exceeded during the trial period |
TRIAL_USER_LIMIT |
402 | The per-user server limit was exceeded during the trial period |
PLAN_NOT_ALLOWED_ON_TRIAL |
402 | The requested server/agent plan is unavailable during the trial period |
SERVER_WAKE_BLOCKED |
403 | Server wake-up is blocked for a non-billing reason |
#Rate limiting
| Code | HTTP | When it occurs |
|---|---|---|
RATE_LIMITED |
429 | Bitrix24 throttled the request rate or an internal limit was exceeded. The response includes retryAfter (seconds) and the Retry-After header |
ERROR_LOOP_DETECTED |
429 | A VibeCode-side block: the same request repeats with the same error. A signal of a bug in the client code. Every Nth request is forwarded onward to check for recovery |
#Backend and third-party services
| Code | HTTP | When it occurs |
|---|---|---|
BITRIX_ERROR |
422 | Bitrix24 returned a business error that does not fall under narrower categories (ACCESS_DENIED, NOT_FOUND, INVALID_PARAMS) |
BITRIX_UNAVAILABLE |
502 | Bitrix24 returned 5xx or did not respond in time |
BIND_FAILED |
502 | Bitrix24 rejected the event registration (event.bind) — for example, the portal is not on a commercial plan. See Portal event subscriptions |
WINDOWED_SEARCH_FAILED |
502 | All sub-windows of /search failed |
QUEUE_TIMEOUT |
504 | The portal queue is saturated: more than 30 seconds of waiting on the VibeCode side |
INTERNAL_ERROR |
500 | An unexpected VibeCode backend error |
#Detailed reference
#`MISSING_API_KEY` (401)
The request does not contain the X-Api-Key header.
{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "API key required. Pass via X-Api-Key header."
}
}
Causes:
- The
X-Api-KeyorAuthorizationheader was not passed. - The header was passed with an empty value.
Fix:
- Add the
X-Api-Key: vibe_api_...orX-Api-Key: vibe_app_...header. - Verify that the environment variable holding the key is set correctly (for CLI tools and SDKs).
#`INVALID_API_KEY` (401)
The passed key does not exist or its format is unrecognized.
{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid API key"
}
}
Causes:
- A typo or extra whitespace in the key.
- The key was deleted by its owner or an administrator.
- The key is from a different environment (staging/production).
- The prefix is not among the supported ones:
vibe_api_,vibe_app_,vibe_live_,vibe_mgmt_.
Fix:
- Check the key in your account on the
/keyspage. - Create a new key if the old one was deleted.
#`SCOPE_DENIED` (403)
The key lacks the required scope for the requested operation.
{
"success": false,
"error": {
"code": "SCOPE_DENIED",
"message": "This endpoint requires 'crm' scope"
}
}
Causes:
- CRM entities require the
crmscope, tasks requiretask, the bot platform requiresimbot, the AI Router requiresvibe:ai, infrastructure requiresvibe:infra. - The key's scope was narrowed at creation time.
Fix:
- Open the key page in your account and issue a new key with a broader scope set.
- The full list of scopes and their purpose is on the Keys and authorization page.
#`BITRIX_ACCESS_DENIED` (403)
Bitrix24 returned ACCESS_DENIED: the user or app lacks permission for the entity or operation.
{
"success": false,
"error": {
"code": "BITRIX_ACCESS_DENIED",
"message": "ACCESS_DENIED"
}
}
Causes:
- The user lacks permission for the entity in CRM (e.g. another user's deal with restricted visibility).
- The Bitrix24 app does not have the required scope in its portal permissions.
- The requested module is disabled on the portal (no CRM, no bot platform, and so on).
Fix:
- Check the user's permissions in the Bitrix24 entity card.
- Open the app settings on the portal and broaden the permission set.
#`WRITE_BLOCKED_READONLY_KEY` (403)
The key is in read-only mode (accessMode: "READONLY"), but the request performs a write. The full description of the mode, switching, and portal policy is in Access mode.
{
"success": false,
"error": {
"code": "WRITE_BLOCKED_READONLY_KEY",
"message": "Key is in read-only mode. Switch to read+write in /keys to enable writes.",
"details": {
"method": "crm.item.add",
"keyName": "MCP key",
"currentMode": "READONLY",
"switchUrl": "/keys"
}
}
}
details fields:
| Field | When returned | Description |
|---|---|---|
method |
Only when proxying to Bitrix24 | The Bitrix24 method name that would have been called on a successful write (e.g. crm.item.add). Not returned for management keys — the block is based on the request's HTTP method |
keyName |
Always | The key name from your account. If the key has no name — "unnamed" is returned |
currentMode |
Always | The key's effective mode — always "READONLY" for this error |
switchUrl |
Always | The path to the account page where the mode is switched — "/keys" |
Causes:
- An API key or authorization key (
vibe_api_,vibe_app_) inREADONLYmode made a call that proxies to Bitrix24 as a write operation: create, update, delete, an action on an entity. - A management key (
vibe_live_) inREADONLYmode made a request with thePOST,PATCH,PUT, orDELETEHTTP method — e.g. an attempt to create a key viaPOST /v1/keysor delete a feedback record.
Fix:
- The key owner — open API keys, in the relevant key's card under the Access mode block select "Read and write" and save. The mode applies to the next request, no reissue needed.
- If the toggle in the card is unavailable — the portal administrator restricted the mode. Ask the administrator to lift the restriction for this key.
- When working through an AI agent — the effective mode is returned by
GET /v1/mein thedata.accessModefield. If writes are needed permanently, issue a separate key in "read and write" mode.
#`VALIDATION_ERROR` (400)
The body or query parameters failed schema validation. Most V1 endpoints validate via Zod, so the message lists the specific problematic fields.
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "fields.title: Required; fields.stageId: Expected string, received number"
}
}
Causes:
- Required fields are missing.
- A value's type does not match the schema (string instead of number, wrong date format).
- The request body is invalid JSON or the
Content-Type: application/jsonheader is missing.
Fix:
- Check the body against the endpoint schema in the entity reference or on the specific endpoint page.
- Pass numbers without quotes, dates in ISO 8601 format (
2026-04-29T10:00:00). - Add the
Content-Type: application/jsonheader.
#`INVALID_PARAMS` (400)
Bitrix24 or the route handler found an invalid parameter value. Often appears as a wrapper for Bitrix24 errors of the form INVALID_PARAMS: ....
{
"success": false,
"error": {
"code": "INVALID_PARAMS",
"message": "Path parameter :id must be a positive integer"
}
}
Causes:
- An invalid path parameter value (e.g. a non-number where a number is expected).
- Bitrix24 rejected a request parameter (e.g. an unsupported enum field value).
Fix:
- Check the endpoint page: which values are valid for each parameter.
- For
filter, use the field list fromGET /v1/<entity>/fields.
#`MISSING_REQUIRED_FILTER` (400)
A required filter was not passed on a list endpoint that needs context.
{
"success": false,
"error": {
"code": "MISSING_REQUIRED_FILTER",
"message": "filter[entityType] and filter[entityId] are required for /v1/timelines"
}
}
Causes:
- The list of timeline records, comments, and other "nested" data requires a pair of parent identifiers.
Fix:
- Add the required filter parameters listed in
messageor on the endpoint page.
#`BATCH_LIMIT_EXCEEDED` (400)
The request exceeds the element limit in a bulk operation. At the /v1/batch level the limit is checked via INVALID_REQUEST referencing Array must contain at most 50 element(s). On domain bulk endpoints (e.g. chats, task-comments) — a dedicated BATCH_LIMIT_EXCEEDED code.
{
"success": false,
"error": {
"code": "BATCH_LIMIT_EXCEEDED",
"message": "Maximum 50 dialogs per bulk request (Bitrix24 batch limit)."
}
}
Causes:
- The array has more than 50 elements.
Fix:
- Split the operation into several requests of 50 elements each.
- Use batch requests for sequential calls from a single key.
#`ENTITY_NOT_FOUND` (404)
A CRM entity record with the given id does not exist or was deleted.
{
"success": false,
"error": {
"code": "ENTITY_NOT_FOUND",
"message": "Item not found"
}
}
Causes:
- A record with this
idgenuinely does not exist. - The record was deleted by a concurrent process.
- The wrong entity: the request goes to
/v1/deals/:id, but the ID is from a lead.
Fix:
- Check that the record exists via the entity's list endpoint.
- Restore it from the Bitrix24 recycle bin if it was deleted recently (via the portal interface).
#`RATE_LIMITED` (429)
Bitrix24 throttled the request rate or an internal VibeCode limit was triggered.
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "QUERY_LIMIT_EXCEEDED",
"hint": "Wait 1-2 seconds and retry. Use POST /v1/batch to combine up to 50 calls in 1 request.",
"retryAfter": 2
}
}
Response headers:
Retry-After: 2
Causes:
- Too many concurrent requests from a single key piled up.
- The requests-per-second limit on the Bitrix24 side was exceeded.
Fix:
- Wait for the time from
error.retryAfteror theRetry-Afterheader. - Implement retries with exponential backoff.
- Combine up to 50 calls via `POST /v1/batch`.
- Cache rarely changing reference data (fields, statuses, currencies).
#`ERROR_LOOP_DETECTED` (429)
VibeCode detects a series of identical errors on a single key for a single Bitrix24 method — and temporarily blocks the request on the VibeCode side to avoid inflating Bitrix24 counters. Every Nth request is forwarded onward: if the backend recovered, the block is lifted automatically.
{
"success": false,
"error": {
"code": "ERROR_LOOP_DETECTED",
"message": "Vibe-side block (not a Bitrix24 limit). 12 failures on crm.deal.list in the last hour.",
"hint": "Every 50th request will probe for recovery — keep retrying with backoff. If you suspect a platform-side issue (e.g. 5xx during an outage), platform admin can clear the block via POST /api/platform/analytics/circuit-breaker/<apiKeyId>/clear.",
"retryAfter": 60
}
}
Causes:
- A bug in the client code: a request with identical parameters repeats and consistently fails.
- A platform outage on the Bitrix24 side during the burst of requests.
Fix:
- Read
message— it names the specific method with the error series. - Find the request's source in the code, fix the parameters or logic.
- During a platform outage — the platform administrator can clear the block via
POST /api/platform/analytics/circuit-breaker/<apiKeyId>/clear.
#`BILLING_EXHAUSTED` (402)
The billing account dropped into the red zone: the balance is negative, the grace period is exhausted. Requests to create and wake infrastructure are blocked until a top-up.
{
"success": false,
"error": {
"code": "BILLING_EXHAUSTED",
"message": "Account is frozen due to negative balance.",
"userMessage": "The billing account is frozen due to a negative balance. Top up the account to continue working with servers and agents.",
"hint": "Top up the account at /billing/topup, then call POST /v1/portals/:id/refresh-tariff."
}
}
Causes:
- The balance has no funds to cover the hourly cost of servers and agents.
Fix:
- Top up the balance on the
/billing/topuppage. - After topping up, call
POST /v1/portals/:id/refresh-tariffto update the status.
#`COMMERCIAL_PLAN_REQUIRED` (402)
Creating servers and agents is unavailable on the free Bitrix24 plan after the trial period ends.
{
"success": false,
"error": {
"code": "COMMERCIAL_PLAN_REQUIRED",
"message": "Commercial Bitrix24 plan required for infrastructure operations.",
"userMessage": "Infrastructure creation is available on commercial Bitrix24 plans. The trial period has already been used.",
"hint": "Upgrade plan at https://www.bitrix24.ru/prices/, then call POST /v1/portals/:id/refresh-tariff."
}
}
Fix:
- Upgrade the Bitrix24 plan to a commercial one.
- After upgrading, call
POST /v1/portals/:id/refresh-tarifforGET /v1/me?refresh=tariff.
#`TRIAL_EXPIRED` (402)
The 14-day trial period has ended, the plan remained free.
{
"success": false,
"error": {
"code": "TRIAL_EXPIRED",
"message": "Trial period has ended.",
"userMessage": "The trial period (14 days) has ended. Switch to a commercial Bitrix24 plan to keep using servers and agents."
}
}
Fix:
- Switch to a commercial Bitrix24 plan.
- Update the status via
POST /v1/portals/:id/refresh-tariff.
#`BITRIX_ERROR` (422)
Bitrix24 returned a business error that does not fall under narrower categories (ACCESS_DENIED, NOT_FOUND, INVALID_PARAMS, RATE_LIMITED).
{
"success": false,
"error": {
"code": "BITRIX_ERROR",
"message": "Invalid filter: field 'NON_EXISTENT_FIELD' is not allowed in filter",
"hint": "Known Bitrix24 limitation: …"
}
}
Causes:
- Bitrix24 rejected the operation for a business reason: incompatible state, unsupported value, business rule.
- The request runs on a portal where the corresponding module is disabled.
Fix:
- Read
message— it holds the original error text from Bitrix24. - If
hintis present — use it as the first diagnostic step.
#`BITRIX_UNAVAILABLE` (502)
Bitrix24 returned 5xx or did not respond within the allotted time.
{
"success": false,
"error": {
"code": "BITRIX_UNAVAILABLE",
"message": "Bitrix24 returned 503 Service Unavailable"
}
}
Causes:
- Maintenance or overload on the Bitrix24 side.
- Network problems between VibeCode and the portal.
Fix:
- Retry the request after a few minutes, implementing retries with exponential backoff.
- Check the portal status at
/bitrix/admin/site_checker.php(for the portal administrator).
#`QUEUE_TIMEOUT` (504)
The request queue to Bitrix24 for a specific portal is saturated: more than 30 seconds of waiting.
{
"success": false,
"error": {
"code": "QUEUE_TIMEOUT",
"message": "Portal queue saturated — too many concurrent Bitrix24 calls",
"userMessage": "Requests to Bitrix24 have been queued for over 30 seconds. The portal likely has many concurrent operations.",
"hint": "If this is a /search request with a wide date range, try adding \"autoWindow\": false OR narrow the date range to <14 days. See /v1/guide for optimization tips.",
"retryAfter": 10
}
}
Fix:
- Reduce concurrency, return a retry to the client after
retryAfterseconds. - For
/searchendpoints — narrow the date range or passautoWindow: false. - Combine calls via
POST /v1/batch.
#`INTERNAL_ERROR` (500)
An unexpected error on the Vibe API side.
{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error"
}
}
Fix:
- Retry the request.
- If the error reproduces consistently — submit a ticket via
POST /v1/feedbackwith the request time. TheX-Request-Idheader from the response speeds up diagnosis.
#Error handling in code
#JavaScript
async function vibeRequest(url, options = {}) {
const response = await fetch(url, {
...options,
headers: {
'X-Api-Key': process.env.VIBE_API_KEY,
'Content-Type': 'application/json',
...options.headers,
},
});
const data = await response.json();
if (!data.success) {
const { code, message, retryAfter } = data.error;
switch (code) {
case 'RATE_LIMITED':
case 'QUEUE_TIMEOUT': {
const wait = retryAfter ?? Number(response.headers.get('Retry-After')) ?? 1;
await new Promise(r => setTimeout(r, wait * 1000));
return vibeRequest(url, options);
}
case 'BITRIX_UNAVAILABLE':
await new Promise(r => setTimeout(r, 5000));
return vibeRequest(url, options);
case 'MISSING_API_KEY':
case 'INVALID_API_KEY':
throw new Error('Check the API key');
default:
throw new Error(`${code}: ${message}`);
}
}
return data;
}
#Python
import os
import time
import requests
def vibe_request(url, method="GET", json_data=None):
headers = {
"X-Api-Key": os.environ["VIBE_API_KEY"],
"Content-Type": "application/json",
}
response = requests.request(method, url, headers=headers, json=json_data)
data = response.json()
if not data.get("success"):
err = data.get("error", {})
code = err.get("code")
message = err.get("message")
retry_after = err.get("retryAfter") or int(response.headers.get("Retry-After", 1))
if code in ("RATE_LIMITED", "QUEUE_TIMEOUT"):
time.sleep(retry_after)
return vibe_request(url, method, json_data)
if code == "BITRIX_UNAVAILABLE":
time.sleep(5)
return vibe_request(url, method, json_data)
raise Exception(f"{code}: {message}")
return data
#PHP
function vibeRequest(string $url, string $method = 'GET', ?array $data = null): array {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => [
'X-Api-Key: ' . getenv('VIBE_API_KEY'),
'Content-Type: application/json',
],
]);
if ($data !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$body = json_decode(curl_exec($ch), true);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($body === null) {
throw new Exception("HTTP error: $httpCode");
}
if (empty($body['success'])) {
$errCode = $body['error']['code'] ?? 'UNKNOWN';
$errMsg = $body['error']['message'] ?? 'Unknown error';
$retryAfter = $body['error']['retryAfter'] ?? 1;
if (in_array($errCode, ['RATE_LIMITED', 'QUEUE_TIMEOUT'], true)) {
sleep((int) $retryAfter);
return vibeRequest($url, $method, $data);
}
if ($errCode === 'BITRIX_UNAVAILABLE') {
sleep(5);
return vibeRequest($url, $method, $data);
}
throw new Exception("$errCode: $errMsg");
}
return $body;
}
#See also
- Quickstart — your first request in 2 minutes
- Keys and authorization — key types, format, scopes
- Optimization and batch — reducing call volume and avoiding
RATE_LIMITED - Batch requests — combining up to 50 calls into one request
- CLI and cURL — working via the command line
- MCP for AI — integration with AI tools