لوكلاء AI: ملف markdown لهذه الصفحة — /docs-content-en/ai/chat.md فهرس التوثيق — /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 by 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 Required Default Description
Fieldmodel Typestring Requiredno Defaultauto DescriptionModel ID or alias. See the "Model aliases" section below. If the field is omitted or set to auto, the request runs on the Bitrix24 account's default model. The list of available models — GET /v1/models
Fieldmessages Typearray Requiredyes Default— DescriptionArray of conversation messages. Minimum 1, maximum 256
Fieldmessages[].role Typestring Requiredyes Default— DescriptionRole: system, user, assistant, tool
Fieldmessages[].content Typestring | array | null Requiredyes Default— DescriptionMessage 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
Fieldmessages[].name Typestring Requiredno Default— DescriptionSender name (multi-agent scenarios)
Fieldmessages[].tool_calls Typearray Requiredno Default— DescriptionFunction calls from the assistant — present in the model's response when finish_reason: "tool_calls"
Fieldmessages[].reasoning_content Typestring | null Requiredno Default— DescriptionThe model's reasoning from an earlier response, sent back into the conversation history. Honored only for the assistant role and ignored on messages with other roles. A null value is the same as omitting the field, and an empty string is accepted. A non-string value or one longer than 4,000,000 characters is rejected with 400 invalid_request. The field reaches the model when its owned_by in GET /v1/models is bitrix, openrouter or vibecode, and it is not sent to models from OpenAI, Anthropic or other OpenAI-compatible providers. A model that reads the reasoning counts it as input tokens. See function calling for how it is used
Fieldmessages[].tool_call_id Typestring Requiredno Default— DescriptionFunction call ID — required in a message with role: "tool"
Fieldtemperature Typenumber Requiredno Defaultper model DescriptionGeneration temperature, range 0..2. Lower values make the output more precise and deterministic; higher values make it more creative
Fieldmax_tokens Typenumber Requiredno Defaultper model DescriptionMaximum tokens in the response
Fieldtop_p Typenumber Requiredno Default— DescriptionNucleus sampling, range 0..1
Fieldreasoning_effort Typestring Requiredno Defaultper model DescriptionOpenAI-compatible reasoning level: none, minimal, low, medium, high, xhigh, max. Normalized to a platform step — see Reasoning control
Fieldreasoning Typeobject Requiredno Default— DescriptionThe canonical object. effort — a level from the same vocabulary. max_tokens — reasoning token budget, honored only on models with budgetTokens: true. enabled — false disables reasoning. exclude — true removes reasoning_content from the response; reasoning tokens are still billed. Takes precedence over reasoning_effort
Fieldchat_template_kwargs Typeobject Requiredno Default— DescriptionVendor format {"thinking": boolean, "reasoning_effort": string}. Accepted for compatibility, resolved to the same step and never forwarded to the model raw. Unknown keys inside are ignored. Lowest precedence of the three fields
Fieldstop Typestring | array Requiredno Default— DescriptionStop sequences (up to 4, each up to 64 characters)
Fieldstream Typeboolean Requiredno Defaultfalse DescriptionIf true, the response arrives as a stream of Server-Sent Events
Fieldresponse_format Typeobject Requiredno Default— DescriptionControls the response format: {"type": "text"} — the default, {"type": "json_object"} — valid JSON, {"type": "json_schema", "json_schema": {...}} — strict JSON Schema, requires model support
Fieldrepetition_guard Typestring Requiredno Default"off" Description"off" or "abort". Explicit early refusal on repeated JSON. Requires json_object/json_schema, no declared tools and a streaming-capable model even with stream: false. Restrictions, false-positive risk and SDK example: JSON response
Fieldtools Typearray Requiredno Default— DescriptionDefinitions of functions the model may call
Fieldtool_choice Typestring | object Requiredno Default— Descriptionauto (the model decides on its own), none (forbid calls) or {"type": "function", "function": {"name": "..."}} (force a specific one)

Reasoning control

Reasoning models think before they answer. Reasoning tokens count towards usage.completion_tokens and are billed as output tokens at the same rate — the price lever is volume, not the rate. Vibecode describes that volume with five steps: none — answer immediately, low — a brief sketch, medium — the model's standard reasoning when it is enabled and no level is given, high — stronger than standard, max — everything the model can do.

The reasoning field in GET /v1/models shows what a particular model supports. Its map maps the steps onto the model's native modes; two steps sharing one native value are a declared collapse. default is the default step, and budgetTokens indicates support for a reasoning token budget. On a model with reasoning: null, control is unavailable: the parameter is ignored with the REASONING_NOT_SUPPORTED warning, and nothing is added to the model call.

Input normalization: minimal → low, xhigh → max. reasoning.enabled: true or chat_template_kwargs.thinking: true without a level gives medium. reasoning.max_tokens without effort gives medium with a budget. An empty reasoning: {} or chat_template_kwargs: {} is the same as no parameter. null in any of the three fields is equivalent to omitting it. When several fields arrive, the highest-precedence one wins: reasoning first, then reasoning_effort, then chat_template_kwargs. A value outside the vocabulary, a non-positive reasoning.max_tokens or a non-object chat_template_kwargs is rejected with 400 invalid_request.

If the model lacks the requested step, the nearest step below among the reasoning steps is applied, and warnings carries REASONING_EFFORT_ADJUSTED with the requested, applied and direction fields. The none step is never chosen by rounding — reasoning can only be disabled explicitly. If there is no step below, the nearest step above is taken. Asking for none on a model where reasoning cannot be disabled gives the lowest step and REASONING_CANNOT_BE_DISABLED. A budget on a model without budgetTokens is ignored with REASONING_BUDGET_NOT_SUPPORTED.

When the request omits the parameter, the platform explicitly sends the default step to a model with a reasoning declaration. The mode is not left to the model provider, so a model update on the provider's side does not change the behavior of requests without the parameter. The response's reasoning field reports that step.

The response carries the reasoning field with requested, applied and native, plus warnings in warnings. In streaming mode the body carries no warnings — the state travels in the X-Reasoning-Applied, X-Reasoning-Native and X-Reasoning-Warnings headers, the last one carrying comma-separated codes. On a synchronous response the same headers duplicate the body. A header is absent when there is nothing to report. When the model is substituted — a DISABLED redirect or a fallback to the backup model — the step is resolved against the model that ran the request, and the reasoning field and headers describe that model. reasoning.exclude is honored on every model, including ones without a reasoning declaration.

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, model accepts a model identifier without the provider prefix: bitrixgpt-5.5 resolves to bitrix/bitrixgpt-5.5. The short name must be an exact, case-sensitive match for an identifier from GET /v1/models with its first segment dropped. There is no partial matching: a request with bitrixgpt gets 404 ai_model_not_found, not the first model whose identifier contains that word. A request with a short name that matches several models available to your key also gets 404 — pass the full identifier. A model found by its short name is flagged in the response with the X-Model-Resolved header carrying its full identifier.

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,000 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,000 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,000 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,000 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
Fieldid Typestring DescriptionUnique completion ID for tracking
Fieldobject Typestring DescriptionAlways chat.completion for a synchronous response
Fieldcreated Typenumber DescriptionUnix timestamp of when the completion was created
Fieldmodel Typestring DescriptionThe model actually used. It differs from the request's model when the model was found by its short name, on automatic fallback to a backup model and on a DISABLED redirect
Fieldchoices Typearray DescriptionThe model's response choices. Without the n parameter the array has a single element
Fieldchoices[].index Typenumber DescriptionIndex of the choice
Fieldchoices[].finish_reason Typestring DescriptionReason the generation finished: stop, length, tool_calls, content_filter
Fieldchoices[].message Typeobject DescriptionThe generated message
Fieldchoices[].message.role Typestring DescriptionAlways assistant
Fieldchoices[].message.content Typestring | null DescriptionResponse text. null when finish_reason: "tool_calls" — the content is in tool_calls
Fieldchoices[].message.tool_calls Typearray DescriptionList of function calls (if the model decided to call them)
Fieldwarnings Typearray DescriptionWarnings 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, TOOL_CALL_MISSING, REASONING_EFFORT_ADJUSTED (carries requested, applied, direction), REASONING_NOT_SUPPORTED, REASONING_CANNOT_BE_DISABLED, REASONING_BUDGET_NOT_SUPPORTED, TEMPERATURE_OVERRIDDEN_BY_REASONING. The field is absent when there are no warnings
Fieldreasoning Typeobject DescriptionPresent on models with a reasoning declaration. requested — the normalized step from the request, null when no parameter was sent. applied — the step actually applied. native — the model's native mode for that step. See Reasoning control
Fieldusage.prompt_tokens Typenumber DescriptionInput tokens
Fieldusage.completion_tokens Typenumber DescriptionResponse tokens
Fieldusage.total_tokens Typenumber DescriptionSum of tokens in the request and response

If a request with tools ends without a usable answer or function call, content may gain an English explanation and warnings may carry { code: "TOOL_CALL_MISSING", message: "..." } with the same text. Any existing text is kept, followed by a blank line and the explanation. HTTP 200, finish_reason: "stop" and usage are preserved; the explanation does not affect billing. It is not added for tool_choice: "none", structured output or reasoning-only turns ending with stop. In streams it is a separate delta.content event before the finish, without a warnings array.

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,000 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
HTTP400 Codeinvalid_request DescriptionEmpty messages array, invalid role, schema violation or invalid repetition_guard. An incompatible "abort" returns param: "repetition_guard" before any reservation or model call
HTTP400 Codeinvalid_image_payload DescriptionInvalid image_url — the error message contains the content element index and the reason. See image analysis
HTTP400 Codeno_default_model DescriptionThe portal has no models available to call
HTTP402 Codeai_credentials_not_configured DescriptionNo provider credentials for the model — connect BYOK
HTTP402 Codeinsufficient_balance DescriptionInsufficient funds for a paid model
HTTP402 Codeaccount_frozen DescriptionThe call is blocked because the billing account is frozen due to a negative balance. Top up that account; the response message explains why this call was blocked. Calls covered by the plan's AI quota can keep working; see the account freeze scope
HTTP402 Codeai_quota_exhausted DescriptionThe portal's monthly AI quota is exhausted. The reason field clarifies the cause
HTTP402 Codecowork_subscription_inactive DescriptionA key carrying the vibe:cowork scope has no active Cowork/Code subscription. Resume the subscription in the Cowork/Code section of your Vibecode account; the key itself stays valid
HTTP402 Codecowork_quota_exhausted DescriptionOne of the Cowork/Code subscription quota windows is exhausted. The body carries window (5h/week/month), resetAt and nextTier; the Retry-After header holds the number of seconds until the window resets
HTTP402 Codecompany_budget_exhausted DescriptionThe monthly company spend budget set by the portal administrator is exhausted. The scope field names the budget that was hit: USER — the caller's own budget, PORTAL — the budget of the whole portal. The canRequest field indicates whether an increase can be requested: true for a personal budget, false for the portal one, which only an administrator raises. The rejection arrives only on calls that draw on the portal balance. Calls inside the plan quota, on a Cowork/Code subscription and with your own provider key (BYOK) keep working
HTTP403 Codescope_missing DescriptionThe API key is missing the vibe:ai scope. For a key issued to a third-party application through Partner Connect, the scope is added by requesting it on the consent page rather than by re-issuing the key — see Platform scopes
HTTP403 CodeCONNECT_AI_NOT_PERMITTED DescriptionThe key belongs to a third-party application from Partner Connect, and the account administrator has not allowed AI for the application or has revoked the permission. Returned when the platform has enabled AI approval by account administrators. The body is in the general API envelope { success, error: { code, message } }, not in the OpenAI format
HTTP404 Codeai_model_not_found DescriptionModel not found or disabled
HTTP404 Codeai_model_not_found DescriptionThe model's short name matches several available models. Pass the full identifier
HTTP409 Codeagent_turn_awaiting_confirmation DescriptionThe AI agent is waiting for the user to confirm or cancel an operation. Until the user answers, its key's requests to this endpoint are refused in any conversation. The request is not sent to the model and nothing is charged. With stream: true the refusal arrives as a JSON response. The wait ends when the user answers, or expires on its own: the agent sets the limit, at most 30 minutes. Requests made with other keys are not affected
HTTP409 Codeagent_turn_loop_detected DescriptionThe agent turn is stuck in a loop: after the last message with the user role, messages holds 20 or more assistant replies without tool_calls. All such replies count, not only consecutive ones; replies with tool_calls do not count. The request is not sent to the model and nothing is charged. With stream: true the refusal arrives as a JSON response and no event stream is opened. To continue, add a new message with the user role to messages — the count starts over
HTTP413 Codeai_payload_too_large DescriptionThe request body for a bitrix/* model exceeds 2 MiB even after image downscaling. The request is not sent to the model and nothing is charged. The message states the request size and the limit in effect. The same code arrives when the model cluster itself, or the provider of a model on your own key, refused the request because of its size: the body then carries providerStatusCode: 413. Downscale the images — image analysis
HTTP422 Codestructured_output_truncated DescriptionA request with response_format did not produce a complete JSON document: generation was cut off with finish_reason: "length" without detected repetition, or the content field is empty and there are no tool_calls, whatever the finish reason. The json_object mode has an exception — a complete JSON document that landed in the internal reasoning_content channel is recovered and the response stays 200. See guaranteed JSON response
HTTP422 Codestructured_output_invalid_json DescriptionA request with response_format produced a non-empty response that does not parse as a JSON object or array — prose around the object, an answer wrapped in a markdown code fence, a bare value such as 42. The body carries no param and no suggestedMaxTokens: raising max_tokens does not change the result. The json_object mode has the same exception — a complete JSON document that landed in the internal reasoning_content channel is recovered and the response stays 200. See guaranteed JSON response
HTTP422 Codereasoning_repetition DescriptionThe model got stuck in its reasoning: it kept repeating the same sentences and never started the answer. In a synchronous response it replaces structured_output_truncated on requests with response_format; in a stream it arrives as an event before data: [DONE] on any request. Send the request again with reasoning_effort: "none"; a larger max_tokens will not help. See guaranteed JSON response
HTTP422 Codereasoning_repetition DescriptionBy default (repetition_guard omitted or "off"), repetition was detected in non-empty incomplete JSON with json_object or json_schema after finish_reason: "length". The check is terminal. This is a heuristic diagnosis: it can also trigger on a legitimate repetitive array that exceeded the budget. Check whether repetition is expected; if so, check the token budget, otherwise revise the request or use another model. The response carries no hint to disable reasoning
HTTP422 Codereasoning_repetition DescriptionWith an explicit repetition_guard: "abort", repeated JSON was detected before completion. A synchronous request returns an ordinary JSON 422; a stream returns one error event and one data: [DONE] with HTTP 200. Discard the partial response. The response carries no retryable/retryAfter fields and no advice to disable reasoning. Conditions and fixed text: JSON response
HTTP429 Coderate_limit_exceeded DescriptionThe rate limit is exceeded. The X-RateLimit-Scope header indicates the level — per-key or per-user. The same code arrives when the model cluster itself throttled the request: the body then carries the providerStatusCode field, there is no scope field or X-RateLimit-Scope header, and the pause comes from Retry-After
HTTP429 Codeai_congested DescriptionThe 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
HTTP429 Codeai_pacing_limited DescriptionA 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)
HTTP429 Codeai_provider_cooldown DescriptionThe model cluster is temporarily unavailable and the platform backs off so retries do not pile up on it. The request was not executed and nothing was charged — retry it after the number of seconds in Retry-After. This response carries neither X-RateLimit-Scope nor X-AI-Admission
HTTP429 Codeai_image_resize_busy DescriptionThe platform is already downscaling many images at once, and the request body for a bitrix/* model does not fit the limit without downscaling. The request was not executed and nothing was charged — retry it after the number of seconds in Retry-After, or downscale the images yourself
HTTP400 Codeai_provider_rejected DescriptionThe 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
HTTP502 Codeai_provider_unavailable DescriptionThe external provider answered with an error (401/403/5xx). The original status arrives in the providerStatusCode field whenever the provider answered with an HTTP status — including when the stream to the client is already open and the provider refused to establish the upstream one. The field is absent where there was no status: the error arrived as a frame from the body of an already open stream (the platform accepts only the 429 status from the body, and such a frame arrives as rate_limit_exceeded) or the failure happened while processing the provider's response
HTTP502 Codeai_provider_network DescriptionThe platform could not connect to the provider, or the connection dropped before a response. This response carries no providerStatusCode: the provider never answered. Retry the request
HTTP503 Codemodel_unavailable DescriptionThe model is disabled and no successor is assigned for it. See model lifecycle
HTTP503 Codepool_exhausted DescriptionThe 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].

Exhausted Cowork/Code quota: the response announces the limit instead of doing the work. This is a separate state, unrelated to X-Model-Fallback above: that header marks a model substitution, whereas here the subscription quota is exhausted. When a quota window is exhausted and a backup model is configured on the platform, the request returns 200, but no work is done for it: the tools, tool_choice and response_format fields are stripped, the request's own system messages have no effect, and the model states that the limit is reached and when it resets. The markers of this state are the X-Cowork-Fallback: true header and the COWORK_QUOTA_FALLBACK warning in the warnings array. In streaming mode there is no warning in the body; the state is visible from the header. Nothing is charged for such a response and no quota is spent. Do not expect tool_calls or schema-shaped JSON here: even with response_format in the request you get plain text. When no backup model is configured — or the configured one fails to answer — 402 cowork_quota_exhausted arrives instead. The response code does not tell those two cases apart, so always handle 402 on this endpoint.

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 treat them as optional. The hint field in this response is a string. When the Bitrix24 account has no paid AI access, a reason: "wallet_off" response additionally carries details.learnMoreUrl — a page that describes the paid Bitrix24 plan that includes AI — and the message field names that plan. For other wallet_off causes details.learnMoreUrl is absent. 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, where an idle timeout between events applies instead of a single budget for the whole call.

Request body size limit. For bitrix/* models the limit is 2 MiB for the whole body, images included. The platform downscales data: images in a body over the limit, and a body still over it gets 413 ai_payload_too_large. For models called with your own provider key, the limit is 30 MiB, enough for a single image of up to 20 MiB. How the platform downscales images — image analysis.

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