For AI agents: markdown of this page — /docs-content-en/ai/chat.md documentation index — /llms.txt

Chat completions

Generate a model's response through a single OpenAI-compatible endpoint. Supports synchronous mode, streaming via Server-Sent Events, function calling, a guaranteed JSON response, and working with images.

Scope: vibe:ai

Create a chat completion

The response arrives in raw OpenAI format.

The {success, data} wrapper used in the other Vibecode endpoints — /v1/deals, /v1/tasks and others — is absent here.

This is done for compatibility with the OpenAI SDK. If you have a single client that checks if (!response.success), add an exception for the AI Router.

POST /v1/chat/completions

Generates an AI model's response to an array of messages. The request and response format is compatible with POST /v1/chat/completions from the OpenAI API.

The endpoint's capabilities are documented on separate pages: streaming, guaranteed JSON response, function calling, image analysis and rate limits.

Request fields (body)

Field Type Req. Default Description
model string no auto Model ID or alias. See the "Model aliases" section below. If the field is not passed or equals auto, the request runs on the Bitrix24 account's default model. The list of available models — GET /v1/models
messages array yes Array of conversation messages. Minimum 1, maximum 256
messages[].role string yes Role: system, user, assistant, tool
messages[].content string | array | null yes Message text. Maximum 500,000 characters in a single message or 64 elements in the content array. For requests with images — an array with type: "text" and type: "image_url". An assistant message with tool_calls may have null content
messages[].name string no Sender name (multi-agent scenarios)
messages[].tool_calls array no Function calls from the assistant — present in the model's response when finish_reason: "tool_calls"
messages[].tool_call_id string no Function call ID — required in a message with role: "tool"
temperature number no per model Generation temperature, range 0..2. Lower values are more precise and deterministic, higher values are more creative
max_tokens number no per model Maximum tokens in the response
top_p number no Nucleus sampling, range 0..1
stop string | array no Stop sequences (up to 4, each up to 64 characters)
stream boolean no false If true — the response arrives as a stream of Server-Sent Events
response_format object no Control the response format: {"type": "text"} — the default, {"type": "json_object"} — valid JSON, {"type": "json_schema", "json_schema": {...}} — strict JSON Schema, requires model support
tools array no Definitions of functions the model may call
tool_choice string | object no auto (the model decides on its own), none (forbid calls) or {"type": "function", "function": {"name": "..."}} (force a specific one)

Model aliases

The model field accepts three values that resolve to the Bitrix24 account's default model (currently bitrix/bitrixgpt-5.5): auto, bitrix/free and an empty string.

The models bitrix/bitrixgpt-5 and bitrix/bitrixgpt-5-vl are marked as deprecated and work until July 31, 2026. After that date, requests to them are transparently redirected to bitrix/bitrixgpt-5.5 with the X-Model-Replacement header — see model lifecycle for details.

In addition, a partial modelId is matched against the catalog by substring: if you pass gpt-4o-mini, the platform picks a model available to your key whose identifier contains that substring.

Examples

curl — personal key

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/chat/completions \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bitrix/bitrixgpt-5.5",
    "messages": [
      {"role": "system", "content": "You are a sales expert. Classify leads by quality."},
      {"role": "user", "content": "Acme LLC, 50 users, budget 500 thousand per month."}
    ],
    "temperature": 0.3,
    "max_tokens": 300
  }'

curl — OAuth application

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/chat/completions \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bitrix/bitrixgpt-5.5",
    "messages": [
      {"role": "system", "content": "You are a sales expert. Classify leads by quality."},
      {"role": "user", "content": "Acme LLC, 50 users, budget 500 thousand per month."}
    ],
    "temperature": 0.3,
    "max_tokens": 300
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'bitrix/bitrixgpt-5.5',
    messages: [
      { role: 'system', content: 'You are a sales expert. Classify leads by quality.' },
      { role: 'user', content: 'Acme LLC, 50 users, budget 500 thousand per month.' },
    ],
    temperature: 0.3,
    max_tokens: 300,
  }),
})

const data = await res.json()
console.log(data.choices[0].message.content)
console.log('Tokens:', data.usage.total_tokens)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'bitrix/bitrixgpt-5.5',
    messages: [
      { role: 'system', content: 'You are a sales expert. Classify leads by quality.' },
      { role: 'user', content: 'Acme LLC, 50 users, budget 500 thousand per month.' },
    ],
    temperature: 0.3,
    max_tokens: 300,
  }),
})

const data = await res.json()
console.log(data.choices[0].message.content)

Response fields

Field Type Description
id string Unique completion ID for tracking
object string Always chat.completion for a synchronous response
created number Unix timestamp of the completion's creation
model string The model actually used (may differ from the request's model on automatic fallback to a backup model or a DISABLED redirect)
choices array The model's response variants. Without the n parameter the array has a single element
choices[].index number Variant ordinal number
choices[].finish_reason string Reason the generation finished: stop, length, tool_calls, content_filter
choices[].message object The generated message
choices[].message.role string Always assistant
choices[].message.content string | null Response text. null when finish_reason: "tool_calls" — the content is in tool_calls
choices[].message.tool_calls array List of function calls (if the model decided to call them)
warnings array Warnings about what the platform changed in the request or what to account for in the response. Every element carries at least code and message, some warnings add more fields. Known codes: MAX_TOKENS_RAISED, COWORK_QUOTA_FALLBACK (also carries tier, nextTier, resetAt), THINKING_TRUNCATED. The field is absent when there are no warnings
usage.prompt_tokens number Input tokens
usage.completion_tokens number Response tokens
usage.total_tokens number Sum of tokens in the request and response

Response example

JSON
{
  "id": "chatcmpl-a1a73c6eb3f180fd",
  "object": "chat.completion",
  "created": 1777289339,
  "model": "bitrix/bitrixgpt-5.5",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "Quality: HIGH\n\nRationale:\n- Legal entity (LLC) — B2B client\n- Budget 500 thousand per month — above average\n- Specific volume (50 users) — a deliberate need\n\nRecommendation: schedule a call within 24 hours."
      }
    }
  ],
  "usage": {
    "prompt_tokens": 42,
    "completion_tokens": 85,
    "total_tokens": 127
  }
}

Error response example

404 ai_model_not_found — model not found or the key has no access to it:

JSON
{
  "error": {
    "message": "Model \"anthropic/claude-imaginary-x\" not found or disabled.",
    "type": "invalid_request_error",
    "code": "ai_model_not_found"
  }
}

Errors

HTTP Code Description
400 invalid_request Empty messages array, invalid role, schema violation
400 invalid_image_payload Invalid image_url — the message contains the content element index and the reason. See image analysis
400 no_default_model The portal has no models available to call
402 ai_credentials_not_configured No provider credentials for the model — connect BYOK
402 insufficient_balance Insufficient funds for a paid model
402 ai_quota_exhausted The portal's monthly AI quota is exhausted. The reason field clarifies the cause
403 scope_missing The API key is missing the vibe:ai scope
404 ai_model_not_found Model not found or disabled
422 structured_output_truncated A request with response_format did not produce a complete JSON: generation was cut off with finish_reason: "length", or the content field is empty with any finish reason and without tool_calls. The json_object mode has an exception — a complete JSON that landed in the service reasoning_content channel is recovered and the response stays 200. See guaranteed JSON response
429 rate_limit_exceeded The rate limit is exceeded. The X-RateLimit-Scope header indicates the level — per-key or per-user
429 ai_congested The AI cluster pool is overloaded. The request did not run and nothing was charged — retry it after the delay in the Retry-After header. The response carries the X-AI-Admission: shed header, not X-RateLimit-Scope
429 ai_pacing_limited A daily or weekly quota pacing window is exceeded. This is not quota exhaustion — retry the request after the delay in the Retry-After header. See Pacing (day/week smoothing)
400 ai_provider_rejected The model rejected the request itself (for example an unsupported parameter). Retrying it unchanged will not help. Returned when the provider responded with 400 or 422
502 ai_provider_unavailable The external provider returned an error (401/403/5xx) or is unavailable
503 model_unavailable The model is disabled and no successor is assigned for it. See model lifecycle
503 pool_exhausted The platform is temporarily overloaded. Retry the request after the number of seconds in Retry-After — 3-7 seconds with random jitter

The full list of common API errors — Errors.

Known specifics

Automatic fallback to a backup model on a provider failure. If a paid model returns a 5xx error or times out, the synchronous request is retried with the default model. The X-Model-Fallback: <original modelId> header appears in the response. In streaming mode there is no such fallback — the client receives an error in the last event before data: [DONE].

The Bitrix24 account's monthly AI quota. On Bitrix24 accounts with quota control enabled, a request may return 402 ai_quota_exhausted. The reason field distinguishes three cases: breaker — the hourly over-quota spending breaker tripped, wallet_empty — the quota is exhausted and the account balance has no funds, wallet_off — over-quota spend is not available for the account. The resetAt field holds the moment when requests will pass again. For wallet_off it may be absent. In the wallet_empty case the response may additionally carry a hint string and a topupUrl link to top up the balance — both fields appear when enforced quota control and the top-up hint are enabled on the platform, so read them as optional. The hint field in this response is a string. While usage stays within the quota, the endpoint's behavior is unchanged. Beyond the quota, if such spend is allowed for the account, requests are charged to the account's money balance at the model's base catalog price.

The processing budget for a synchronous request is about 850 seconds. Once the budget runs out, 503 ai_provider_timeout is returned. This response deliberately carries no Retry-After header: repeating the same request would hit the same budget. Reduce the request size or switch to streaming — there an idle timeout between events applies instead of a single budget for the whole call.

Request body size limit — 30 MiB. This is enough to pass a single image of up to 20 MiB: after base64 encoding it takes about 27 MiB.

Passing content as an array. For text models, pass content as a string. An array with a single text element also works but is redundant. An array is required only for requests with images.

See also