SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
13 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
172.2 KB · 883 lines python
Raw Blame History
1#!/usr/bin/env python32"""Single source for the cross-provider feature matrix (OpenAI · Anthropic · xAI · Gemini).3Emits docs/comparisons/features.md and generated/compatibility/cross-provider-feature-matrix.json.4Every cell is traceable to generated/*.json or a docs page (column 'ref'). Re-runnable.56Cell convention: side(supported, how, endpoint, params, status, notes). `portable` = the same task is expressible7with an equivalent parameter on EVERY provider that offers the feature (False when only one provider offers it)."""8import json9ROOT = "/Users/simon-pierreboucher/Desktop/doc-api"10TODAY = "2026-09-18"11PROVIDERS = ["openai", "anthropic", "xai", "gemini"]12LABEL = {"openai": "OpenAI", "anthropic": "Anthropic", "xai": "xAI", "gemini": "Gemini"}1314def side(supported, how="", endpoint="", params=None, status=None, notes=""):15    return {"supported": supported, "how": how, "endpoint": endpoint,16            "params": params or [], "status": status or [], "notes": notes}1718NO = side(False, "not offered", "", [], ["UNVERIFIED"], "no equivalent surface in the documented API")19def no(note): return side(False, "not offered", "", [], ["DOCUMENTED"], note)2021ROWS = []22def row(section, feature, oai, ant, xai, gem, portable, diff, ref):23    sup = [p for p, s in zip(PROVIDERS, (oai, ant, xai, gem)) if s["supported"]]24    ROWS.append({"section": section, "feature": feature, "openai": oai, "anthropic": ant, "xai": xai, "gemini": gem,25                 "providers_supporting": sup, "provider_count": len(sup),26                 "portable": bool(portable) and len(sup) >= 2, "notes": diff, "ref": ref})2728# Common xAI / Gemini shorthands29XR = "POST /v1/responses"30GC = "POST /v1beta/models/{model}:generateContent"31IX = "POST /v1beta/interactions"3233# ============================================================ Core generation34S = "Core generation"35row(S, "Primary text/multimodal generation endpoint",36    side(True, "Responses API: `input` (string or Item[]), `output[]` items", "POST /v1/responses", ["model","input","instructions","tools","text","reasoning"], ["DOCUMENTED","LIVE_VERIFIED"], "stored by default (`store:true`, 30 days)"),37    side(True, "Messages API: `messages[]` of content blocks, `content[]` blocks out", "POST /v1/messages", ["model","messages","system","max_tokens","tools","output_config","thinking"], ["DOCUMENTED","LIVE_VERIFIED"], "stateless; `max_tokens` required (400 if missing)"),38    side(True, "Responses API clone: same `input` items / `output[]` items as OpenAI (`message`, `reasoning`, `function_call`, `web_search_call`, `code_interpreter_call`, `mcp_call`…); xAI extras `max_turns`, `top_k`, `min_p`, `reasoning_effort`; `usage.cost_in_usd_ticks`", XR, ["model","input","instructions","tools","text","reasoning","max_turns","store"], ["DOCUMENTED","LIVE_VERIFIED"], "stored by default (30 days); `background` → 400; `metadata` → 400; every Grok call bills reasoning tokens"),39    side(True, "`generateContent`: `contents[] {role: user|model, parts[]}` → `candidates[].content.parts[]`; `generationConfig` holds every knob; Google calls it 'legacy' since June 2026 in favour of the **Interactions API** (`POST /v1beta/interactions`, snake_case, `model` or `agent`, `input`, `steps[]` out)", GC, ["contents","systemInstruction","generationConfig","tools","toolConfig","safetySettings","cachedContent"], ["DOCUMENTED","LIVE_VERIFIED"], "`/v1` stable twin exists for generateContent; Interactions `/v1beta` BETA + LIVE_VERIFIED, `/v1` GA but UNVERIFIED"),40    True, "Four envelopes, two shapes: OpenAI and xAI share the **items** model (xAI reimplements the Responses API); Anthropic uses **content blocks**; Gemini uses **parts** inside `contents[]` with `generationConfig`. Required fields differ: Anthropic needs `max_tokens`; Gemini needs the last turn to be `user`; xAI rejects `background`/`metadata`.",41    "docs/openai/responses.md · docs/anthropic/messages-api.md · docs/xai/responses.md · docs/gemini/generate-content.md · docs/gemini/interactions-api.md")42row(S, "Legacy / secondary chat endpoint",43    side(True, "Chat Completions (`messages[]`, `choices[]`), still GA and maintained", "POST /v1/chat/completions", ["messages","response_format","reasoning_effort","web_search_options"], ["DOCUMENTED","LIVE_VERIFIED"], "no hosted tools except search models; list/retrieve/update/delete of stored completions"),44    no("none — Messages is the only chat surface"),45    side(True, "Chat Completions, OpenAI-compatible; xAI calls it the **legacy predecessor** of `/v1/responses` (new features land on Responses first); only `function` tools; `deferred:true` + `GET /v1/chat/deferred-completion/{id}`; `reasoning_content` field", "POST /v1/chat/completions", ["messages","reasoning_effort","response_format","deferred","prompt_cache_key","max_completion_tokens"], ["DOCUMENTED","LEGACY","LIVE_VERIFIED"], "`file` parts → 400 (use Responses); server tools → 422; Live Search params → 410"),46    side(True, "OpenAI-compatibility layer `POST /v1beta/openai/chat/completions` (Bearer key required; `extra_body.google.thinking_config`, `cached_content`; unknown params silently ignored); native `generateContent` itself is now labelled legacy vs Interactions", "POST /v1beta/openai/chat/completions", ["messages","reasoning_effort","response_format","extra_body.google"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "no Responses / Assistants / audio routes on the compat layer"),47    True, "OpenAI, xAI and Gemini all expose an OpenAI-shaped `chat/completions`; Anthropic has none. Only OpenAI's is a first-class, fully featured surface.", "docs/comparisons/responses-vs-chat-completions.md · docs/xai/chat-completions.md · docs/gemini/openai-compatibility.md")48row(S, "Anthropic-compatible Messages endpoint",49    NO,50    side(True, "the native surface", "POST /v1/messages", ["messages","system","max_tokens","tools"], ["DOCUMENTED","LIVE_VERIFIED"], ""),51    side(True, "`POST /v1/messages` accepting Anthropic shapes (`system`, `messages`, `tools[{name,description,input_schema}]`, `tool_choice {auto|any|tool}`, `thinking` blocks with empty `signature`) — **fully deprecated** by xAI ('migrate to Responses or gRPC'); Bearer auth, `anthropic-version` ignored; `/v1/complete` twin RETIRED (400)", "POST /v1/messages", ["messages","system","max_tokens","tools","tool_choice"], ["DOCUMENTED","DEPRECATED","LIVE_VERIFIED"], "`top_k` 400, `stop_sequences` 400 on reasoning models, `document` blocks 422, no count_tokens (404), no batches, `cache_control` ignored"),52    NO, True, "xAI is the only third party exposing the Anthropic Messages wire format, and is retiring it.", "docs/xai/messages-compat.md · parameters.json (xai POST /v1/messages)")53row(S, "Legacy completion (prompt-in / text-out) endpoint",54    side(True, "`gpt-3.5-turbo-instruct`, `davinci-002`, `babbage-002` only; shutdowns 2026-09-28", "POST /v1/completions", ["prompt","suffix","max_tokens"], ["DOCUMENTED","LEGACY","LIVE_VERIFIED"], ""),55    side(False, "documented as Legacy but every live call returns 400 'has been deprecated'", "POST /v1/complete", ["prompt","max_tokens_to_sample"], ["DOCUMENTED","LEGACY","DEPRECATED","FAILED_VERIFICATION"], "removed from Python SDK v1"),56    side(False, "`POST /v1/completions` (OpenAI shape) and `POST /v1/complete` (Anthropic shape) both answer 400 'Raw sampling is not supported for reasoning models' for every live model, incl. the non-reasoning grok-4.20", "POST /v1/completions", ["prompt","max_tokens"], ["DOCUMENTED","LEGACY","RETIRED"], "gRPC `Sample` service still lists raw sampling"),57    side(False, "PaLM-era `:generateText` / `:generateMessage` remain in the v1beta discovery document but return 404 / 501; only `models/aqa:generateAnswer` still answers", "POST /v1beta/models/{model}:generateText", [], ["DOCUMENTED","LEGACY","FAILED_VERIFICATION"], "`legacy-palm` family: 7 endpoints"),58    False, "Every provider still documents a prompt-completion route; only OpenAI's answers, and it shuts down 2026-09-28.", "docs/openai/completions-legacy.md · docs/anthropic/text-completions-legacy.md · docs/xai/legacy-completions.md · docs/gemini/legacy-palm-methods.md")59row(S, "System / developer prompt",60    side(True, "`instructions` (per request, not carried by `previous_response_id`) or `developer`/`system` role message items", "POST /v1/responses", ["instructions","input[](message).role"], ["DOCUMENTED","LIVE_VERIFIED"], "`instructions` participate in the cache prefix"),61    side(True, "top-level `system` (string or text blocks with `cache_control`/`citations`); mid-conversation `role:system` messages for tool changes/effort (beta)", "POST /v1/messages", ["system","system[].cache_control","messages[].output_config.effort"], ["DOCUMENTED","LIVE_VERIFIED"], "schema lists a `system` role but docs say use the top-level field"),62    side(True, "`instructions` (Responses) **or** a `system` / `developer` role message; Chat: `system` role; `/v1/messages`: `system` string or text blocks", XR, ["instructions","input[](message).role"], ["DOCUMENTED","LIVE_VERIFIED"], "`instructions` + `previous_response_id` → 400 (the previous system prompt is reused)"),63    side(True, "`systemInstruction` (Content, text parts only, role ignored) — not a turn; Interactions: `system_instruction` string (must be resent when chaining)", GC, ["systemInstruction"], ["DOCUMENTED","LIVE_VERIFIED"], "counted in `promptTokenCount`; cacheable inside `cachedContents`"),64    True, "All four keep the system prompt outside the turn list. OpenAI/xAI accept it either as a field or as a role item; Anthropic and Gemini only as a field.", "parameters.json (instructions / system / systemInstruction)")65row(S, "Message roles",66    side(True, "`user`, `assistant`, `system`, `developer` (+ `phase: commentary|final_answer` on assistant)", "POST /v1/responses", ["input[](message).role","input[](message).phase"], ["DOCUMENTED","LIVE_VERIFIED"], ""),67    side(True, "`user`, `assistant`; consecutive same-role turns are merged; ≤100,000 messages", "POST /v1/messages", ["messages[].role"], ["DOCUMENTED","LIVE_VERIFIED"], "`system` role reserved for beta mid-conversation blocks"),68    side(True, "`user`, `assistant`, `system`, `developer` (Responses); Chat adds `tool` (`tool_call_id`) and legacy `function`; no ordering constraint", XR, ["input[](message).role","messages[].role"], ["DOCUMENTED","LIVE_VERIFIED"], "`developer` accepted live on Chat although not in the spec"),69    side(True, "`user`, `model` only (omitted role = user); **last turn must be `user`** (400 'Requests ending with a model turn are not supported'); function results go in a `user` Content of `functionResponse` parts", GC, ["contents[].role"], ["DOCUMENTED","LIVE_VERIFIED"], "Interactions steps use `role: user|model` too"),70    True, "The assistant role is spelled `model` on Gemini; Anthropic enforces alternation by merging; Gemini enforces a trailing user turn; OpenAI/xAI accept any order.", "docs/anthropic/messages-api.md §1 · docs/gemini/generate-content.md")71row(S, "Assistant prefill (continue a partial assistant turn)",72    side(False, "no prefill semantics; an assistant item is history only", "POST /v1/responses", [], ["DOCUMENTED"], ""),73    side(True, "end `messages` with an `assistant` turn → model continues it. **Deprecated**: 400 on Claude 4.6+ / Fable / Mythos, incompatible with thinking and structured outputs", "POST /v1/messages", ["messages[].content[] (assistant prefill)"], ["DOCUMENTED","DEPRECATED","LIVE_VERIFIED"], "live: Haiku 4.5 OK, Sonnet 5 → 400"),74    side(False, "assistant history items / `assistant` role accepted, but no documented continuation semantics", XR, [], ["DOCUMENTED"], ""),75    side(False, "impossible: a request ending with a `model` turn is rejected (400)", GC, [], ["DOCUMENTED","LIVE_VERIFIED"], ""),76    False, "Only Anthropic ever offered prefill, and only its 4.5 models still honour it; Gemini rejects the pattern outright.", "docs/anthropic/messages-api.md · deprecations.json · docs/gemini/generate-content.md")77row(S, "Multi-turn conversation",78    side(True, "three modes: manual replay of `output[]` items, `previous_response_id` (server keeps chain), `conversation` (Conversations API)", "POST /v1/responses", ["previous_response_id","conversation","store"], ["DOCUMENTED","LIVE_VERIFIED"], "`previous_response_id` and `conversation` are mutually exclusive"),79    side(True, "manual replay only: resend full `messages[]` each call (incl. `thinking`/`tool_use`/`tool_result` blocks)", "POST /v1/messages", ["messages"], ["DOCUMENTED","LIVE_VERIFIED"], "server-side state exists only in Managed Agents sessions"),80    side(True, "manual replay **or** `previous_response_id` (server rehydrates the whole agentic trajectory incl. reasoning and tool outputs; follow-ups may change tools/model); Chat: replay incl. `reasoning_content`", XR, ["previous_response_id","store","input"], ["DOCUMENTED","LIVE_VERIFIED"], "no Conversations API; `x-grok-conv-id` / `prompt_cache_key` are cache-routing keys, not stored conversations"),81    side(True, "`generateContent`: manual replay of `contents[]` (echo `thoughtSignature` on Gemini 3 function calls); **Interactions**: `previous_interaction_id` chains stored interactions (`store:true` default; only history is carried — resend tools/system/config)", GC, ["contents","previous_interaction_id","store"], ["DOCUMENTED","LIVE_VERIFIED"], "chaining on an `in_progress` interaction → 400"),82    True, "Portable pattern = manual replay everywhere; OpenAI, xAI and Gemini (Interactions) add server-side chaining by id.", "docs/comparisons/state-management.md")83row(S, "Response storage, retrieval, deletion",84    side(True, "`store:true` default → `GET/DELETE /v1/responses/{id}`, `GET …/input_items`; 30-day retention", "GET /v1/responses/{response_id}", ["store","include"], ["DOCUMENTED","LIVE_VERIFIED"], "`store:false` → 404 on retrieve, reasoning returned as `encrypted_content`"),85    side(False, "no response store; nothing to retrieve after the HTTP response", "", [], ["DOCUMENTED"], "Batches results are retrievable 29 days"),86    side(True, "`store:true` default → `GET/DELETE /v1/responses/{id}`, `GET …/input_items` (limit 1–100, order, after); 30-day retention; ZDR teams cannot store", "GET /v1/responses/{response_id}", ["store"], ["DOCUMENTED","LIVE_VERIFIED","LIVE_DISCOVERED"], "LIVE_DISCOVERED: GET still 200 for a `store:false` id"),87    side(True, "Interactions: `store:true` default → `GET /v1beta/interactions/{id}` (full timeline incl. `user_input`), `DELETE`, `POST …/cancel`; retention 55 days paid (AI Studio 7/14/28/55), 1 day free; `store:false` → no `id`, stateless. `generateContent` stores nothing (per-request `store` logging flag LIVE_DISCOVERED)", "GET /v1beta/interactions/{id}", ["store"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "`GET /v1beta/interactions` (list) → 404"),88    True, "Three stateful-by-default surfaces (OpenAI Responses, xAI Responses, Gemini Interactions) vs Anthropic's stateless Messages.", "docs/openai/responses.md §1 · docs/xai/responses.md · docs/gemini/interactions-api.md")89row(S, "Background / deferred (async) execution",90    side(True, "`background:true` → `status:queued`, poll `GET`, `POST …/cancel`, resumable stream `?stream=true&starting_after=N`", "POST /v1/responses", ["background"], ["DOCUMENTED","LIVE_VERIFIED"], "not available over WebSocket; not in EU region"),91    side(False, "no per-request background mode; use Message Batches (≤24 h) or Managed Agents sessions", "POST /v1/messages/batches", [], ["DOCUMENTED"], ""),92    side(True, "Chat Completions only: `deferred:true` → `{request_id}`; `GET /v1/chat/deferred-completion/{request_id}` → 202 while pending, 200 when done (docs: retrievable once within 24 h; live: second GET also 200)", "GET /v1/chat/deferred-completion/{request_id}", ["deferred"], ["DOCUMENTED","LIVE_VERIFIED"], "Responses `background` → 400 'Argument not supported'"),93    side(True, "Interactions `background:true` (requires `store`) → `queued`/`in_progress`; poll `GET /v1beta/interactions/{id}` or resume the stream with `?stream=true&last_event_id=`; `POST …/cancel`; mandatory for Deep Research (≤60 min); `webhook_config` for completion callbacks", IX, ["background","stream","webhook_config"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "Veo/Batch use long-running `Operation`s instead"),94    True, "OpenAI, xAI (Chat only) and Gemini (Interactions) offer per-request async; Anthropic only batches.", "docs/openai/responses.md §5 · docs/xai/deferred-completions.md · docs/gemini/interactions-api.md")95row(S, "Token counting",96    side(True, "count input tokens of a Responses payload (free)", "POST /v1/responses/input_tokens", ["model","input","tools","instructions"], ["DOCUMENTED","LIVE_VERIFIED"], "supports images/files"),97    side(True, "count tokens of a Messages payload (free; separate RPM bucket 5k/10k/20k)", "POST /v1/messages/count_tokens", ["model","messages","system","tools","thinking","output_config.format"], ["DOCUMENTED","LIVE_VERIFIED"], "server tools other than advisor → 400; `mcp_servers` rejected"),98    side(True, "`POST /v1/tokenize-text {model, text}` → `token_ids[{token_id, string_token, token_bytes}]` (tokenizer, not a request counter); free", "POST /v1/tokenize-text", ["model","text"], ["DOCUMENTED","LIVE_VERIFIED"], "no per-request counter; `/v1/messages/count_tokens` → 404"),99    side(True, "`:countTokens` with `{contents}` or `{generateContentRequest:{model, contents, systemInstruction, tools, cachedContent, generationConfig}}` → `totalTokens`, `promptTokensDetails[]`, `cachedContentTokenCount`; free", "POST /v1beta/models/{model}:countTokens", ["contents","generateContentRequest"], ["DOCUMENTED","LIVE_VERIFIED"], "SDKs refuse `system_instruction`/`tools` here although REST accepts them"),100    True, "Free everywhere; xAI tokenises raw text only (no tools/images), the other three count a full request.", "docs/anthropic/token-counting.md · docs/openai/multimodal-input.md · docs/xai/index.md · docs/gemini/token-counting.md")101row(S, "Model listing / catalogue",102    side(True, "list/retrieve (`shutdown_date` field on deprecated ids); some aliases (e.g. `gpt-5.6`) 404 on GET but work on POST", "GET /v1/models", [], ["DOCUMENTED","LIVE_VERIFIED"], "136 ids live"),103    side(True, "list/retrieve with `capabilities` block (thinking, effort, structured_outputs, context_management…)", "GET /v1/models", ["limit","before_id","after_id"], ["DOCUMENTED","LIVE_VERIFIED"], "11 ids live; invite-only Mythos ids → 404"),104    side(True, "`GET /v1/models` (OpenAI shape, 12 ids) plus typed catalogues `GET /v1/language-models`, `/v1/image-generation-models`, `/v1/video-generation-models`, `/v1/embedding-models` with **live price ticks**, aliases, `input_modalities`, fingerprint; retired slugs redirect (`grok-3` → grok-4.3 object)", "GET /v1/language-models", [], ["DOCUMENTED","LIVE_VERIFIED"], "voice models absent from the catalogue; `/v1/embedding-models` → `{models: []}` for this team"),105    side(True, "`GET /v1beta/models` (58 ids: `inputTokenLimit`, `outputTokenLimit`, `supportedGenerationMethods`, `thinking`, `temperature`/`topP`/`topK` defaults, `version`) and `GET /v1beta/models/{model}`; `/v1/models` lists only 22 stable ids", "GET /v1beta/models", ["pageSize","pageToken"], ["DOCUMENTED","LIVE_VERIFIED"], "agents (deep-research, antigravity) appear as models; shut-down previews still listed"),106    True, "xAI publishes prices in the catalogue, Anthropic publishes capability flags, Gemini publishes token limits and generation methods, OpenAI publishes shutdown dates.", "sources/*/models-api-raw.json")107108# ============================================================ Structured output & sampling109S = "Structured output & sampling"110row(S, "Structured outputs (JSON Schema constrained)",111    side(True, "`text.format {type:json_schema, name, schema, strict, description}` (flat)", "POST /v1/responses", ["text.format","text.format(json_schema).strict"], ["DOCUMENTED","LIVE_VERIFIED"], "Chat: `response_format.json_schema{…}` wrapper; refusal → `refusal` content part"),112    side(True, "`output_config.format {type:json_schema, schema}` (GA, no beta header; legacy `output_format` → 400)", "POST /v1/messages", ["output_config.format","output_config.format.schema"], ["DOCUMENTED","LIVE_VERIFIED"], "grammar compiled once (24 h cache), first call slower; `stop_reason: refusal` possible"),113    side(True, "`text.format {type:json_schema, name, schema, strict, description}` (Responses) / `response_format {type:json_schema, json_schema:{name, strict, schema}}` (Chat); Draft 2020-12 preferred; `additionalProperties` defaults false; formats date/time/email/uuid/uri enforced; `pattern` ECMA subset", XR, ["text.format","response_format"], ["DOCUMENTED","LIVE_VERIFIED"], "`strict` accepted and ignored (always strict); all Grok 4 models"),114    side(True, "`generationConfig.responseMimeType: application/json` + `responseJsonSchema` (JSON Schema) or legacy `responseSchema` (OpenAPI subset, `propertyOrdering`); new canonical `responseFormat.text {mimeType: APPLICATION_JSON, schema}`; enum mode `text/x.enum`; XML/YAML mime types accepted; Interactions `response_format {type:text, mime_type, schema}`", GC, ["generationConfig.responseMimeType","generationConfig.responseJsonSchema","generationConfig.responseSchema","generationConfig.responseFormat"], ["DOCUMENTED","LIVE_VERIFIED"], "values are syntactically valid but not semantically validated; `maxOutputTokens` can truncate the JSON; SO + tools = Gemini 3 preview"),115    True, "Same task on all four. Schema dialects differ: OpenAI/xAI require `additionalProperties:false` semantics (xAI defaults it), Anthropic rejects numeric/string constraints, Gemini ignores unsupported keywords silently and offers an OpenAPI-style alternative.", "docs/openai/structured-outputs.md · docs/anthropic/structured-outputs.md · docs/xai/structured-outputs.md · docs/gemini/structured-outputs.md")116row(S, "Strict tool arguments",117    side(True, "`tools[type=function].strict:true` (Responses omits → tries strict then falls back)", "POST /v1/responses", ["tools[type=function].strict"], ["DOCUMENTED","LIVE_VERIFIED"], ""),118    side(True, "`tools[].strict:true` grammar-constrained `tool_use.input`; ≤20 strict tools/request", "POST /v1/messages", ["tools[].strict"], ["DOCUMENTED","LIVE_VERIFIED"], "not on toolsets / mcp_toolset / programmatic callers"),119    side(True, "tool `parameters` are **always** strictly enforced ('strict flag implicitly true'); explicit `strict` accepted and ignored", XR, ["tools[].strict"], ["DOCUMENTED","LIVE_VERIFIED"], ""),120    side(True, "`toolConfig.functionCallingConfig.mode: VALIDATED` (schema-validated constrained decoding; default when built-ins or structured output are combined) or `ANY` (forced, constrained)", GC, ["toolConfig.functionCallingConfig.mode"], ["DOCUMENTED","LIVE_VERIFIED"], "no per-tool flag; `ANY` may reject very large/deep schemas"),121    True, "Per-tool flag on OpenAI/Anthropic, always-on on xAI, a request-level mode on Gemini.", "tools.json · docs/tools/gemini/function-calling.md")122row(S, "JSON mode (valid JSON, no schema)",123    side(True, "`text.format {type:json_object}`; prompt must mention JSON (400 otherwise)", "POST /v1/responses", ["text.format(json_object)"], ["DOCUMENTED","LIVE_VERIFIED"], "legacy"),124    NO,125    side(True, "`text.format {type:json_object}` / `response_format {type:json_object}`", XR, ["text.format(json_object)"], ["DOCUMENTED","LIVE_VERIFIED"], ""),126    side(True, "`responseMimeType: application/json` without a schema", GC, ["generationConfig.responseMimeType"], ["DOCUMENTED","LIVE_VERIFIED"], ""),127    True, "Anthropic only offers schema-constrained output.", "docs/openai/structured-outputs.md · docs/gemini/structured-outputs.md")128row(S, "Output verbosity control",129    side(True, "`text.verbosity: low|medium|high`", "POST /v1/responses", ["text.verbosity"], ["DOCUMENTED","LIVE_VERIFIED"], ""),130    side(False, "no direct knob; `output_config.effort` shapes length indirectly", "", [], ["DOCUMENTED"], ""),131    side(False, "no verbosity parameter (`text.format` only)", "", [], ["DOCUMENTED"], ""),132    side(False, "no verbosity parameter; `thinkingLevel` and `maxOutputTokens` only", "", [], ["DOCUMENTED"], ""),133    False, "OpenAI-only knob.", "parameters.json")134row(S, "Sampling parameters (temperature / top_p / top_k)",135    side(True, "`temperature` 0–2, `top_p`; rejected by reasoning models", "POST /v1/responses", ["temperature","top_p"], ["DOCUMENTED","LIVE_VERIFIED"], "no `top_k`"),136    side(True, "`temperature` 0–1, `top_p`, `top_k` — **DEPRECATED**: 400 when non-default on Claude 4.7+ / Fable / Mythos; Python SDK v1 removed the kwargs", "POST /v1/messages", ["temperature","top_p","top_k"], ["DOCUMENTED","DEPRECATED","LIVE_VERIFIED"], ""),137    side(True, "`temperature` 0–2, `top_p`, plus xAI-specific `top_k` (≥1) and `min_p` (0–1); accepted on reasoning models (echo 0.7/0.95); Chat `seed` → `system_fingerprint`", XR, ["temperature","top_p","top_k","min_p","seed"], ["DOCUMENTED","LIVE_VERIFIED"], "`presence_penalty`/`frequency_penalty`/`stop` → 400 on reasoning models"),138    side(True, "`generationConfig.temperature` 0–2 (default 1.0), `topP` (0.95), `topK` (64), `seed`; **DEPRECATED** guidance since 2026-07-21: keep defaults on Gemini 3.x (temperature < 1 can cause looping); `presencePenalty`/`frequencyPenalty` → 400 'not enabled'", GC, ["generationConfig.temperature","generationConfig.topP","generationConfig.topK","generationConfig.seed"], ["DOCUMENTED","DEPRECATED","LIVE_VERIFIED"], "`candidateCount` > 1 → 400 on 3.x"),139    True, "Sampling knobs are shrinking on all frontier lines: rejected by OpenAI reasoning models and Claude 4.7+, deprecated-by-guidance on Gemini 3.x, still fully accepted on Grok.", "deprecations.json (anthropic, gemini api_features) · parameters.json")140row(S, "Stop sequences",141    side(True, "Chat Completions `stop` (≤4); **not** a Responses parameter", "POST /v1/chat/completions", ["stop"], ["DOCUMENTED"], ""),142    side(True, "`stop_sequences[]` → `stop_reason: stop_sequence` + `stop_sequence`", "POST /v1/messages", ["stop_sequences"], ["DOCUMENTED","LIVE_VERIFIED"], ""),143    side(True, "Chat `stop` (≤4) and `/v1/messages` `stop_sequences` — **400 on reasoning models**; not on Responses", "POST /v1/chat/completions", ["stop","stop_sequences"], ["DOCUMENTED","LIVE_VERIFIED"], "usable only on grok-4.20-0309-non-reasoning"),144    side(True, "`generationConfig.stopSequences[]` (≤5; 6 → 400); Interactions `generation_config.stop_sequences`", GC, ["generationConfig.stopSequences"], ["DOCUMENTED","LIVE_VERIFIED"], ""),145    True, "Absent from both Responses APIs; Gemini allows 5, the others 4.", "parameters.json")146row(S, "Log probabilities",147    side(True, "`top_logprobs` + `include: [\"message.output_text.logprobs\"]`", "POST /v1/responses", ["top_logprobs","include"], ["DOCUMENTED"], ""),148    NO,149    side(False, "`logprobs`/`top_logprobs` (0–8) accepted but **silently ignored** on grok-4.20 and newer (DEPRECATED); `include: message.output_text.logprobs` ignored", "POST /v1/chat/completions", ["logprobs","top_logprobs"], ["DOCUMENTED","DEPRECATED","LIVE_VERIFIED"], ""),150    side(False, "`responseLogprobs` / `logprobs` (0–20) in the schema but `400 Logprobs is not enabled for this model` on every current model", GC, ["generationConfig.responseLogprobs","generationConfig.logprobs"], ["DOCUMENTED","FAILED_VERIFICATION"], ""),151    False, "Only OpenAI still returns logprobs; xAI and Gemini keep the parameters as dead compatibility fields.", "parameters.json")152row(S, "Refusal / safety signalling in-band",153    side(True, "`output[].content[] {type: refusal}` (structured outputs) / `status: incomplete` + `incomplete_details.reason: content_filter`; HTTP 403 `misalignment_policy_violation`, `cyber_policy`", "POST /v1/responses", [], ["DOCUMENTED"], ""),154    side(True, "HTTP 200 with `stop_reason: refusal` + `stop_details {category, explanation}`; beta `fallbacks` re-runs on another model", "POST /v1/messages", ["fallbacks","fallback_credit_token"], ["DOCUMENTED","BETA"], "categories: cyber, bio, frontier_llm, reasoning_extraction, general_harms"),155    side(True, "Chat `message.refusal` field; `respect_moderation` flag on image/video results; usage-guideline violations are **billed** (+ $0.05 fee when caught pre-generation on Responses); no error code catalogue for refusals", "POST /v1/chat/completions", [], ["DOCUMENTED"], ""),156    side(True, "HTTP 200 with **no candidates** + `promptFeedback.blockReason` (SAFETY|OTHER|BLOCKLIST|PROHIBITED_CONTENT|IMAGE_SAFETY) for prompt blocks; `candidates[].finishReason` SAFETY|RECITATION|SPII|IMAGE_SAFETY|… (21 values) + `safetyRatings[]` for output blocks; thresholds via `safetySettings[]`", GC, ["safetySettings","candidates[].finishReason","promptFeedback.blockReason"], ["DOCUMENTED","LIVE_VERIFIED"], "Interactions mirror finishReason as snake_case error codes"),157    True, "All four signal in-band with different shapes; only Gemini lets the caller tune thresholds; only xAI charges for violating requests.", "docs/anthropic/stop-reasons.md · docs/openai/safety.md · docs/gemini/safety.md · docs/xai/pricing.md §5")158row(S, "Server-side model fallback on refusal",159    NO,160    side(True, "`fallbacks` parameter (+ `fallback_credit_token` billing credit)", "POST /v1/messages", ["fallbacks","fallback_credit_token"], ["DOCUMENTED","BETA"], "beta `server-side-fallback-2026-07-01`, `fallback-credit-2026-07-01`"),161    NO, NO, False, "Anthropic-only.", "generated/fragments/headers/anthropic-beta-headers.json")162row(S, "Configurable safety thresholds",163    side(True, "inline `moderation {model, policy}` on Responses/Chat (policy selection, not thresholds)", "POST /v1/responses", ["moderation"], ["DOCUMENTED"], ""),164    NO, NO,165    side(True, "`safetySettings[] {category: HARM_CATEGORY_HARASSMENT|HATE_SPEECH|SEXUALLY_EXPLICIT|DANGEROUS_CONTENT|JAILBREAK (CIVIC_INTEGRITY deprecated → `enableEnhancedCivicAnswers`), threshold: OFF|BLOCK_NONE|BLOCK_ONLY_HIGH|BLOCK_MEDIUM_AND_ABOVE|BLOCK_LOW_AND_ABOVE}`; default Off on 2.5/3.x; `safetyRatings[]` returned when a threshold is set", GC, ["safetySettings"], ["DOCUMENTED","LIVE_VERIFIED"], "Interactions: custom safety settings not supported"),166    False, "Only Gemini exposes per-category blocking thresholds; OpenAI selects a moderation policy.", "docs/gemini/safety.md · docs/openai/moderation.md")167168# ============================================================ Tools — client side169S = "Tools — client side"170row(S, "Function / custom tools (you execute)",171    side(True, "`tools[type=function] {name, description, parameters, strict, output_schema, async, defer_loading, allowed_callers}` → `function_call` item → you reply `function_call_output {call_id, output}`", "POST /v1/responses", ["tools[type=function]","input[](function_call_output)"], ["DOCUMENTED","LIVE_VERIFIED"], "38 compatible models listed"),172    side(True, "`tools[] {name, description, input_schema, strict, input_examples, cache_control, defer_loading, allowed_callers}` → `tool_use` block → you reply user message of `tool_result {tool_use_id, content, is_error}`", "POST /v1/messages", ["tools","messages[].content[] (tool_result)"], ["DOCUMENTED","LIVE_VERIFIED"], "13 compatible models"),173    side(True, "Responses `tools[type=function] {name, description, parameters}` → `function_call {call_id: call-…, name, arguments}` → `function_call_output`; Chat `tools[{type:function, function:{…}}]` → `message.tool_calls[]` → `{role: tool, tool_call_id}`; ≤350 tools; parameters always strict; a client-side call ends the agentic request (fresh `max_turns` budget on the follow-up)", XR, ["tools[type=function]","input[](function_call_output)","parallel_tool_calls"], ["DOCUMENTED","LIVE_VERIFIED"], "all 7 Grok text models; also inside the voice session and `/v1/messages`"),174    side(True, "`tools[].functionDeclarations[] {name, description, parameters | parametersJsonSchema, response | responseJsonSchema, behavior}` → `parts[].functionCall {name, args, id}` (+ mandatory `thoughtSignature` on Gemini 3) → you reply a `user` Content of `functionResponse {name, id, response, parts[] (multimodal)}`; max 512 declarations", GC, ["tools[].functionDeclarations","contents[].parts[].functionResponse","toolConfig.functionCallingConfig"], ["DOCUMENTED","LIVE_VERIFIED"], "Interactions: `{type: function, name, description, parameters}` + `function_call`/`function_result` steps; Live: `toolCall`/`toolResponse` messages"),175    True, "Same loop on all four. Arguments are a JSON **string** on OpenAI/xAI and an **object** on Anthropic (`input`) and Gemini (`args`); results are a top-level item (OpenAI/xAI), a leading `tool_result` block in a user turn (Anthropic) or `functionResponse` parts in a user Content (Gemini). Gemini 3 additionally requires echoing the `thoughtSignature` of the first call of each step (400 / `MISSING_THOUGHT_SIGNATURE`).",176    "docs/comparisons/tool-execution.md · docs/tools/xai/function-calling.md · docs/tools/gemini/function-calling.md")177row(S, "Free-form / grammar-constrained custom tools",178    side(True, "`tools[type=custom] {format: {type:text} | {type:grammar, syntax: lark|regex, definition}}`", "POST /v1/responses", ["tools[type=custom].format"], ["DOCUMENTED","LIVE_VERIFIED"], ""),179    NO,180    side(False, "no `custom` tool type in the deserializer (422 'unknown variant'); no grammar mode", XR, [], ["DOCUMENTED"], ""),181    NO, False, "OpenAI-only.", "tools.json · docs/xai/structured-outputs.md")182row(S, "Tool choice",183    side(True, "`tool_choice`: `auto|none|required` string, `{type:function,name}`, hosted `{type:web_search|mcp|shell|apply_patch|…}`, `{type:allowed_tools, mode, tools[]}`", "POST /v1/responses", ["tool_choice","tool_choice(allowed_tools)"], ["DOCUMENTED","LIVE_VERIFIED"], ""),184    side(True, "`tool_choice {type: auto|any|tool|none, name?, disable_parallel_tool_use?}`", "POST /v1/messages", ["tool_choice.type","tool_choice.disable_parallel_tool_use"], ["DOCUMENTED","LIVE_VERIFIED"], "`any`/`tool` → 400 on Fable 5.1 / Mythos 5.1 and with manual thinking"),185    side(True, "`tool_choice`: `auto|none|required` or `{type:function, name}` (Responses) / `{type:function, function:{name}}` (Chat); `/v1/messages`: `{type: auto|any|tool}` (`disable_parallel_tool_use` → 400); no `allowed_tools`, no forcing of server tools", XR, ["tool_choice","tool_choice.type","tool_choice.name"], ["DOCUMENTED","LIVE_VERIFIED"], ""),186    side(True, "`toolConfig.functionCallingConfig {mode: AUTO|ANY|NONE|VALIDATED, allowedFunctionNames[]}` (ANY + names = forced subset); Interactions `generation_config.tool_choice: auto|any|none|validated` or `{allowed_tools:{mode, tools[]}}`; built-in tools cannot be forced", GC, ["toolConfig.functionCallingConfig.mode","toolConfig.functionCallingConfig.allowedFunctionNames"], ["DOCUMENTED","LIVE_VERIFIED"], "Live `setup.toolConfig` → close 1007"),187    True, "`required` ≈ `any` ≈ `ANY`; only OpenAI and Gemini (`allowedFunctionNames` / Interactions `allowed_tools`) can restrict to a subset; only OpenAI can force a hosted tool.", "parameters.json")188row(S, "Parallel tool calls",189    side(True, "`parallel_tool_calls` (default true); hosted tools never batched with functions", "POST /v1/responses", ["parallel_tool_calls"], ["DOCUMENTED","LIVE_VERIFIED"], ""),190    side(True, "default on (Claude 4+); `tool_choice.disable_parallel_tool_use:true` to force ≤1; all results in one user message", "POST /v1/messages", ["tool_choice.disable_parallel_tool_use"], ["DOCUMENTED","LIVE_VERIFIED"], ""),191    side(True, "`parallel_tool_calls` (default true; `false` = at most one call) on Chat and Responses", XR, ["parallel_tool_calls"], ["DOCUMENTED","LIVE_VERIFIED"], "`/v1/messages` `disable_parallel_tool_use` → 400"),192    side(True, "several `functionCall` parts in one `model` Content; answer **all** of them in one `user` Content (interleaving FC1,FR1,FC2 → 400); only the first call carries the thought signature; no on/off switch", GC, ["contents[].parts[].functionCall"], ["DOCUMENTED","LIVE_VERIFIED"], "`compositional_function_calling` chains calls across turns"),193    True, "Default-on everywhere; Gemini has no switch to disable it.", "docs/openai/tool-loop.md · docs/tools/anthropic/tool-use-loop.md · docs/tools/gemini/function-calling.md")194row(S, "Tool namespaces",195    side(True, "`tools[type=namespace] {name, description, tools[]}`; calls carry `namespace`", "POST /v1/responses", ["tools[type=namespace]"], ["DOCUMENTED","LIVE_VERIFIED"], ""),196    side(False, "no namespaces; toolsets (`computer_toolset_20260801`, `mcp_toolset`) group Anthropic-defined members only", "", [], ["DOCUMENTED"], ""),197    NO, NO, False, "OpenAI-only.", "tools.json")198row(S, "Deferred tool loading / tool search",199    side(True, "`tools[type=tool_search] {execution: server|client}` + `defer_loading:true` on function/custom/mcp; `tool_search_call`/`tool_search_output` items; `additional_tools` input item", "POST /v1/responses", ["tools[type=tool_search]","tools[type=function].defer_loading"], ["DOCUMENTED","LIVE_VERIFIED"], "gpt-5.4+ only; gpt-5.4-nano lacks it"),200    side(True, "`tool_search_tool_regex_20251119` / `tool_search_tool_bm25_20251119` (server) + `defer_loading:true` (≤10,000 tools); `tool_reference` blocks expanded server-side; client-side search via `tool_reference` in `tool_result`", "POST /v1/messages", ["tools[].defer_loading","tools[].type"], ["DOCUMENTED","LIVE_VERIFIED"], "GA no header; not cacheable together with `cache_control`"),201    side(True, "`tools[type=tool_search] {execution}` + `defer_loading:true` on function/mcp tools → `tool_search_call {arguments:{query, limit}}` / `tool_search_output {tools[]}` — **alpha**: 403 'only available for alpha users'", XR, ["tools[type=tool_search]","tools[].defer_loading"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "listed as compatible with all 7 text models"),202    NO,203    True, "OpenAI-shaped on xAI (gated), two algorithms on Anthropic; Gemini has no deferred loading (best practice: keep 10–20 active declarations).", "docs/tools/openai/tool-search.md · docs/tools/anthropic/tool-search.md · tools.json (xai tool_search)")204row(S, "Programmatic tool calling (model writes code that calls tools)",205    side(True, "`tools[type=programmatic_tool_calling]` + `allowed_callers:[\"programmatic\"]`; `program`/`program_output` items; nested calls `caller.type: program`; JavaScript in isolated V8", "POST /v1/responses", ["tools[type=programmatic_tool_calling]","tools[type=function].allowed_callers"], ["DOCUMENTED","UNVERIFIED"], "no compatible model list in tools.json"),206    side(True, "`code_execution_20260120+` + `allowed_callers:[\"code_execution_20260120\"]`; Python `await tool({...})` in the sandbox; `caller {type, tool_id}`; reply requires top-level `container`", "POST /v1/messages", ["tools[].allowed_callers","container"], ["DOCUMENTED","LIVE_VERIFIED"], "not Haiku 4.5 (400)"),207    NO,208    side(False, "not a generateContent feature; nearest: compositional function calling (chained calls across turns) and code execution over `functionResponse` data; Antigravity agents script tools inside their sandbox", GC, [], ["DOCUMENTED"], ""),209    True, "OpenAI and Anthropic only (JS vs Python).", "docs/tools/anthropic/programmatic-tool-calling.md · docs/openai/tool-loop.md §6 · docs/tools/gemini/function-calling.md")210row(S, "Async tools (model continues while a tool runs)",211    side(True, "`tools[type=function].async:true` + wait tool / task handles (GPT-6 Astra+)", "POST /v1/responses", ["tools[type=function].async","input[](function_call).async"], ["DOCUMENTED"], ""),212    NO, NO,213    side(True, "Live API only: `functionDeclarations[].behavior: NON_BLOCKING` (default on gemini-3.8-live) + `toolResponse.functionResponses[].scheduling: INTERRUPT|WHEN_IDLE|SILENT`, `willContinue`; `generateContent` → 400", "WSS BidiGenerateContent", ["setup.tools[].functionDeclarations[].behavior","toolResponse.functionResponses[].scheduling"], ["DOCUMENTED","LIVE_VERIFIED"], "gemini-3.8-live-extended-thinking: async only"),214    True, "Different scopes: OpenAI in text Responses, Gemini in the voice Live session.", "parameters.json · docs/gemini/live-api.md")215row(S, "Shell execution",216    side(True, "`tools[type=shell]` hosted (`environment.type: container_auto|container_reference`) **or** local (`type: local` — you run commands); legacy `local_shell` → 400", "POST /v1/responses", ["tools[type=shell].environment"], ["DOCUMENTED","LIVE_VERIFIED"], "gpt-5.2+, codex, gpt-6-astra"),217    side(True, "`bash_20250124` client tool (you run a persistent bash) **or** server `bash_code_execution` sub-tool of `code_execution_20250825+`", "POST /v1/messages", ["tools[].type"], ["DOCUMENTED","LIVE_VERIFIED"], "all current models"),218    side(True, "`tools[type=shell] {environment:{type: local, skills:[{name, description, path}]}}` → `shell_call` → you reply `shell_call_output {stdout, stderr, outcome}`; **local only** (no hosted container variant); hosted Python via `code_interpreter`", XR, ["tools[type=shell].environment","input[](shell_call_output)"], ["DOCUMENTED","LIVE_VERIFIED"], "accepted live, not invoked; Grok Build CLI runs its own sandbox"),219    side(False, "no shell tool on `generateContent`; the **Antigravity** managed agent runs bash/python/node `code_execution` and file tools inside its Linux sandbox (Interactions API only, PREVIEW)", IX, ["agent_config(antigravity)"], ["DOCUMENTED","PREVIEW"], "`gemini-3.1-pro-preview-customtools` is tuned for bash-style custom tools you define yourself"),220    True, "OpenAI has hosted + local, Anthropic hosted (code execution) + local (bash), xAI local only, Gemini only inside its managed agent.", "docs/tools/openai/shell.md · docs/tools/anthropic/bash.md · docs/xai/skills-api.md · docs/gemini/interactions-api.md")221row(S, "File editing tool",222    side(True, "`tools[type=apply_patch]` → `apply_patch_call {operation: create_file|update_file|delete_file, diff}`; you reply `apply_patch_call_output`", "POST /v1/responses", ["tools[type=apply_patch]"], ["DOCUMENTED","LIVE_VERIFIED"], "undocumented SSE events `response.apply_patch_call_operation_diff.*` (LIVE_DISCOVERED)"),223    side(True, "`text_editor_20250728` (`name: str_replace_based_edit_tool`, `max_characters`) → commands view/str_replace/create/insert; server variant `text_editor_code_execution`", "POST /v1/messages", ["tools[].max_characters"], ["DOCUMENTED","LIVE_VERIFIED"], "older 20250429/20250124 → 400 on current models"),224    NO,225    side(False, "no editor tool on `generateContent`; Antigravity 09-2026 built-ins `write_to_file`, `replace_file_content`, `view_file`, `list_dir`, `find_by_name`, `grep_search` (agent sandbox only)", IX, [], ["DOCUMENTED","PREVIEW"], "05-2026 tool names deprecated → 2026-10-05"),226    True, "Diff-based (OpenAI) vs command-based (Anthropic); Gemini only inside Antigravity; none on xAI.", "docs/tools/openai/apply-patch.md · docs/tools/anthropic/text-editor.md · docs/gemini/interactions-api.md")227row(S, "Memory tool (client-side persistent memory)",228    side(False, "none in Responses; Agents API sessions persist items but no memory tool", "", [], ["DOCUMENTED"], ""),229    side(True, "`memory_20250818` client tool (you store files under `/memories`)", "POST /v1/messages", ["tools[].type"], ["DOCUMENTED","LIVE_VERIFIED"], "Managed Agents add server-side memory stores"),230    NO, NO, False, "Anthropic-only.", "docs/tools/anthropic/memory.md")231row(S, "Computer use",232    side(True, "`tools[type=computer]` (current, gpt-5.4+/gpt-6) or `computer_use_preview` (+ `computer-use-preview` model, RETIRED); `computer_call {action|actions[], pending_safety_checks}` → `computer_call_output {computer_screenshot, acknowledged_safety_checks}`", "POST /v1/responses", ["tools[type=computer]","tools[type=computer_use_preview]"], ["DOCUMENTED","PREVIEW","ACCOUNT_RESTRICTED"], "`computer` UNVERIFIED live"),233    side(True, "`computer_toolset_20260801` (GA, no header, Fable/Mythos/Opus 5/Sonnet 5/Opus 4.8) or beta `computer_20251124` (`computer-use-2025-11-24`) / `computer_20250124`; member tools screenshot/zoom/click…; batch actions", "POST /v1/messages", ["tools[].display_width_px","tools[].enable_zoom","tools[].configs"], ["DOCUMENTED","LIVE_VERIFIED","BETA"], "~4,500-token toolset definition"),234    NO,235    side(True, "`tools[].computerUse {environment: ENVIRONMENT_BROWSER|MOBILE|DESKTOP, excludedPredefinedFunctions[], enablePromptInjectionDetection, disabledSafetyPolicies[]}` → predefined `functionCall`s (`click`, `type`, `scroll`, `navigate`, `open_app`…; coordinates 0–999) → you reply `functionResponse` with a screenshot; `safety_decision: require_confirmation` → `safety_acknowledgement`; Interactions `{type: computer_use, environment: browser}`", GC, ["tools[].computerUse","tools[].computerUse.environment"], ["DOCUMENTED","PREVIEW","ACCOUNT_RESTRICTED"], "gemini-3.8-flash recommended; legacy `gemini-2.5-computer-use-preview-10-2025` browser-only; no free tier"),236    True, "Three client-executed screenshot loops (OpenAI, Anthropic, Gemini); none on xAI. Gemini normalises coordinates to 0–999 and adds mobile/desktop environments.", "docs/tools/openai/computer-use.md · docs/tools/anthropic/computer-use.md · docs/tools/gemini/computer-use.md")237row(S, "Browser use toolset",238    NO,239    side(True, "`browser_toolset_20260801` (client toolset, `browser_state` result blocks)", "POST /v1/messages", ["tools[].type"], ["DOCUMENTED","LIVE_VERIFIED"], "≈6,600-token definition; 7 models"),240    NO,241    side(False, "browser is an `environment` of the computer-use tool, not a separate toolset", GC, [], ["DOCUMENTED"], ""),242    False, "Anthropic-only as a dedicated toolset.", "tools.json")243244# ============================================================ Tools — server side / hosted245S = "Tools — server side / hosted"246row(S, "Web search",247    side(True, "`tools[type=web_search] {search_context_size, user_location, filters.allowed_domains, external_web_access, return_token_budget, search_content_types}`; `web_search_call` item + `url_citation` annotations; $10/1k calls", "POST /v1/responses", ["tools[type=web_search]"], ["DOCUMENTED","LIVE_VERIFIED"], "Chat: search models + `web_search_options`; preview variants LEGACY"),248    side(True, "`web_search_20260318|20260209|20250305 {max_uses, allowed_domains XOR blocked_domains, user_location}`; `server_tool_use` + `web_search_tool_result` blocks, `web_search_result_location` citations; $10/1k searches; dynamic filtering via code execution (20260209+)", "POST /v1/messages", ["tools[].max_uses","tools[].allowed_domains","tools[].blocked_domains","tools[].user_location"], ["DOCUMENTED","LIVE_VERIFIED"], "13 models; `pause_turn` after 10 iterations"),249    side(True, "`tools[type=web_search] {allowed_domains ≤5 XOR excluded_domains ≤5, enable_image_understanding, enable_image_search}` → `web_search_call {action: search|open_page|find_in_page}` + `url_citation` annotations + inline `[[N]](url)` (disable via `include: no_inline_citations`); **$5/1k successful calls**; `search_context_size` → 400", XR, ["tools[type=web_search]","tools[].allowed_domains","tools[].excluded_domains","tools[].enable_image_search"], ["DOCUMENTED","LIVE_VERIFIED"], "Responses only; Chat Live Search → 410; usage `server_side_tool_usage_details.web_search_calls`"),250    side(True, "`tools[{googleSearch: {timeRangeFilter?, searchTypes?{webSearch, imageSearch}}}]` → `groundingMetadata {webSearchQueries, searchEntryPoint (must be displayed — ToS), groundingChunks[].web, groundingSupports}`; Gemini 3.x **5,000 free queries/month then $14/1k queries**, 2.5: 1,500 RPD free then $35/1k grounded prompts; legacy `googleSearchRetrieval` (dynamic retrieval) DEPRECATED", GC, ["tools[].googleSearch","tools[].googleSearch.searchTypes","tools[].googleSearchRetrieval"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "429 `limit: 0` on this free-tier key; Interactions `{type: google_search}`; the only tool allowed with functions in the Live API"),251    True, "Same task on all four with four price models ($10 / $10 / $5 per 1k calls; Gemini per query with a free monthly quota). Domain filters exist on OpenAI, Anthropic and xAI; Gemini offers time-range and image-search filters instead.", "docs/tools/openai/web-search.md · docs/tools/anthropic/web-search.md · docs/tools/xai/web-search.md · docs/tools/gemini/google-search-grounding.md")252row(S, "Social / vertical search (X posts, Google Maps)",253    NO, NO,254    side(True, "`tools[type=x_search] {allowed_x_handles ≤10 XOR excluded_x_handles, from_date, to_date, enable_image_understanding, enable_video_understanding}` → live item `custom_tool_call` named `x_keyword_search`/`x_semantic_search` (docs: `x_search_call`) + `url_citation` to x.com posts; $5/1k calls until **2026-09-21**, then $5/1k posts + $10/1k profiles fetched", XR, ["tools[type=x_search]","tools[].allowed_x_handles","tools[].from_date","tools[].to_date"], ["DOCUMENTED","LIVE_VERIFIED","LIVE_DISCOVERED"], "also in the voice session"),255    side(True, "`tools[{googleMaps: {enableWidget?}}]` + `toolConfig.retrievalConfig {latLng, languageCode}` → `groundingChunks[].maps {uri, title, placeId, text, placeAnswerSources}`; GA; text only; not in Live; Gemini 3.x $14/1k queries after 5,000/month (tools table: $25/1k grounded prompts, 1,500 RPD free)", GC, ["tools[].googleMaps","toolConfig.retrievalConfig.latLng"], ["DOCUMENTED","GA","LIVE_VERIFIED"], "pricing inconsistency flagged (`DOCUMENTATION_INCOMPLETE`)"),256    False, "Provider-specific data sources; no equivalent on OpenAI/Anthropic.", "docs/tools/xai/x-search.md · docs/tools/gemini/google-maps-grounding.md")257row(S, "Web fetch / URL context (retrieve specific URLs)",258    side(False, "no dedicated fetch tool; web search may open pages; `input_file.file_url` fetches PDFs only", "", [], ["DOCUMENTED"], ""),259    side(True, "`web_fetch_20260318|20260309|20260209|20250910 {max_uses, allowed_domains, citations, max_content_tokens, use_cache, url_sources}`; only URLs already in context; free (tokens only)", "POST /v1/messages", ["tools[].max_content_tokens","tools[].url_sources","tools[].use_cache"], ["DOCUMENTED","LIVE_VERIFIED"], "`url_not_in_prior_context` error"),260    side(False, "no fetch tool; `web_search_call.action.type: open_page|find_in_page` shows the search tool opening pages; `input_file.file_url` attaches a remote file (attachment search)", XR, [], ["DOCUMENTED"], ""),261    side(True, "`tools[{urlContext: {}}]` (no options): ≤20 public URLs per request, ≤34 MB each (HTML/JSON/text/CSV/RTF/PNG/JPEG/PDF; no YouTube/Workspace/paywalls) → `urlContextMetadata.urlMetadata[] {retrievedUrl, urlRetrievalStatus}`; free tool, content billed as input (`toolUsePromptTokenCount`)", GC, ["tools[].urlContext"], ["DOCUMENTED","GA","LIVE_VERIFIED"], "Interactions `{type: url_context}`; combinable with search/code exec/functions"),262    True, "Anthropic and Gemini offer a fetch tool; Anthropic restricts to URLs already in context, Gemini to any public URL you name.", "docs/tools/anthropic/web-fetch.md · docs/tools/gemini/url-context.md")263row(S, "File search / managed RAG",264    side(True, "Vector Stores API (create, files, file_batches, search) + `tools[type=file_search] {vector_store_ids, max_num_results, filters, ranking_options}`; $2.50/1k calls + $0.10/GB/day", "POST /v1/vector_stores · POST /v1/responses", ["tools[type=file_search]"], ["DOCUMENTED","LIVE_VERIFIED"], "16 endpoints"),265    side(False, "no vector store; patterns: `search_result` blocks (your RAG, citable), `document` blocks from Files API, code execution over uploaded files", "POST /v1/messages", ["messages[].content[] {type:'search_result'}","messages[].content[] {type:'document'}"], ["DOCUMENTED","LIVE_VERIFIED"], ""),266    side(True, "**Collections API** (`/v1/collections`, documents added from Files ids, `index_configuration.model_name: grok-embedding-small`, `chunk_configuration`, `POST /v1/documents/search {query, retrieval_mode: hybrid|semantic|keyword}`) + `tools[type=file_search|collections_search] {vector_store_ids (= collection ids), max_num_results, filters, ranking_options}` → `file_search_call {queries, results[{file_id, filename, score, text}]}`; $2.50/1k calls + $0.10/GiB/day; implicit `attachment_search` over `input_file` parts $10/1k", XR, ["tools[type=file_search]","tools[].vector_store_ids"], ["DOCUMENTED","LIVE_VERIFIED","ACCOUNT_RESTRICTED"], "13 collection endpoints; documented on management-api.x.ai but working on api.x.ai (LIVE_DISCOVERED); search 404 while indexing"),267    side(True, "**File Search stores** (`/v1beta/fileSearchStores`, `:uploadToFileSearchStore` resumable ≤100 MB, `:importFile`, documents, `chunkingConfig`, `customMetadata[]`; embedding model fixed at creation) + `tools[{fileSearch: {fileSearchStoreNames[], metadataFilter (AIP-160), topK}}]` → `groundingChunks[].retrievedContext {title, text, pageNumber, customMetadata}`; indexing $0.15/1M tokens once, storage + queries free; store quota 1 GB (free) … 1 TB (Tier 3)", GC, ["tools[].fileSearch","tools[].fileSearch.fileSearchStoreNames","tools[].fileSearch.metadataFilter"], ["DOCUMENTED","PREVIEW","LIVE_VERIFIED"], "12 endpoints; not combinable with Search/URL context; not in Live"),268    True, "Three hosted stores (OpenAI vector stores, xAI collections, Gemini file-search stores) with different billing (per call / per call + storage / per indexed token); Anthropic supplies citation plumbing instead of storage.", "docs/openai/vector-stores.md · docs/anthropic/citations.md · docs/xai/collections.md · docs/tools/gemini/file-search.md")269row(S, "Code execution (sandboxed Python)",270    side(True, "`tools[type=code_interpreter] {container: auto|cntr_id, file_ids, memory_limit 1g–64g, network_policy}`; `code_interpreter_call {code, outputs}`; $0.03–$1.92 per 20-min session (per-minute since 2026-06-02)", "POST /v1/responses", ["tools[type=code_interpreter].container"], ["DOCUMENTED","LIVE_VERIFIED"], "36 models"),271    side(True, "`code_execution_20260521|20260120|20250825` (bash + text editor sub-tools, Python 3.11, 5 GiB RAM, no internet); `container {id, skills}` reuse (30-day state); 1,550 free container-hours/org/month then $0.05/h; free with web_search/fetch 20260209+", "POST /v1/messages", ["tools[].type","container"], ["DOCUMENTED","LIVE_VERIFIED"], "13 models; usage counter `code_execution_requests` missing live"),272    side(True, "`tools[type=code_interpreter]` (alias `code_execution`) → `code_interpreter_call {code, outputs[{type: logs, logs: <JSON string stdout/stderr/exit_code>} | {type: image, url}]}` (outputs only with `include: code_interpreter_call.outputs`); Python + NumPy/Pandas/Matplotlib/SciPy, no network; **$5/1k calls** + tokens; no container object", XR, ["tools[type=code_interpreter]","include"], ["DOCUMENTED","LIVE_VERIFIED"], "all 7 text models; gRPC rejects the `code_interpreter` alias"),273    side(True, "`tools[{codeExecution: {}}]` → parts `executableCode {language: PYTHON, code}` + `codeExecutionResult {outcome, output}` (+ `inlineData` PNG for matplotlib); Python ≥3.10, fixed library set, 30 s per run, ≤5 retries, no pip/network; **no fee** — code and results billed as output then input tokens", GC, ["tools[].codeExecution"], ["DOCUMENTED","LIVE_VERIFIED"], "12 models; Interactions `{type: code_execution}`; not in Live"),274    True, "Four sandboxes, four price models: per container-session (OpenAI), per container-hour with a free tier (Anthropic), per call (xAI), tokens only (Gemini). Only OpenAI/Anthropic expose a reusable container object.", "docs/tools/openai/code-interpreter.md · docs/tools/anthropic/code-execution.md · docs/tools/xai/code-execution.md · docs/tools/gemini/code-execution.md")275row(S, "Container management API",276    side(True, "CRUD containers and container files, download outputs", "GET/POST/DELETE /v1/containers[/{id}/files]", [], ["DOCUMENTED","LIVE_VERIFIED"], "9 endpoints; auto containers expire 20 min after last activity"),277    side(False, "no container endpoints; container id returned on the message (`container.id`, `expires_at`) and reused via the `container` param; outputs via Files API", "POST /v1/messages · GET /v1/files/{id}/content", ["container"], ["DOCUMENTED","LIVE_VERIFIED"], ""),278    side(False, "no container object; `container` param accepted for OpenAI compatibility, not needed", XR, [], ["DOCUMENTED"], ""),279    side(True, "**Environments API** for Interactions agents (`POST/GET/DELETE /v1beta/environments`, files `GET …/files/{path}`, `PUT /upload/v1beta/environments/{env}/files/{path}`; sources repository/GCS/inline; network allowlist; idle 15 min, deleted after 7 days) — not usable by `codeExecution`", "POST /v1beta/environments", ["environment","sources","network"], ["DOCUMENTED","BETA","PREVIEW","LIVE_VERIFIED"], "7 endpoints; sandbox compute unbilled during preview"),280    True, "OpenAI containers and Gemini environments are both first-class resources but serve different tools (code interpreter vs managed agents).", "docs/openai/containers.md · docs/tools/anthropic/code-execution.md · docs/gemini/interactions-api.md")281row(S, "Image generation as a tool / modality inside a text call",282    side(True, "`tools[type=image_generation] {model, quality, size, background, input_fidelity, partial_images, moderation}`; `image_generation_call` item; streaming partials", "POST /v1/responses", ["tools[type=image_generation]"], ["DOCUMENTED","LIVE_VERIFIED"], "31 models"),283    NO,284    side(True, "`tools[type=image_generation]` → `image_generation_call` billed at Imagine per-image rates (no call fee); accepted live, not invoked", XR, ["tools[type=image_generation]"], ["DOCUMENTED","LIVE_VERIFIED"], "all 7 text models listed"),285    side(True, "not a tool: `generationConfig.responseModalities: [TEXT, IMAGE]` + `imageConfig {aspectRatio, imageSize 512|1K|2K|4K}` on image models (`gemini-3.1-flash-image`, `-lite-image`, `gemini-3-pro-image`); Interactions `response_format {type: image}`", GC, ["generationConfig.responseModalities","generationConfig.imageConfig"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "no free tier (`limit: 0` here); text models ignore IMAGE modality"),286    True, "Tool item on OpenAI/xAI, output modality on Gemini; Claude outputs text only.", "tools.json · docs/gemini/image-generation.md · docs/xai/images.md")287row(S, "Remote MCP servers",288    side(True, "`tools[type=mcp] {server_label, server_url|connector_id|tunnel_id, authorization, headers, allowed_tools, require_approval (default always), defer_loading, allowed_callers}`; `mcp_list_tools`, `mcp_call`, `mcp_approval_request/response` items; no beta header", "POST /v1/responses", ["tools[type=mcp]"], ["DOCUMENTED","LIVE_VERIFIED"], "42 models; also Realtime and Agents API"),289    side(True, "`mcp_servers[] {type:url, url, name, authorization_token}` (≤20) + `tools[type=mcp_toolset] {mcp_server_name, default_config, configs}`; `mcp_tool_use`/`mcp_tool_result` blocks; **beta header `mcp-client-2025-11-20`**", "POST /v1/messages", ["mcp_servers","tools[].mcp_server_name","tools[].default_config","tools[].configs"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "no approvals in Messages; the error text advertises `mcp-client-2026-09-15` which is rejected (inconsistency)"),290    side(True, "`tools[type=mcp] {server_url, server_label (required), server_description, allowed_tools[], authorization, headers}` → `mcp_call {server_label, name, arguments, output, error}`; tokens only; **no approval round-trip** (`require_approval` silently accepted); also inside the voice session", XR, ["tools[type=mcp]","tools[].server_url","tools[].server_label","tools[].allowed_tools"], ["DOCUMENTED","LIVE_VERIFIED"], "LIVE_VERIFIED with DeepWiki; `connector_id` unsupported"),291    side(True, "server-side `tools[].mcpServers[] {name, streamableHttpTransport {url, headers, timeout}}` in the discovery schema (UNVERIFIED, no guide) and Interactions `{type: mcp_server, name, url, headers, allowed_tools}` (documented; not on Gemini 3 per the overview); SDK-side MCP (`mcpToTool()`, Python `ClientSession` in `tools`) runs the calls in **your** process (BETA)", IX, ["tools[].mcpServers","tools[](mcp_server)"], ["DOCUMENTED","DOCUMENTATION_INCOMPLETE","UNVERIFIED"], "Streamable HTTP only; server names must not contain '-'"),292    True, "OpenAI GA with approvals; xAI GA without approvals; Anthropic beta without approvals; Gemini server-side MCP is documented but unverified — its verified path is SDK-side execution.", "docs/tools/openai/mcp-and-connectors.md · docs/tools/anthropic/mcp-connector.md · docs/tools/xai/mcp.md · docs/tools/gemini/mcp.md")293row(S, "Built-in SaaS connectors",294    side(True, "`connector_id`: dropbox, gmail, googlecalendar, googledrive, microsoftteams, outlookcalendar, outlookemail, sharepoint (+ OAuth `authorization`) — **deprecated** for models after 2025-09-01", "POST /v1/responses", ["tools[type=mcp].connector_id"], ["DOCUMENTED","DEPRECATED"], ""),295    NO,296    side(False, "`connector_id` documented as unsupported", XR, [], ["DOCUMENTED"], ""),297    NO, False, "OpenAI-only (deprecated).", "docs/tools/openai/mcp-and-connectors.md")298row(S, "Private-network MCP (tunnels) / agent credentials",299    side(True, "Secure MCP Tunnel: outbound `tunnel-client`, `tools[type=mcp].tunnel_id` (`tunnel_[a-z0-9]{32}`)", "POST /v1/responses", ["tools[type=mcp].tunnel_id"], ["DOCUMENTED"], ""),300    side(True, "MCP tunnels API (`/v1/tunnels`, certificates, tokens) + tunnel agent; header `mcp-tunnels-2026-06-22`; WIF bearer with `workspace:manage_tunnels`", "GET/POST /v1/tunnels", [], ["DOCUMENTED","BETA","PREVIEW","ACCOUNT_RESTRICTED"], "10 endpoints; older `/v1/organizations/tunnels` deprecated"),301    NO,302    side(True, "no tunnels; **Credentials API** (`/v1beta/credentials`: `bearer_token`, `oauth2`, `environment_variable` with `injection_location` and `trusted_domains`; secrets write-only) referenced from environment network allowlists", "POST /v1beta/credentials", [], ["DOCUMENTED","BETA","PREVIEW"], "5 endpoints, not tested"),303    False, "Tunnels on OpenAI/Anthropic; Gemini solves the secret-injection half with credentials; nothing on xAI.", "endpoints.json (managed-agents tunnels, gemini credentials) · docs/tools/openai/mcp-and-connectors.md")304row(S, "Skills (packaged instructions + files)",305    side(True, "Skills API (`POST /v1/skills`, versions, content zip) referenced from `tools[type=shell].environment.skills[]`, containers, Agents sessions; ≤500 files, ≤25 MB", "POST /v1/skills", ["tools[type=shell].environment.skills"], ["DOCUMENTED","LIVE_VERIFIED","FAILED_VERIFICATION"], "version-by-number endpoints returned 404 live; lists returned empty"),306    side(True, "Skills API (`/v1/skills`, versions, content; GA no header) + Anthropic skills (pptx, xlsx, docx, pdf); used via `container.skills[]` with code execution and on Managed Agents", "POST /v1/skills", ["container.skills"], ["DOCUMENTED","LIVE_VERIFIED"], "9 endpoints all LIVE_VERIFIED"),307    side(True, "Skills API `GET/POST /v1/skills`, `GET/DELETE /v1/skills/{id}`, `GET …/content` (zip; `SKILL.md` frontmatter `name`, `description`, `when-to-use`, `paths`, `allowed-tools`) — **all 404 for this team** (ACCOUNT_RESTRICTED); reach inference only via `shell.environment.skills[]`; Grok Build CLI also loads skills locally", "POST /v1/skills", ["tools[type=shell].environment.skills"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "5 endpoints, OpenAPI only"),308    side(False, "no Skills API; custom Interactions agents mount `.agents/skills/<name>/SKILL.md` from their environment sources", IX, [], ["DOCUMENTED","PREVIEW"], ""),309    True, "Same `SKILL.md` bundle model on OpenAI, Anthropic and xAI (xAI gated); Gemini uses environment files.", "docs/openai/skills-api.md · docs/anthropic/skills-api.md · docs/xai/skills-api.md · docs/gemini/interactions-api.md")310row(S, "Advisor (consult a stronger model mid-response)",311    NO,312    side(True, "`advisor_20260301 {model, max_tokens, caching}` server tool, beta `advisor-tool-2026-03-01`", "POST /v1/messages", ["tools[].model","tools[].max_tokens","tools[].caching"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "11 models"),313    NO, NO, False, "Anthropic-only.", "tools.json")314row(S, "Citations / grounding metadata",315    side(True, "`output_text.annotations[]`: `url_citation`, `file_citation`, `container_file_citation`, `file_path` (produced by web/file search, code interpreter)", "POST /v1/responses", ["include"], ["DOCUMENTED","LIVE_VERIFIED"], "no citations for plain documents"),316    side(True, "`citations {enabled:true}` on `document`/`search_result` blocks → `char_location`, `page_location`, `content_block_location`, `search_result_location`, `web_search_result_location`; `citations_delta` when streaming", "POST /v1/messages", ["messages[].content[].citations","tools[].citations"], ["DOCUMENTED","LIVE_VERIFIED"], "all-or-nothing across documents"),317    side(True, "`output_text.annotations[] {type: url_citation, url, start_index, end_index, title}` (live indices 0/0, title = URL) + inline markdown `[[N]](url)`; collections citations `collections://<cid>/files/<fid>`; `include: web_search_call.action.sources`", XR, ["include"], ["DOCUMENTED","LIVE_VERIFIED"], "`usage.num_sources_used`"),318    side(True, "`candidates[].groundingMetadata {groundingChunks[] (web|maps|retrievedContext), groundingSupports[] {segment, groundingChunkIndices, confidenceScores}, webSearchQueries, searchEntryPoint}`, `urlContextMetadata`, `citationMetadata` (recitation); Interactions `text_annotation_delta`", GC, ["candidates[].groundingMetadata","candidates[].urlContextMetadata"], ["DOCUMENTED","LIVE_VERIFIED"], "streaming chunks carry only new grounding chunks — accumulate"),319    True, "Anthropic cites any document you pass; OpenAI, xAI and Gemini cite only their own tool results (Gemini with segment-level supports and confidence scores).", "docs/anthropic/citations.md · docs/tools/gemini/google-search-grounding.md")320321# ============================================================ Multimodal input & media APIs322S = "Multimodal input & media APIs"323row(S, "Image input",324    side(True, "`input_image {image_url|file_id, detail: low|high|auto|original}`; patch/tile token formulas; ≤1,500 images, ≤512 MB", "POST /v1/responses", ["input[](message).content[](input_image)"], ["DOCUMENTED","LIVE_VERIFIED"], ""),325    side(True, "`image {source: base64|url|file, transformations}`; ≤100 (200k models) / 600 (1M models) images; 10 MB each; tokens = ⌈w/28⌉×⌈h/28⌉ (2576 px hi-res on 4.7+)", "POST /v1/messages", ["messages[].content[] {type:'image'}"], ["DOCUMENTED","LIVE_VERIFIED"], ""),326    side(True, "Responses `input_image {image_url (https or data URL), detail}` (≥512 px; `file_id` variant → 400); Chat `image_url {url, detail}`; image tokens priced as text input (`image_input` = `input` price); all Grok 4 text models accept images", XR, ["input[](message).content[](input_image)","messages[].content[](image_url)"], ["DOCUMENTED","LIVE_VERIFIED"], "`usage.prompt_tokens_details.image_tokens`"),327    side(True, "`parts[].inlineData {mimeType, data}` or `fileData {fileUri}` (Files API); `mediaResolution` LOW/MEDIUM/HIGH globally or per part (Gemini 3 adds ULTRA_HIGH, 2,240 tokens); docs 280/560/1,120/2,240 tokens by level (observed 256/529/1,089/2,209)", GC, ["contents[].parts[].inlineData","contents[].parts[].fileData","generationConfig.mediaResolution"], ["DOCUMENTED","LIVE_VERIFIED"], "`promptTokensDetails[] {modality: IMAGE}`"),328    True, "Universal. Token accounting differs on every provider (patches/tiles, 28-px grid, text-price tokens, resolution levels).", "docs/openai/multimodal-input.md · docs/anthropic/vision-and-documents.md · docs/xai/chat-completions.md · docs/gemini/multimodal-input.md")329row(S, "PDF / document input",330    side(True, "`input_file {file_id|file_url|file_data+filename, detail}`; text + page images in context; <50 MB combined; office formats via file_id", "POST /v1/responses", ["input[](message).content[](input_file)"], ["DOCUMENTED"], ""),331    side(True, "`document {source: base64 pdf|url|file|text|content, title, context, citations}`; ≤600 pages/request, 32 MB body", "POST /v1/messages", ["messages[].content[] {type:'document'}"], ["DOCUMENTED","LIVE_VERIFIED"], "citable"),332    side(True, "Responses `input_file {file_id|file_url|file_data}` → routed through the implicit **attachment search** tool ($10/1k calls); Chat `file` parts → 400; `/v1/messages` `document` → 422", XR, ["input[](message).content[](input_file)"], ["DOCUMENTED","LIVE_VERIFIED"], "Files API 50 MB (spec) / 512 MB (guide)"),333    side(True, "`inlineData {mimeType: application/pdf}` or `fileData` (Files API, 2 GB); PDF pages billed at the image token rate (`DOCUMENT` modality, 560 tokens/page in countTokens vs `IMAGE 520` observed in generateContent); `pdf_input` true on all 3.x text models", GC, ["contents[].parts[].inlineData","contents[].parts[].fileData"], ["DOCUMENTED","LIVE_VERIFIED"], "no citations for documents; URL context handles remote PDFs"),334    True, "Universal; only Anthropic makes documents citable, only xAI bills a per-call fee for attachments.", "docs/anthropic/vision-and-documents.md · docs/xai/files.md · docs/gemini/multimodal-input.md")335row(S, "Audio / video input (understanding)",336    side(True, "Chat Completions `input_audio {data, format}` on `gpt-audio-1.5`, `gpt-4o-audio-preview`; Responses `input_audio` part in schema but UNVERIFIED; no video input", "POST /v1/chat/completions", ["messages[](user).content[](input_audio)"], ["DOCUMENTED","LIVE_DISCOVERED"], ""),337    NO,338    side(False, "no audio/video parts on text models (audio only in the voice session and STT; `grok-imagine-video` accepts video/audio as generation inputs; `view_x_video` sub-tool understands X videos)", "", [], ["DOCUMENTED"], ""),339    side(True, "native: `inlineData`/`fileData` audio (WAV/MP3/AIFF/AAC/OGG/FLAC; ≈25–32 tokens/s) and video (≤1 fps frames + audio; `videoMetadata {startOffset, endOffset, fps}`; YouTube URLs via `fileData`) on every 3.x text model; `gemini-embedding-2` embeds audio/video too", GC, ["contents[].parts[].inlineData","contents[].parts[].videoMetadata"], ["DOCUMENTED","LIVE_VERIFIED"], "`audio_input` price rows on 2.5/3.1-lite/3-flash; 3.5+ single price"),340    True, "Gemini is the only provider with native audio **and** video understanding in the text API; OpenAI has audio-in on dedicated chat models.", "docs/openai/multimodal-input.md §4 · docs/gemini/multimodal-input.md")341row(S, "Text-to-speech",342    side(True, "`POST /v1/audio/speech` (`gpt-4o-mini-tts`, `tts-1`, `tts-1-hd`; SSE `speech.audio.delta`) and Chat `modalities:[text,audio]`", "POST /v1/audio/speech", ["model","input","voice","instructions"], ["DOCUMENTED","LIVE_VERIFIED"], "custom voices ACCOUNT_RESTRICTED"),343    NO,344    side(True, "`POST /v1/tts {text ≤60,000 chars, voice_id, language (required), output_format {codec mp3|wav|pcm|mulaw|alaw, sample_rate, bit_rate}, speed, with_timestamps}` + `wss://api.x.ai/v1/tts` streaming (`text.delta` → `audio.delta`); 28 built-in voices (`GET /v1/tts/voices`) + custom voices (`/v1/custom-voices`, Enterprise); **$15 / 1M characters**", "POST /v1/tts", ["text","voice_id","language","output_format"], ["DOCUMENTED","LIVE_VERIFIED"], "17 voice endpoints; voice models absent from `GET /v1/models`"),345    side(True, "`generateContent` on TTS models (`gemini-3.1-flash-tts-preview`, `gemini-2.5-flash|pro-preview-tts`) with `responseModalities: [AUDIO]` + `speechConfig.voiceConfig.prebuiltVoiceConfig.voiceName` (30 voices) or `multiSpeakerVoiceConfig` (≤2 speakers); raw PCM 24 kHz out; $1 text in / $20 audio out per 1M (≈ $0.03/min); free tier (10 req/day observed)", GC, ["generationConfig.responseModalities","generationConfig.speechConfig"], ["DOCUMENTED","PREVIEW","LIVE_VERIFIED"], "streaming TTS on 3.1 only; multi-speaker may return `finishReason: OTHER`"),346    True, "Dedicated endpoint (OpenAI, xAI) vs a generation modality (Gemini); none on Anthropic.", "docs/openai/audio.md · docs/xai/voice.md · docs/gemini/speech-generation.md")347row(S, "Speech-to-text / transcription",348    side(True, "`POST /v1/audio/transcriptions` (`gpt-transcribe`, `gpt-4o-transcribe(-diarize)`, `whisper-1`; streaming `transcript.text.delta`), `POST /v1/audio/translations` (whisper-1)", "POST /v1/audio/transcriptions", ["model","file","response_format","stream"], ["DOCUMENTED","LIVE_VERIFIED"], "whisper-1 & gpt-4o-transcribe shutdown 2027-02-26"),349    NO,350    side(True, "`POST /v1/stt` (multipart `file` ≤500 MB or `url`; `language`, `diarize`, `keyterm`, `vad_threshold`, `model: grok-voice-transcribe-2.0|1.0`) **$0.10/h**; `wss://api.x.ai/v1/stt` streaming (binary frames, `interim_results`, `endpointing`, `smart_turn` → `transcript.partial/done`) **$0.20/h**", "POST /v1/stt", ["file","url","language","diarize","model"], ["DOCUMENTED","LIVE_VERIFIED"], "25 languages; default model contradicts between release notes (1.0) and model page (2.0)"),351    side(True, "`gemini-3.5-transcribe` via `generateContent` + `generationConfig.audioTranscriptionConfig {languageCodes, customVocabulary, mode VERBATIM|SMART, diarization, wordTimestamp}` → `parts[].audioTranscription {text, speakerLabel, words[]}` (LIVE_DISCOVERED shape); ≤1 h audio; ≈ $0.005/min blended; `gemini-3.5-transcribe-live` over the Live WebSocket (10-min sessions); `gemini-3.5-live-translate-preview` speech-to-speech translation", GC, ["generationConfig.audioTranscriptionConfig"], ["DOCUMENTED","LIVE_VERIFIED"], "free tier available"),352    True, "OpenAI/xAI dedicated endpoints (per minute / per hour); Gemini a dedicated model behind the generic endpoint; none on Anthropic.", "docs/openai/audio.md · docs/xai/voice.md · docs/gemini/transcription.md")353row(S, "Realtime speech-to-speech (WebSocket / WebRTC / SIP)",354    side(True, "Realtime API GA: WebSocket `wss://api.openai.com/v1/realtime?model=`, WebRTC `POST /v1/realtime/calls`, SIP, ephemeral `POST /v1/realtime/client_secrets`; transcription & translation sessions; 60-min sessions", "WS /v1/realtime", ["session.update","response.create"], ["DOCUMENTED","LIVE_VERIFIED"], "legacy `/v1/realtime/sessions` → 404"),355    NO,356    side(True, "`wss://api.x.ai/v1/realtime?model=grok-voice-latest` (= `grok-voice-think-fast-2.0`) with the **OpenAI Realtime event vocabulary** (`session.update`, `input_audio_buffer.*`, `conversation.item.create`, `response.create` → `response.output_audio.delta`, `response.done`; 39 server / 9 client events); tools in-session (`function`, `web_search`, `x_search`, `file_search`, `mcp`); `reasoning.effort high|none`; ephemeral `POST /v1/realtime/client_secrets` (≤3600 s); SIP via `/v2/phone-numbers`, `/v1/realtime/calls/{id}/refer|hangup`, webhook `realtime.call.incoming`; **$0.08/min** + $0.004 per text item; 120-min sessions; concurrent sessions 10–200 by tier", "WS wss://api.x.ai/v1/realtime", ["session.update","conversation.item.create","response.create"], ["DOCUMENTED","LIVE_VERIFIED"], "text turn LIVE_VERIFIED; audio UNVERIFIED; `ping` undocumented"),357    side(True, "**Live API** `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent` (`setup` → `setupComplete`; `clientContent`/`realtimeInput {audio|video|text|activityStart|activityEnd}`/`toolResponse` → `serverContent {modelTurn, turnComplete, interrupted, inputTranscription, outputTranscription}`, `toolCall`, `goAway`, `sessionResumptionUpdate`); models `gemini-3.8-live` (native audio, interleaved thinking, GA 2026-09-15), `-extended-thinking`, `gemini-3.1-flash-live-preview`, 2.5 native audio; ephemeral tokens `POST /v1beta/auth_tokens` on the `…Constrained` method; 16 kHz PCM in / 24 kHz out; ≈10-min connections, 15-min audio sessions (unlimited with `contextWindowCompression`), resumption handles 2 h; audio $3 in / $12 out per 1M (≈ $0.005 / $0.018 per min); free tier", "WSS BidiGenerateContent", ["setup","realtimeInput","toolResponse","setup.sessionResumption","setup.contextWindowCompression"], ["DOCUMENTED","PREVIEW","LIVE_VERIFIED"], "32 message types recorded; `responseModalities: [TEXT]` → close 1007; only googleSearch + functions as tools"),358    True, "Three voice stacks: xAI copies OpenAI's Realtime protocol (so client code ports almost verbatim), Gemini's Live API is a distinct message family; Anthropic has none. Only OpenAI and xAI offer WebRTC/SIP.", "docs/openai/realtime.md · docs/xai/voice.md · docs/gemini/live-api.md · docs/gemini/live-events.md")359row(S, "Full-duplex voice with backend delegation (Live) / voice agents",360    side(True, "Live API: `POST /v1/live/sessions` (WebRTC), `WS /v1/live/sessions`, fork/attach/SIP; `gpt-live-1` $0.05/min; delegation to Responses or client", "POST /v1/live/sessions", ["session.delegation","session.store"], ["DOCUMENTED","LIVE_DISCOVERED"], ""),361    NO,362    side(False, "no separate delegation product; the realtime session itself runs server tools (web/x/file search, MCP) with `reasoning.effort`", "WS wss://api.x.ai/v1/realtime", [], ["DOCUMENTED"], ""),363    side(False, "no delegation layer; `gemini-3.8-live-extended-thinking` runs background reasoning and speaks fillers (`interactionStatus: IN_PROGRESS`); `proactivity.proactiveAudio` always on for 3.8", "WSS BidiGenerateContent", [], ["DOCUMENTED"], ""),364    False, "OpenAI-only as a product; xAI and Gemini fold agentic behaviour into the voice session itself.", "docs/openai/live.md · docs/xai/voice.md · docs/gemini/live-api.md")365row(S, "Image generation API",366    side(True, "`POST /v1/images/generations`, `/edits` (gpt-image-2, gpt-image-2.5-flare/sunburst; DALL·E RETIRED, gpt-image-1.x DEPRECATED); streaming partials; arbitrary sizes ≤4K", "POST /v1/images/generations", ["prompt","size","quality","background","output_format","stream"], ["DOCUMENTED","LIVE_VERIFIED"], "`/variations` RETIRED (404)"),367    NO,368    side(True, "`POST /v1/images/generations {model, prompt, n 1–10, response_format url|b64_json, aspect_ratio (incl. 21:9, 5:2, auto), resolution 1k|1.5k|2k, quality low|medium|auto, storage_options}` and `POST /v1/images/edits` (**JSON only**: `image {url|file_id}` or `images[]` 2–5); `grok-imagine-image` $0.02, `grok-imagine-image-2.0` $0.04–$0.08, `grok-imagine-image-quality` $0.05 (DEPRECATED → 2026-11-02); sync ~5–10 s; always JPEG", "POST /v1/images/generations", ["prompt","n","aspect_ratio","resolution","quality","response_format"], ["DOCUMENTED","LIVE_VERIFIED"], "no `size`/`mask`/`seed`; `grok-2-image` RETIRED; not on us.api.x.ai"),369    side(True, "`generateContent` on image models with `responseModalities` + `imageConfig {aspectRatio (14 ratios), imageSize 512|1K|2K|4K}`; editing = pass the image as input and iterate; SynthID watermark; `gemini-3.1-flash-image` $0.045–$0.151, `-lite-image` $0.034, `gemini-3-pro-image` $0.134/$0.24; `gemini-2.5-flash-image` DEPRECATED → 2026-10-02; Imagen (`:predict`) RETIRED 2026-08-17; OpenAI-compat `POST /v1beta/openai/images/generations` subset", GC, ["generationConfig.responseModalities","generationConfig.imageConfig.aspectRatio","generationConfig.imageConfig.imageSize"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "no free tier (`limit: 0`); batch 50 %"),370    True, "OpenAI and xAI have dedicated image endpoints (token-priced vs per-image); Gemini generates images through the text endpoint; Claude produces no images.", "docs/openai/images.md · docs/xai/images.md · docs/gemini/image-generation.md")371row(S, "Video generation API",372    side(True, "`/v1/videos` (Sora 2) — **DEPRECATED, shutdown 2026-09-24**; $0.10–$0.70/s", "POST /v1/videos", ["prompt","seconds","size"], ["DOCUMENTED","DEPRECATED","LIVE_VERIFIED"], ""),373    NO,374    side(True, "`POST /v1/videos/generations {model, prompt, duration 1–15, aspect_ratio, resolution 480p|720p|1080p, generate_audio, image, reference_images[], reference_audios[] (1.5), last_frame (1.5)}` → `{request_id}`; `GET /v1/videos/{request_id}` 202 pending → 200 `{status: done, video:{url}}`; `POST /v1/videos/edits`, `/extensions`; `grok-imagine-video` **$0.05/s**, `grok-imagine-video-1.5` **$0.08/s** (1080p, reference-to-video)", "POST /v1/videos/generations", ["prompt","duration","aspect_ratio","resolution","image"], ["DOCUMENTED","LIVE_VERIFIED"], "4 endpoints; also via Batch (URLs expire 1 h)"),375    side(True, "Veo 3.1: `POST /v1beta/models/veo-3.1-*:predictLongRunning {instances[{prompt, image, lastFrame, referenceImages[], video}], parameters {aspectRatio, resolution 720p|1080p|4k, durationSeconds 4|6|8, personGeneration, negativePrompt, seed}}` → `Operation`; poll `GET /v1beta/{name}`; download `files/{id}:download?alt=media`; native audio; $0.40/$0.60 (Veo 3.1), $0.10–$0.30 (Fast), $0.05/$0.08 (Lite) per second; `gemini-omni-1.1-flash` video-out model via Interactions (≈ $0.10/s); OpenAI-compat `POST /v1beta/openai/videos`", "POST /v1beta/models/{model}:predictLongRunning", ["instances[].prompt","parameters.resolution","parameters.durationSeconds"], ["DOCUMENTED","PREVIEW"], "Veo 2.0/3.0 RETIRED 2026-06-30; no free tier; 400 on this key"),376    True, "Async polling everywhere; OpenAI's is shutting down, xAI's is the cheapest per second, Gemini's the only one with 4K.", "docs/openai/video.md · docs/xai/videos.md · docs/gemini/video-generation.md")377row(S, "Music generation",378    NO, NO, NO,379    side(True, "`lyria-3.5` (GA, **$0.08/song**), `lyria-3-clip-preview` ($0.04 / 30-s clip), `lyria-3-pro-preview` via `generateContent` (MP3) or Interactions `response_format {type: audio}` (WAV); **Lyria RealTime** WebSocket `…BidiGenerateMusic` (`weightedPrompts`, `musicGenerationConfig {bpm, density, brightness, scale…}`, `playbackControl`) → 48 kHz stereo PCM chunks (experimental, unpriced)", GC, ["contents[].parts[].text","musicGenerationConfig","playbackControl"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "no free tier for Lyria 3.x; RealTime LIVE_VERIFIED"),380    False, "Gemini-only.", "docs/gemini/music-generation.md")381row(S, "Embeddings",382    side(True, "`text-embedding-3-small` ($0.02/M), `-3-large` ($0.13/M), `ada-002`; `dimensions`, `encoding_format`; 8,192 tokens/input, 2,048 inputs", "POST /v1/embeddings", ["input","model","dimensions","encoding_format"], ["DOCUMENTED","LIVE_VERIFIED"], ""),383    NO,384    side(False, "`POST /v1/embeddings {model, input, encoding_format, dimensions}` documented (OpenAPI) but `grok-embedding-small` → 404 'does not exist or your team does not have access', `GET /v1/embedding-models` → `{models: []}`; no published price; used internally to index Collections", "POST /v1/embeddings", ["input","model","dimensions"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "gRPC `Embedder.Embed` exists"),385    side(True, "`POST /v1beta/models/gemini-embedding-2:embedContent {content, outputDimensionality 128–3072, taskType (001 only), embedContentConfig}` and `:batchEmbedContents {requests[]}`; **multimodal** (text, ≤6 images, ≤180 s audio, ≤120 s video, PDF ≤6 pages → one vector); $0.20 text / $0.45 image / $6.50 audio / $12 video per 1M, batch 50 %; free tier; `gemini-embedding-001` DEPRECATED → 2028-05-14; OpenAI-compat `/v1beta/openai/embeddings`", "POST /v1beta/models/{model}:embedContent", ["content","outputDimensionality","taskType"], ["DOCUMENTED","LIVE_VERIFIED"], "`:asyncBatchEmbedContent` ACCOUNT_RESTRICTED (400 FAILED_PRECONDITION)"),386    True, "OpenAI (text) and Gemini (multimodal) ship embeddings; xAI's endpoint is documented but inaccessible; Anthropic has none.", "docs/openai/embeddings.md · docs/gemini/embeddings.md · docs/models/xai-models.md")387row(S, "Moderation endpoint",388    side(True, "`POST /v1/moderations` (`omni-moderation-latest`, text+image, free) and inline `moderation {model, policy}` on Responses/Chat", "POST /v1/moderations", ["input","model","moderation"], ["DOCUMENTED","LIVE_VERIFIED"], "`text-moderation-*` RETIRED"),389    NO, NO,390    side(False, "no moderation route among the 125 Gemini endpoints; `safetySettings` thresholds and `safetyRatings` instead", "", [], ["DOCUMENTED"], ""),391    False, "OpenAI-only.", "docs/openai/moderation.md · docs/gemini/safety.md")392row(S, "Content provenance",393    side(True, "`POST /v1/content_provenance_checks` (C2PA verification)", "POST /v1/content_provenance_checks", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),394    side(False, "generated media from code execution carry C2PA credentials; no verification endpoint", "", [], ["DOCUMENTED"], ""),395    side(False, "no provenance endpoint; `respect_moderation` flag on image/video results", "", [], ["DOCUMENTED"], ""),396    side(False, "SynthID watermark on all generated images/video/audio (Nano Banana 2 Lite also C2PA); no verification endpoint on the Developer API", "", [], ["DOCUMENTED"], ""),397    False, "Only OpenAI exposes a check endpoint.", "endpoints.json · docs/gemini/image-generation.md")398399# ============================================================ Files & batch400S = "Files & batch"401row(S, "Files API",402    side(True, "`POST /v1/files` (purposes user_data, batch, evals, assistants, vision, fine-tune), list/retrieve/delete/content; 512 MB/file; `expires_after` 1 h–30 d; batch files auto-expire 30 d", "POST /v1/files", ["file","purpose","expires_after"], ["DOCUMENTED","LIVE_VERIFIED"], "`user_data` content not downloadable (400)"),403    side(True, "`POST /v1/files` (any MIME; 500 MB/file; workspace-scoped), list (`ids[]`), metadata, content (tool-generated files only), delete; `expires_in_seconds` 1 h–90 d; GA no header", "POST /v1/files", ["file","expires_in_seconds"], ["DOCUMENTED","LIVE_VERIFIED"], "not on Bedrock/Vertex"),404    side(True, "`POST /v1/files` (multipart; `purpose` ignored; `expires_after` 1 h–30 d), list (`filter` AIP-160, `sort_by`), get, delete, `GET …/content?format=original`, **public URLs** (`POST …/public-url`, `…/revoke`; ≤50 MiB, ≤1,000 active/team), chunked upload `files:initialize`/`:uploadChunks` (UNVERIFIED); storage $0.025/GiB/day, downloads $0.20/GiB; used by Responses `input_file`, Collections, Imagine, Batch", "POST /v1/files", ["file","expires_after"], ["DOCUMENTED","LIVE_VERIFIED"], "10 endpoints; disabled under ZDR"),405    side(True, "`POST /upload/v1beta/files` (resumable `X-Goog-Upload-*` protocol, multipart or media), `GET /v1beta/files[/{id}]`, `DELETE`, `POST /v1beta/files:register {uris: gs://…}` (GCS, 30 days), `GET /v1beta/generatedFiles`, download `files/{id}:download?alt=media` (generated files); **2 GB/file, 20 GB/project, 48 h TTL, free**; used via `fileData {fileUri}`", "POST /upload/v1beta/files", ["file","displayName","mimeType"], ["DOCUMENTED","LIVE_VERIFIED"], "unknown file → 403 (never 404); not available on Vertex AI"),406    True, "All four are blob stores referenced by id; TTLs range from 48 h (Gemini, fixed) to 90 d (Anthropic); only xAI prices storage and only xAI mints public URLs.", "docs/openai/files-and-uploads.md · docs/anthropic/files-api.md · docs/xai/files.md · docs/gemini/files.md")407row(S, "Multipart / resumable upload",408    side(True, "Uploads API: ≤8 GB in ≤64 MB parts, 1 h TTL", "POST /v1/uploads", ["filename","purpose","bytes","mime_type"], ["DOCUMENTED","LIVE_VERIFIED"], ""),409    NO,410    side(True, "`POST /v1/files:initialize` + `POST /v1/files:uploadChunks` (documented, UNVERIFIED)", "POST /v1/files:initialize", [], ["DOCUMENTED","UNVERIFIED"], ""),411    side(True, "Google resumable upload protocol on `/upload/v1beta/files` and `/upload/v1beta/fileSearchStores/{s}:uploadToFileSearchStore` (`start` → `x-goog-upload-url` → `upload, finalize`; 8 MiB chunk granularity); environments `PUT /upload/v1beta/environments/{env}/files/{path}` (≤2 GiB)", "POST /upload/v1beta/files", ["X-Goog-Upload-Protocol","X-Goog-Upload-Command"], ["DOCUMENTED","LIVE_VERIFIED"], ""),412    True, "Three resumable schemes, all provider-specific.", "docs/openai/files-and-uploads.md · docs/xai/files.md · docs/gemini/files.md")413row(S, "Batch processing (async, discounted)",414    side(True, "JSONL file (`custom_id`, `method`, `url`, `body`) → `POST /v1/batches {input_file_id, endpoint, completion_window:'24h'}`; 50,000 requests / 200 MB; endpoints responses, chat, embeddings, completions, moderations, images, videos; 50 % off; output file 30 d", "POST /v1/batches", ["input_file_id","endpoint","completion_window","output_expires_after"], ["DOCUMENTED","LIVE_VERIFIED"], "cancel LIVE_DISCOVERED 409 on terminal"),415    side(True, "inline `requests[] {custom_id, params}` → `POST /v1/messages/batches`; 100,000 requests / 256 MB; 24 h expiry; results JSONL at `results_url` 29 d; 50 % off all token dims (stacks with caching); all Messages features incl. server tools; `output-300k-2026-03-24` beta", "POST /v1/messages/batches", ["requests","requests[].custom_id","requests[].params"], ["DOCUMENTED","LIVE_VERIFIED"], "6 endpoints all LIVE_VERIFIED"),416    side(True, "`POST /v1/batches {name}` → `POST /v1/batches/{id}/requests {batch_requests[{batch_request_id, batch_request: {chat_get_completion | responses | image_generation | image_edit | video_generation | video_extension}}]}` (inline, ≤25 MB/request) or JSONL via Files (`input_file_id`, ≤50,000 lines / 200 MB); `GET …/requests`, `GET …/results`, `POST …:cancel`; **20 % off** on grok-4.3 / 4.20 only (grok-4.6 / 4.5 / build unsupported; Imagine at standard rates); bypasses rate limits; not with priority; live turnaround 11 s", "POST /v1/batches", ["name","input_file_id","batch_requests"], ["DOCUMENTED","LIVE_VERIFIED"], "8 endpoints; DELETE → 405; `responses` bodies come back as `chat_get_completion`"),417    side(True, "`POST /v1beta/models/{model}:batchGenerateContent {batch:{displayName, inputConfig:{requests:{requests[]} | fileName}, priority, webhookConfig}}` (inline ≤20 MB or JSONL Files ≤2 GB) → `Operation` `batches/{id}`; `:asyncBatchEmbedContent`; `GET /v1beta/batches[/{id}]`, `:cancel`, `DELETE`, `PATCH :update*Batch`; states PENDING→RUNNING→SUCCEEDED|FAILED|CANCELLED|EXPIRED (>48 h); **50 %**; target 24 h; 100 concurrent jobs; per-model enqueued-token caps; results 6 weeks; OpenAI-compat `/v1beta/openai/batches`", "POST /v1beta/models/{model}:batchGenerateContent", ["batch.inputConfig.requests","batch.inputConfig.fileName","batch.displayName"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "9 endpoints; free tier → 400 FAILED_PRECONDITION; list LIVE_VERIFIED"),418    True, "Same 24-h / discounted idea on all four, with 50 % (OpenAI, Anthropic, Gemini) vs 20 % (xAI, three models only). Inline requests: Anthropic, xAI, Gemini; file-based: OpenAI, xAI, Gemini.", "docs/openai/batch.md · docs/anthropic/message-batches.md · docs/xai/batches.md · docs/gemini/batch.md")419420# ============================================================ Prompt caching421S = "Prompt caching"422row(S, "Prompt / context caching",423    side(True, "automatic prefix caching (≥1,024 tokens; exact prefix; `prompt_cache_key` routing hint); GPT-5.6+: `prompt_cache_options {mode: implicit|explicit, ttl:'30m', prewarm}` and per-part `prompt_cache_breakpoint {mode:explicit}` (≤4); `prompt_cache_retention: in_memory|24h` (deprecated)", "POST /v1/responses", ["prompt_cache_key","prompt_cache_options","prompt_cache_retention","prompt_cache_breakpoint"], ["DOCUMENTED","LIVE_VERIFIED"], "reads 0.1× (5.6+) / model-specific; writes 1.25× only on GPT-5.6+"),424    side(True, "explicit `cache_control {type: ephemeral, ttl: 5m|1h}` on system/tools/content blocks (≤4 breakpoints) or top-level automatic; 20-block lookback; min 512 (Fable/Mythos/Opus 5) · 1,024 (Sonnet 5/4.6/4.5, Opus 4.8) · 2,048 (Opus 4.7) · 4,096 (Haiku 4.5, Opus 4.6/4.5)", "POST /v1/messages", ["cache_control","system[].cache_control","messages[].content[].cache_control","tools[].cache_control"], ["DOCUMENTED","LIVE_VERIFIED"], "writes 1.25× (5m) / 2× (1h); reads 0.1× (0.025× Fable 5.1)"),425    side(True, "**automatic** prefix cache, no markers (`cache_control` on `/v1/messages` ignored); sticky routing via `prompt_cache_key` (Responses, Chat) or header `x-grok-conv-id` (Chat/gRPC); include prior `reasoning_content` / encrypted reasoning or use `previous_response_id` to keep hits; no TTL or minimum documented, no write charge; cached reads 0.15×–0.25× (grok-4.6 $0.50, grok-4.3 $0.20); long-context tier doubles cached price too", XR, ["prompt_cache_key","x-grok-conv-id"], ["DOCUMENTED","LIVE_VERIFIED"], "live: a fresh minimal request already shows ~192 cached tokens (hidden system prefix); cached tokens count toward TPM"),426    side(True, "**implicit** caching (automatic on 2.5+, min prompt 4,096 tokens on 3.x Flash/3.1 Pro, 2,048 on 2.5; hits in `usageMetadata.cachedContentTokenCount`) **and explicit** `cachedContents` (`POST /v1beta/cachedContents {model, contents, systemInstruction, tools, ttl|expireTime}` → use `cachedContent: cachedContents/{id}`; default TTL 1 h, PATCH TTL only; min 1,024 tokens live); cached reads 0.1× everywhere; explicit storage $0.50–$4.50 per 1M tokens per hour", GC, ["cachedContent","generationConfig","ttl","expireTime"], ["DOCUMENTED","BETA","ACCOUNT_RESTRICTED"], "explicit caching v1beta-only, not via Interactions; free tier `limit: 0`; no write fee"),427    True, "Two philosophies: implicit (OpenAI default, xAI, Gemini implicit) vs explicit breakpoints (Anthropic, OpenAI 5.6+, Gemini `cachedContents`). Write fees exist only on Anthropic and GPT-5.6+; Gemini charges storage time instead; xAI charges nothing but publishes no TTL.", "docs/comparisons/caching-and-reasoning.md · docs/xai/prompt-caching.md · docs/gemini/context-caching.md")428row(S, "Cache diagnostics",429    side(True, "`prompt_cache_options.comparison_response_id` → `prompt_cache_diagnostics {type: cache_hit|cache_miss{reason}}` (GPT-5.6+)", "POST /v1/responses", ["prompt_cache_options.comparison_response_id"], ["DOCUMENTED"], "reasons: model_changed, tools_changed, text_format_changed, …"),430    side(True, "`diagnostics.previous_message_id` → response `diagnostics` cache-miss reasons; beta `cache-diagnosis-2026-04-07`", "POST /v1/messages", ["diagnostics.previous_message_id"], ["DOCUMENTED","BETA"], ""),431    side(False, "no diagnostics; only `usage.*cached_tokens` counters (`input_tokens_details.cached_tokens`, `prompt_tokens_details.cached_tokens`, `cache_read_input_tokens` on `/v1/messages`)", XR, [], ["DOCUMENTED"], ""),432    side(False, "no diagnostics; `usageMetadata.cachedContentTokenCount` + `cacheTokensDetails[]` only", GC, [], ["DOCUMENTED"], ""),433    True, "OpenAI and Anthropic explain misses; xAI and Gemini only count hits.", "parameters.json")434435# ============================================================ Reasoning / thinking436S = "Reasoning / thinking"437row(S, "Reasoning control",438    side(True, "`reasoning {effort: none|minimal|low|medium|high|xhigh|max, summary: auto|concise|detailed, context: auto|current_turn|all_turns, mode: standard|pro}`; `reasoning` output items with `encrypted_content`; `usage.output_tokens_details.reasoning_tokens`", "POST /v1/responses", ["reasoning.effort","reasoning.summary","reasoning.context","reasoning.mode"], ["DOCUMENTED","LIVE_VERIFIED"], "Chat: `reasoning_effort` only; effort set per model (gpt-6-astra rejects `none`)"),439    side(True, "`thinking {type: adaptive|enabled|disabled, budget_tokens, display: summarized|omitted|updates}` + `output_config.effort: low|medium|high|xhigh|max` (default high); `thinking`/`redacted_thinking` blocks with `signature`; `usage.output_tokens_details.thinking_tokens`", "POST /v1/messages", ["thinking.type","thinking.budget_tokens","thinking.display","output_config.effort"], ["DOCUMENTED","LIVE_VERIFIED"], "`enabled` (manual budget) 400 on 4.7+; adaptive 400 on 4.5 models"),440    side(True, "Responses `reasoning {effort: low|medium|high|xhigh, summary: auto|concise|detailed}` (alias `reasoning_effort`); Chat `reasoning_effort` + `message.reasoning_content` (`delta.reasoning_content` when streaming); `usage.completion_tokens_details.reasoning_tokens`; **reasoning is always on** for grok-4.6/4.5/4.20-reasoning/build (`reasoning_effort` → 400 on 4.20-reasoning and build); grok-4.3 accepts `none` (LIVE_DISCOVERED, 0 reasoning tokens); `grok-4.20-0309-non-reasoning` has none; on `grok-4.20-multi-agent-0309` effort selects **4 or 16 agents**", XR, ["reasoning.effort","reasoning.summary","reasoning_effort"], ["DOCUMENTED","LIVE_VERIFIED"], "`max_output_tokens` documented to include reasoning but not enforced live; 'Reply with OK.' costs 70–180 reasoning tokens"),441    side(True, "`generationConfig.thinkingConfig {thinkingLevel: MINIMAL|LOW|MEDIUM|HIGH (Gemini 3), thinkingBudget: -1|0|N (2.5-era, LEGACY on 3.x; exclusive with level → 400), includeThoughts}`; defaults high (3.1 Pro, 3 Flash) / medium (3.5–3.8 Flash) / minimal (Flash-Lite); `MINIMAL` → 400 on 3.8/3.7 Flash and 3.1 Pro; thought parts `{text, thought: true}`; `usageMetadata.thoughtsTokenCount`; Interactions `generation_config.thinking_level` + `thinking_summaries: auto|none`", GC, ["generationConfig.thinkingConfig.thinkingLevel","generationConfig.thinkingConfig.thinkingBudget","generationConfig.thinkingConfig.includeThoughts"], ["DOCUMENTED","LIVE_VERIFIED"], "thinking cannot be disabled on 3.8/3.7 Flash, 3.1 Pro, 2.5 Pro; `thinkingBudget: 0` works on 3.6/3.5 Flash; OpenAI-compat maps `reasoning_effort` minimal/low/medium/high"),442    True, "Four effort ladders overlap on low/medium/high: OpenAI adds none/minimal/xhigh/max, Anthropic xhigh/max, xAI xhigh, Gemini minimal. Off-switches: OpenAI `none` (most models), Anthropic `disabled` (not Fable/Mythos), xAI `none` on grok-4.3 only, Gemini `thinkingBudget: 0` on two Flash models only. Only Anthropic and Gemini (2.5) expose a token budget.",443    "docs/openai/reasoning.md · docs/anthropic/thinking.md · docs/xai/reasoning.md · docs/gemini/thinking.md")444row(S, "Reasoning visibility",445    side(True, "summaries only (`reasoning.summary`); raw `content[]` empty for GPT models; encrypted replay item", "POST /v1/responses", ["reasoning.summary","include"], ["DOCUMENTED","LIVE_VERIFIED"], ""),446    side(True, "summarized text by default (≤4.6) or omitted (4.7+); `display: updates` progress text (Fable 5.x beta); signature always present", "POST /v1/messages", ["thinking.display"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),447    side(True, "Chat returns the **full `reasoning_content` text** by default; Responses returns `reasoning` items with `summary[]` (`reasoning.summary` accepted 'for compatibility'; the item is sometimes omitted); `/v1/messages` returns `thinking` blocks with an empty `signature`", XR, ["reasoning.summary","include"], ["DOCUMENTED","LIVE_VERIFIED"], ""),448    side(True, "`includeThoughts: true` → thought **summaries** as `thought: true` parts (not guaranteed on trivial prompts); `thoughtSignature` (opaque) on function-call and final parts; Interactions `thought` steps `{signature, summary[]}`", GC, ["generationConfig.thinkingConfig.includeThoughts","contents[].parts[].thoughtSignature"], ["DOCUMENTED","LIVE_VERIFIED"], "billing is on full thoughts, not the summary"),449    True, "Only xAI (Chat Completions) exposes the raw chain of thought; the other three return summaries plus an opaque signature/encrypted blob.", "docs/anthropic/thinking.md §3 · docs/xai/reasoning.md · docs/gemini/thinking.md")450row(S, "Reasoning replay across turns",451    side(True, "replay `reasoning` items verbatim (auto with `previous_response_id`); `encrypted_content` decrypted in memory when `store:false`; `reasoning.context: all_turns` (GPT-5.6 default)", "POST /v1/responses", ["input[](reasoning).encrypted_content","reasoning.context"], ["DOCUMENTED","LIVE_VERIFIED"], ""),452    side(True, "pass `thinking` blocks back unmodified within tool-use turns (400 if modified); prior-turn thinking kept for all turns on Opus 4.5+/Sonnet 4.6+/Fable, last turn on Haiku/Sonnet 4.5; `clear_thinking_20251015` edit; beta `thinking.block_binding`", "POST /v1/messages", ["messages[].content[].signature","thinking.block_binding"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),453    side(True, "`include: [\"reasoning.encrypted_content\"]` (xai-sdk `use_encrypted_content=True`) → replay the `reasoning` items with `encrypted_content` when `store:false` (ZDR) — also the 'top cause of cache misses' when omitted; `previous_response_id` rehydrates automatically; Chat: resend `reasoning_content`", XR, ["include","input[](reasoning).encrypted_content","previous_response_id"], ["DOCUMENTED","LIVE_VERIFIED"], ""),454    side(True, "**mandatory** on Gemini 3: echo `thoughtSignature` of the first `functionCall` of each step (400 'missing a thought_signature' / `finishReason: MISSING_THOUGHT_SIGNATURE`, even at `minimal`); text-part signatures recommended; tampering → 400 'Corrupted thought signature'; Interactions carry it in `thought` steps; 'thought preservation' across turns since 3.5 Flash", GC, ["contents[].parts[].thoughtSignature"], ["DOCUMENTED","LIVE_VERIFIED"], "dummy values `skip_thought_signature_validator` bypass validation (verified)"),455    True, "All four carry hidden reasoning as an opaque blob; Anthropic and Gemini validate it (400 on edits / omissions), OpenAI and xAI encrypt it.", "docs/anthropic/thinking.md §4 · docs/xai/reasoning.md · docs/gemini/thinking.md")456row(S, "Pro / extended-compute mode",457    side(True, "`reasoning.mode: pro` (GPT-5.6) billed at standard rates; `*-pro` models (gpt-5.4-pro, gpt-5.5-pro)", "POST /v1/responses", ["reasoning.mode"], ["DOCUMENTED"], ""),458    side(False, "`effort: max` is the top of the ladder; no separate mode", "", ["output_config.effort"], ["DOCUMENTED"], ""),459    side(True, "`grok-4.20-multi-agent-0309` (BETA): one Responses call fans out to 4 (low/medium) or 16 (high/xhigh) agents; all agents' tokens billed at grok-4.20 rates; Responses-only (Chat → 400)", XR, ["reasoning.effort"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "'Reply with OK.' cost 1,645 output tokens ≈ $0.0047"),460    side(True, "`gemini-3.8-live-extended-thinking` (Live) and Deep Research **agents** (`deep-research-preview-04-2026`, `-max-`; 60-min background runs, $1–7 per task estimated) rather than a mode; `gemini-3.1-pro-preview` is the deep-reasoning text model", IX, ["agent","agent_config(deep-research)"], ["DOCUMENTED","PREVIEW","LIVE_VERIFIED"], ""),461    False, "Different vehicles: a mode/model (OpenAI), a multi-agent model (xAI), an agent (Gemini), a ladder value (Anthropic).", "parameters.json · docs/models/xai-models.md · docs/gemini/interactions-api.md")462row(S, "Change effort mid-conversation without breaking the cache",463    side(True, "`configuration_update` input item `{reasoning:{effort}}` (gpt-6-astra)", "POST /v1/responses", ["input[](configuration_update)"], ["DOCUMENTED"], ""),464    side(True, "`messages[].output_config.effort` on `role:system` entries; beta `mid-conversation-output-config-2026-07-01` (Fable 5.1, Mythos 5.1, Opus 5)", "POST /v1/messages", ["messages[].output_config.effort"], ["DOCUMENTED","BETA"], ""),465    side(False, "per-request `reasoning.effort` only (automatic cache; no documented invalidation rule)", XR, [], ["DOCUMENTED"], ""),466    side(False, "per-request `thinkingLevel` only; an explicit `cachedContents` prefix is unaffected by generationConfig changes", GC, [], ["DOCUMENTED"], ""),467    True, "OpenAI and Anthropic only.", "parameters.json")468row(S, "Task-wide token budget (advisory)",469    side(False, "none in Responses (`max_tool_calls` caps hosted tool calls; Agents API has `session_budget_exceeded`)", "POST /v1/responses", ["max_tool_calls"], ["DOCUMENTED"], ""),470    side(True, "`output_config.task_budget {type, total ≥20000, remaining}`; beta `task-budgets-2026-03-13` (Fable/Mythos/Opus 5/4.8/4.7)", "POST /v1/messages", ["output_config.task_budget"], ["DOCUMENTED","BETA"], ""),471    side(True, "`max_turns` (agentic turns per Responses request; default = server cap) — a turn budget, not tokens", XR, ["max_turns"], ["DOCUMENTED","LIVE_VERIFIED"], ""),472    side(True, "Antigravity `agent_config.max_total_tokens` (Interactions, PREVIEW) → status `incomplete` when exhausted", IX, ["agent_config(antigravity).max_total_tokens"], ["DOCUMENTED","PREVIEW"], ""),473    False, "Three different budget units (tokens, turns, agent tokens); none on the OpenAI Responses API.", "compatibility/anthropic-feature-model-matrix.json · docs/xai/responses.md · docs/gemini/interactions-api.md")474475# ============================================================ Context management476S = "Context management"477row(S, "Context window",478    side(True, "1,050,000 (GPT-5.4/5.5/5.6/6 Astra; >272k input = long-context pricing 2×/1.5×), 400k (5.x mini/nano, GPT-5–5.3), 200k (o-series), 128k (gpt-4o)", "", [], ["DOCUMENTED"], ""),479    side(True, "1,000,000 default on Claude 4.6+ (no header, no premium); 200k on Opus 4.5 / Sonnet 4.5 / Haiku 4.5; `context-1m-2025-08-07` header RETIRED", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),480    side(True, "1,000,000 (grok-4.3, all grok-4.20 ids), 500,000 (grok-4.6, grok-4.5), 256,000 (grok-build-0.1); prompts ≥200,000 tokens switch the **whole request** to the 2× long-context tier", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "`usage.context_details` on Responses"),481    side(True, "1,048,576 on every Gemini 3.x / 2.5 text model (`inputTokenLimit`); 262,144 Gemma 4; 131,072 Live / image / agent models; Pro models bill >200k prompts at 2× input / 1.5× output, Flash models flat", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),482    True, "~1M on every flagship line; long-context premiums on OpenAI (>272k), xAI (≥200k, all tokens) and Gemini Pro (>200k); none on Anthropic or Gemini Flash.", "models.json")483row(S, "Max output tokens",484    side(True, "128,000 on GPT-5.x/6 (272,000 on gpt-5-pro); `max_output_tokens` ≥16", "POST /v1/responses", ["max_output_tokens"], ["DOCUMENTED","LIVE_VERIFIED"], ""),485    side(True, "128,000 on Claude 4.6+ (64,000 on 4.5 models); `max_tokens` required; 300,000 in Batches with `output-300k-2026-03-24`", "POST /v1/messages", ["max_tokens"], ["DOCUMENTED","LIVE_VERIFIED"], ""),486    side(True, "**no documented limit** (`max_output: null` on every Grok record; grok-4.6 page: 'No text output limit'); Responses `max_output_tokens` default 128,000 (docs) and not enforced on reasoning live; Chat `max_completion_tokens` caps visible output only", XR, ["max_output_tokens","max_completion_tokens"], ["DOCUMENTED","LIVE_VERIFIED"], "`max_tokens` DEPRECATED alias on Chat"),487    side(True, "65,536 on every 3.x / 2.5 text model (`outputTokenLimit`); 32,768 Gemma 4 / image models; `maxOutputTokens` **includes thinking tokens** (hit → `finishReason: MAX_TOKENS`, possibly empty text)", GC, ["generationConfig.maxOutputTokens"], ["DOCUMENTED","LIVE_VERIFIED"], "Interactions `generation_config.max_output_tokens`"),488    True, "128k (OpenAI, Anthropic), 64k (Gemini), unpublished (xAI). Only Anthropic makes the cap mandatory.", "models.json")489row(S, "Server-side compaction (in-flight)",490    side(True, "`context_management: [{type: compaction, compact_threshold ≥1000}]` → `compaction` output item, SSE `response.compaction.compacting`", "POST /v1/responses", ["context_management[].compact_threshold"], ["DOCUMENTED"], ""),491    side(True, "`context_management.edits: [{type: compact_20260112, trigger ≥50000, pause_after_compaction, instructions}]` → `compaction` block, `stop_reason: compaction`; beta `compact-2026-01-12`; 4.6+", "POST /v1/messages", ["context_management.edits[]"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "usage.iterations[] for billing"),492    side(False, "`context_management[]` accepted but 'parsed but not yet executed' (compat only); use the stand-alone compact endpoint", XR, ["context_management"], ["DOCUMENTED"], ""),493    side(True, "Live API only: `setup.contextWindowCompression {triggerTokens, slidingWindow {targetTokens}}` (unlimited session length); Antigravity agents compact around ~135k automatically; nothing on `generateContent`", "WSS BidiGenerateContent", ["setup.contextWindowCompression"], ["DOCUMENTED"], ""),494    True, "OpenAI and Anthropic compact text conversations in-flight; Gemini only compresses Live sessions; xAI parses the field and ignores it.", "docs/openai/responses.md §6 · docs/anthropic/context-management.md §3 · docs/gemini/live-api.md")495row(S, "Stand-alone compaction request",496    side(True, "`POST /v1/responses/compact {model, input|previous_response_id}` → `response.compaction` with encrypted `compaction` item", "POST /v1/responses/compact", ["model","input","previous_response_id","instructions"], ["DOCUMENTED","LIVE_VERIFIED"], ""),497    side(True, "`compaction: {type: summarize}` on Messages → single signed `compaction` block; beta `compact-2026-09-04`", "POST /v1/messages", ["compaction","compaction.type","compaction.instructions"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "block must be sent first"),498    side(True, "`POST /v1/responses/compact {model, input}` → `{object: response.compaction, id: cmp_…, output:[{type: compaction, encrypted_content}], usage {…, dropped_message_count}}`; put the `output` first in the next `input`; do not edit the blob; the pre-compaction conversation must still fit the window (May 2026 'Context Compaction API')", "POST /v1/responses/compact", ["model","input"], ["DOCUMENTED","LIVE_VERIFIED"], "48 parameter rows"),499    NO,500    True, "OpenAI-shaped on xAI (same endpoint and item); Anthropic as a Messages parameter; none on Gemini.", "docs/anthropic/context-management.md §3 · docs/xai/responses.md")501row(S, "Server-side context editing (clear old tool results / thinking)",502    side(False, "no editing strategies; legacy `truncation: auto` drops oldest items", "POST /v1/responses", ["truncation"], ["DOCUMENTED","LEGACY","LIVE_VERIFIED"], ""),503    side(True, "`context_management.edits[]`: `clear_tool_uses_20250919`, `clear_thinking_20251015`; beta `context-management-2025-06-27`; response `context_management.applied_edits[]`", "POST /v1/messages", ["context_management.edits[].type","context_management.edits[].trigger","context_management.edits[].keep"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),504    side(False, "`truncation` accepted (`disabled` echoed) — 'not supported, compatibility only'", XR, ["truncation"], ["DOCUMENTED"], ""),505    NO, False, "Anthropic-only.", "docs/anthropic/context-management.md §2")506row(S, "Mid-conversation tool add/remove (cache-preserving)",507    side(True, "`additional_tools` developer item (adds tools mid-thread); `tool_choice: allowed_tools` to restrict", "POST /v1/responses", ["input[](additional_tools)"], ["DOCUMENTED"], ""),508    side(True, "`tool_addition`/`tool_removal` blocks in `role:system` messages; beta `mid-conversation-tool-changes-2026-07-01` (Fable 5, Mythos 5, Opus 4.8, Opus 5)", "POST /v1/messages", ["messages[].role"], ["DOCUMENTED","BETA"], ""),509    side(False, "follow-ups via `previous_response_id` 'may change tools/model' — no dedicated item; cache effect undocumented", XR, ["previous_response_id"], ["DOCUMENTED"], ""),510    side(False, "resend the full `tools[]` each call (Interactions chaining also requires re-sending tools)", GC, [], ["DOCUMENTED"], ""),511    True, "OpenAI and Anthropic only.", "anthropic-beta-headers.json")512513# ============================================================ Service tiers, limits, safety514S = "Service tiers, limits, safety"515row(S, "Service tiers / processing modes",516    side(True, "`service_tier: auto|default|flex|scale|priority|fast|ultrafast`; flex = batch price, slower; fast = 2× (renamed from priority 2026-07-30); echoed in response", "POST /v1/responses", ["service_tier"], ["DOCUMENTED","LIVE_VERIFIED"], ""),517    side(True, "`service_tier: auto|standard_only` (Priority Tier commitments, no longer sold) + `speed: fast` (beta `fast-mode-2026-02-01`, Opus 5 / 4.8 only, 2× price); `usage.service_tier` standard|priority|batch", "POST /v1/messages", ["service_tier","speed"], ["DOCUMENTED","BETA","PREVIEW","ACCOUNT_RESTRICTED"], "fast 429 'rate limit of 0' for our key"),518    side(True, "`service_tier: default|priority` (Chat + Responses): **priority = 2×** on every token type (after the cache discount), billed only when the response echoes `service_tier: priority`; not combinable with Batch", XR, ["service_tier"], ["DOCUMENTED","LIVE_VERIFIED"], "live responses always echoed `default`"),519    side(True, "`serviceTier: standard|flex|priority` (`service_tier` on Interactions / OpenAI-compat): **flex = 0.5×** (1–15 min target, sheddable → 429), **priority = 1.8×** (0.3× rate limit, graceful downgrade to standard); echoed in `usageMetadata.serviceTier` and header `X-Gemini-Service-Tier`", GC, ["serviceTier"], ["DOCUMENTED","LIVE_VERIFIED"], "flex accepted live; ten text models listed"),520    True, "Cheaper tier: OpenAI flex, Gemini flex (both 50 %). Faster tier: OpenAI fast 2×, Anthropic fast 2× (two models), xAI priority 2×, Gemini priority 1.8×.", "docs/anthropic/service-tiers.md · docs/xai/pricing.md · docs/gemini/pricing.md · pricing.json")521row(S, "End-user identifier for abuse detection",522    side(True, "`safety_identifier` (≤64 chars; replaces `user`) + `prompt_cache_key`; header `OpenAI-Safety-Identifier` on Realtime", "POST /v1/responses", ["safety_identifier","user"], ["DOCUMENTED","LIVE_VERIFIED"], ""),523    side(True, "`metadata.user_id` (≤512 chars, no PII); beta `anthropic-user-profile-id` header", "POST /v1/messages", ["metadata.user_id","anthropic-user-profile-id"], ["DOCUMENTED","LIVE_VERIFIED"], ""),524    side(True, "`user` and `safety_identifier` (both accepted on Chat and Responses); `/v1/messages` `metadata.user_id`", XR, ["safety_identifier","user"], ["DOCUMENTED","LIVE_VERIFIED"], ""),525    side(True, "`labels {safety_identifier: …}` (documented key; Cloud-label rules; accepted, not echoed) on generateContent and Interactions", GC, ["labels"], ["DOCUMENTED","LIVE_VERIFIED"], ""),526    True, "Same idea everywhere; the field name changes four times.", "parameters.json")527row(S, "Rate-limit headers",528    side(True, "`x-ratelimit-{limit,remaining,reset}-{requests,tokens}` (+ `-project-tokens`), `Retry-After`, `retry-after-ms`, `x-should-retry`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "reset as Go durations (`6m0s`)"),529    side(True, "`anthropic-ratelimit-{requests,tokens,input-tokens,output-tokens}-{limit,remaining,reset}` (RFC 3339), `retry-after`, `x-should-retry`, `anthropic-priority-*`, `anthropic-fast-*`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "not on GET /models or count_tokens"),530    side(True, "**undocumented but observed**: `x-ratelimit-limit-requests` (7,200 grok-4.6/4.5, 1,800 grok-4.3/4.20/build — per minute), `x-ratelimit-remaining-requests`, `x-ratelimit-limit-tokens` (50,000,000 / 10,000,000 = documented T0 TPM), `x-ratelimit-remaining-tokens`; no `reset`, no `Retry-After`; `x-request-id`, `x-zero-data-retention`", "", [], ["DOCUMENTED","LIVE_DISCOVERED"], "absent on `/v1/responses` multi-agent calls and catalogue GETs"),531    side(False, "**none** — no `x-ratelimit-*` or `Retry-After` on 200/404/429; retry delay only inside the 429 message text ('Please retry in 54.2s') and `google.rpc.RetryInfo`; undocumented `X-Gemini-Service-Tier` header", "", [], ["DOCUMENTED","LIVE_DISCOVERED"], "no request-id header either — use `responseId` in the body"),532    True, "Headers on three providers (xAI's undocumented); Gemini puts the information in the 429 body.", "headers.json · rate-limits.json")533row(S, "Rate-limit tiers",534    side(True, "Free, Tier 1–5 by cumulative spend ($5 → $1,000) with monthly usage caps $100 → $200k; per-model RPM/TPM/batch-queue tables; long-context tables >272k", "", [], ["DOCUMENTED"], "Scale/Reserved Tier, Ultrafast preview above Tier 5"),535    side(True, "Start ($500/mo cap) / Build ($1,000) / Scale ($200k) / Custom; per model-class RPM/ITPM/OTPM (cache reads excluded from ITPM); Batches & count_tokens separate", "", [], ["DOCUMENTED","LIVE_DISCOVERED"], "observed Scale-tier headers for our key"),536    side(True, "Tier 0–4 by cumulative spend since 2026-01-01 ($0 / $50 / $250 / $1,000 / $5,000; Enterprise on request); per-model **RPS** (= RPM/60) and **TPM** (prompt + completion + reasoning + cached): grok-4.6/4.5 150→500 RPS, 50M→100M TPM; grok-4.3/4.20/build 37→208 RPS, 10M→85M TPM; multi-agent 9→56 RPS; Imagine RPS-only (6→100 images, 10→158 videos); voice concurrent sessions 10→200; Batch bypasses limits; per-key `qps/qpm/tpm` caps via Management API", "", [], ["DOCUMENTED","LIVE_DISCOVERED"], "console shows personalised limits"),537    side(True, "Free / Tier 1 (billing linked; $250 cap, $10 per rolling 10 min) / Tier 2 ($100 paid + 3 days; $2,000; $50) / Tier 3 ($1,000 + 30 days; $20k–100k+; $200); dimensions RPM / TPM / RPD (+ IPM, TPD) **per project**; per-model matrix published only in AI Studio; Pro and media models unavailable on Free (`limit: 0`); priority 0.3× limits; batch enqueued-token caps per model", "", [], ["DOCUMENTED","LIVE_DISCOVERED"], "free-tier RPM observed 15/min on flash-lite"),538    True, "Spend-based tiers everywhere; xAI is the only provider publishing exact per-model RPS/TPM per tier in the docs, Gemini the only one with a genuinely free tier.", "generated/rate-limits.json")539row(S, "Overload / capacity error",540    side(True, "HTTP 503 `server_is_overloaded` (retryable, `Retry-After`)", "", [], ["DOCUMENTED"], ""),541    side(True, "HTTP 529 `overloaded_error` (also as SSE `error` event after 200); acceleration limits now 429", "", [], ["DOCUMENTED"], ""),542    side(True, "HTTP 429 (RPS/TPM/credits; gRPC RESOURCE_EXHAUSTED) and 5xx `internal` — no dedicated overload code; status.x.ai", "", [], ["DOCUMENTED"], "no 429 triggered in this run"),543    side(True, "HTTP 503 `UNAVAILABLE` ('The model is overloaded. Please try again later.'), 429 `RESOURCE_EXHAUSTED` when Flex capacity is shed, 504 `DEADLINE_EXCEEDED` for long Flex/Deep Research requests", "", [], ["DOCUMENTED"], ""),544    True, "503 (OpenAI, Gemini), 529 (Anthropic), 429 (xAI) for the same condition.", "errors.json")545row(S, "Error envelope",546    side(True, "`{error: {message, type, param, code}}`; types invalid_request_error, rate_limit_error, insufficient_quota, server_error…; codes e.g. `model_not_found`, `context_length_exceeded`, `previous_response_not_found`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "empty-body 404 from Cloudflare on unknown URLs"),547    side(True, "`{type: error, error: {type, message}, request_id}`; types invalid_request_error, authentication_error, permission_error, not_found_error, request_too_large, rate_limit_error, api_error, overloaded_error, billing_error, timeout_error", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "no `code` field except `error.details.error_code` on some 429/529"),548    side(True, "`{code: <kebab-case>, error: <message>}` (`invalid-argument`, `not-found`, `unauthenticated:no-credentials`…); 422 = **bare JSON string** (serde message); Management API = gRPC-style `{code: 16, message, details[]}`; Realtime WS `{type: error, error:{type, code, message}}`; **an invalid API key returns 400, not 401**", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "12 error records; gRPC↔HTTP mapping 3→400, 16→401, 7→403, 5→404, 8→429"),549    side(True, "google.rpc `Status`: `{error: {code: <http>, message, status: INVALID_ARGUMENT|FAILED_PRECONDITION|UNAUTHENTICATED|PERMISSION_DENIED|NOT_FOUND|ALREADY_EXISTS|RESOURCE_EXHAUSTED|INTERNAL|UNIMPLEMENTED|UNAVAILABLE|DEADLINE_EXCEEDED…, details[] (BadRequest.fieldViolations, QuotaFailure, RetryInfo, Help)}}`; Interactions `{error: {code: <snake_case>, message}}`; soft failures at HTTP 200 (`promptFeedback.blockReason`, `finishReason`); Live WS close codes 1007/1008", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "18 error records; unknown File/Operation → 403, not 404"),550    True, "Four envelopes; only Anthropic and OpenAI carry a request id in the body/header pair; Gemini has no request-id header at all.", "docs/errors/openai.md · docs/errors/anthropic.md · docs/xai/authentication-headers-errors.md · docs/errors/gemini.md")551row(S, "Idempotency key",552    side(False, "not documented for api.openai.com (only Workspace Agents on api.chatgpt.com); dedupe via `metadata`/`custom_id`", "", [], ["UNVERIFIED"], ""),553    side(False, "not documented; SDKs retry on 409", "", [], ["UNVERIFIED"], ""),554    side(False, "not documented; `public-url` creation is idempotent by design; batch `batch_request_id` dedupes within a batch", "", [], ["UNVERIFIED"], ""),555    side(False, "not documented; batch `key` per JSONL line; `seed` for determinism", "", [], ["UNVERIFIED"], ""),556    False, "No provider offers request idempotency keys on the model APIs.", "headers.json")557558# ============================================================ Auth, versioning, SDKs, platform559S = "Auth, versioning, SDKs, platform"560row(S, "Authentication",561    side(True, "`Authorization: Bearer <sk-proj-…|sk-…|service-account key|WIF access token>`; optional `OpenAI-Organization`, `OpenAI-Project`; Admin keys `sk-admin-…`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "WIF token exchange at auth.openai.com / mTLS"),562    side(True, "`x-api-key: sk-ant-api03-…` **or** `Authorization: Bearer <key|sk-ant-oat01-… OAuth/WIF token>`; `anthropic-workspace-id`; Admin keys `sk-ant-admin01-…`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "WIF via `POST /v1/oauth/token`"),563    side(True, "`Authorization: Bearer xai-…` on REST, WebSocket and gRPC metadata; separate **Management key** for `management-api.x.ai` (inference key → 401 code 16); ephemeral `xai-realtime…` client secrets for browsers (`POST /v1/realtime/client_secrets`); per-key ACLs `api-key:endpoint:*`, `api-key:model:*` (new keys have **no access by default**); mTLS host `mtls.api.x.ai` (enterprise)", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "`GET /v1/api-key`, `GET /v1/me` introspection"),564    side(True, "`x-goog-api-key: AIza…` (recommended; `?key=` discouraged); `Authorization: Bearer <GEMINI_API_KEY>` **mandatory** on `/v1beta/openai/*`; OAuth/ADC Bearer alternative (+ `x-goog-user-project`); ephemeral tokens `POST /v1beta/auth_tokens` for the Live API; **standard keys rejected from September 2026** in favour of service-account-bound auth keys", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "limits are per project, not per key"),565    True, "Bearer everywhere except Gemini's native header; only OpenAI/Anthropic/xAI split admin vs inference keys; Gemini is the only one retiring a key type.", "headers.json · docs/openai/authentication-and-keys.md · docs/anthropic/admin-api.md §1 · docs/xai/authentication-headers-errors.md · docs/gemini/authentication-headers-versions.md")566row(S, "API version header / path version",567    side(False, "none (server answers `openai-version: 2020-10-01`)", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),568    side(True, "`anthropic-version: 2023-06-01` **required** on every request (400 otherwise)", "", ["anthropic-version"], ["DOCUMENTED","LIVE_VERIFIED"], ""),569    side(False, "no version header, no beta headers; features selected by body fields or base URL; Interactions-style `Api-Revision` does not exist", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),570    side(True, "version in the **URL path**: `/v1beta` (86 methods, default for SDKs) vs `/v1` (47; stable subset — no caching, tuning, Live, Files, agents); Interactions optional header `Api-Revision: 2026-05-20`", "", ["Api-Revision"], ["DOCUMENTED","LIVE_VERIFIED"], "docs say every model is in both versions; live `/v1/models` lists 22 vs 58"),571    False, "Header (Anthropic), path (Gemini), nothing (OpenAI, xAI).", "headers.json · docs/gemini/authentication-headers-versions.md")572row(S, "Beta opt-in header",573    side(True, "`OpenAI-Beta`: `agents=v1`, `chatkit_beta=v1`, `workspace_agent_runs=v1`, `responses_multi_agent=v1`, legacy `assistants=v2`, `realtime=v1`; plus `?beta=true` surface with body `openai-beta[]`", "", ["OpenAI-Beta"], ["DOCUMENTED"], "400 `invalid_beta` when missing"),574    side(True, "`anthropic-beta: <feature>-<YYYY-MM-DD>[,…]` (50 catalogued values; SDK `betas=[…]`, `client.beta.*`); unknown → 400", "", ["anthropic-beta","betas"], ["DOCUMENTED","LIVE_VERIFIED"], "see docs/faq.md for the current list"),575    side(False, "**none**; alpha features answer 403 ('only available for alpha users' — `tool_search`) or 404 (ACL)", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),576    side(False, "**none**; gating by `/v1beta` path and `-preview` / `-exp` model ids (`kind: preview` 45 records)", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),577    False, "Anthropic gates parameters, OpenAI gates surfaces, Gemini gates by path/model id, xAI by account.", "generated/fragments/headers/anthropic-beta-headers.json · headers.json · docs/faq.md Q6")578row(S, "Request correlation",579    side(True, "response `x-request-id`; request `X-Client-Request-Id` (logged, not echoed); `openai-processing-ms`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),580    side(True, "response `request-id` (also `request_id` in error body); `anthropic-organization-id`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),581    side(True, "response `x-request-id` (= `chat.completion.id`), `Server-Timing` (Cloudflare `cfEdge`/`cfOrigin`), `CF-RAY`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "absent on catalogue GETs"),582    side(False, "no request-id header; `responseId` in the JSON body; `Server-Timing: gfet4t7; dur=…`", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),583    True, "Header on three providers, body field on Gemini.", "headers.json")584row(S, "Official SDKs",585    side(True, "Python `openai` 3.16.2, Node `openai` 7.18/7.19, .NET, Java 4.65 (beta label), Go v3 (beta), Ruby, CLI, Agents SDK (py/ts), Azure libraries; retries 2, timeout 600 s", "", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),586    side(True, "Python `anthropic` 1.7.0, TS `@anthropic-ai/sdk` 0.126, Go, Java 2.63, Ruby, C# ≥10, PHP (beta), `ant` CLI 1.33; retries 2, timeout 10 min; cloud clients Bedrock/Vertex/AWS/Foundry", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "Python v1 removed sampling kwargs and `completions`"),587    side(True, "Python `xai-sdk` 1.19 (**gRPC**, `client.chat.create().sample()/stream()/defer()/parse()`, `response.cost_usd`, timeout 1620 s) — no official Node SDK: use `openai` with `baseURL: https://api.x.ai/v1`, `@ai-sdk/xai`, `langchain-xai`, or the Anthropic SDK against `/v1/messages` (deprecated); Grok Build CLI (`grok`, BETA); protos `xai-org/xai-proto` for `buf curl`; gRPC `api.x.ai:443` (11 services / 38 RPCs) lacks Responses items, voice, skills", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "9 SDK records"),588    side(True, "Python `google-genai` 2.24 (`genai.Client()`; same SDK targets Vertex with `vertexai=True`), JS `@google/genai` 2.23, Go `google.golang.org/genai`, Java `com.google.genai`, C# `Google.GenAI`; Firebase AI Logic / Genkit / Vercel AI SDK; OpenAI SDK against `/v1beta/openai`; legacy `google-generativeai`, `@google/generative-ai`, Go/Dart/Swift/Android libs **DEPRECATED** 2025-11-30", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "8 SDK records; default `api_version` v1beta"),589    True, "Every provider has Python and Node coverage — xAI's Node path is the OpenAI SDK; xAI's own SDK is the only gRPC-first one.", "sdks.json · docs/xai/sdks.md · docs/gemini/sdks.md")590row(S, "Webhooks (platform events)",591    side(True, "`/v1/webhook_endpoints` CRUD + `rotate_secret`, `test`; `/v1/webhook_event_types`; events batch.*, response.*, fine_tuning.*, eval.run.*, video.*, realtime/live incoming calls, safety.*, agent.session.*; Standard Webhooks signature (`webhook-id/-timestamp/-signature`, `whsec_`)", "GET /v1/webhook_endpoints", [], ["DOCUMENTED","LIVE_VERIFIED"], "28 event types"),592    side(True, "Managed Agents only: endpoints registered in Console (no API), 44 event types (agent.*, session.*, deployment*.*, environment.*, vault*.*, memory_store.*); same Standard Webhooks headers; ≤3 attempts, 5-min freshness; beta `managed-agents-2026-04-01`", "", [], ["DOCUMENTED","BETA"], "no webhooks for Messages/Batches"),593    side(True, "only the SIP voice webhook `realtime.call.incoming` (Standard Webhooks headers, HMAC-SHA256) registered via `POST /v2/phone-numbers {webhook:{url}}`; no batch/response webhooks", "POST /v2/phone-numbers", [], ["DOCUMENTED"], ""),594    side(True, "`POST/GET /v1/webhooks`, `GET|PATCH|DELETE /v1/webhooks/{id}`, `POST …/rotate_secret` (documented on **/v1**, BETA) + per-request `webhook_config {uris[], user_metadata}` / Batch `webhookConfig`; events `interaction.completed|failed|cancelled|requires_action`, `batch.succeeded|failed`; JWKS-signed", "POST /v1/webhooks", ["webhook_config"], ["DOCUMENTED","BETA"], "7 endpoints, not tested; `:ping` UNVERIFIED"),595    True, "OpenAI covers the widest event set; Gemini and Anthropic cover their agent/interaction resources; xAI only incoming calls.", "generated/webhook-events.json · docs/openai/webhooks.md · docs/anthropic/managed-agents.md §17.2 · docs/gemini/interactions-api.md")596row(S, "Administration API",597    side(True, "124 operations under `/v1/organization/*` and `/v1/projects/*`: admin keys, users, invites, projects, service accounts, project API keys, groups, roles, certificates (mTLS), data retention, spend limits/alerts, audit logs, usage & costs; Admin API key `sk-admin-…`", "GET /v1/organization/*", [], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "all probes 403/401 with a project key"),598    side(True, "100 operations under `/v1/organizations/*`: me, users, invites, workspaces, api_keys, service accounts, federation (WIF), RBAC, spend limits, external keys, tunnels certs, usage_report & cost_report, analytics, Claude Code analytics; Admin key `sk-ant-admin01-…`", "GET /v1/organizations/*", [], ["DOCUMENTED","ACCOUNT_RESTRICTED","LIVE_VERIFIED"], "`GET /v1/organizations/me` works with a regular key"),599    side(True, "**Management API** `https://management-api.x.ai` (21 endpoints, separate Management key, camelCase): API keys (create with `acls[]`, `qps/qpm/tpm`, `expireTime`; rotate; delete; propagation), team models/endpoints ACLs, billing (`billing-info`, invoices, payment methods, postpaid spending limits, prepaid balance/top-up, `POST …/usage` aggregated by key/model/IP/cluster), audit events; teams/members/ZDR toggle are console-only", "GET /auth/teams/{teamId}/api-keys", [], ["DOCUMENTED","ACCOUNT_RESTRICTED"], "inference key → 401 code 16"),600    side(False, "no admin API on the Developer API: keys/projects/quota live in AI Studio and Google Cloud IAM/Console; `GET /v1beta/models` is the only account-scoped read", "", [], ["DOCUMENTED"], ""),601    True, "Three admin surfaces (OpenAI, Anthropic, xAI — all inaccessible to this atlas's keys); Gemini delegates to Google Cloud.", "docs/openai/admin-api.md · docs/anthropic/admin-api.md · docs/xai/management-api.md")602row(S, "Usage & cost reporting",603    side(True, "`GET /v1/organization/usage/{completions,embeddings,images,…}` + `GET /v1/organization/costs` (buckets 1m/1h/1d, group_by)", "GET /v1/organization/costs", ["start_time","bucket_width","group_by"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], ""),604    side(True, "`GET /v1/organizations/usage_report/messages`, `/usage_report/claude_code`, `/cost_report`; analytics `/analytics/{usage_report,cost_report,user_*}`", "GET /v1/organizations/cost_report", ["starting_at","bucket_width","group_by"], ["DOCUMENTED","ACCOUNT_RESTRICTED"], ""),605    side(True, "per-request **`usage.cost_in_usd_ticks`** (1 USD = 10^10 ticks) on every inference response + `POST /v1/billing/teams/{team_id}/usage` (Management API, aggregated by API key / model / IP / cluster / token type); batch `cost_breakdown` (SDK/gRPC)", "POST /v1/billing/teams/{team_id}/usage", [], ["DOCUMENTED","ACCOUNT_RESTRICTED","LIVE_VERIFIED"], "cost ticks LIVE_VERIFIED; billing endpoint restricted"),606    side(True, "no reporting endpoint; per-response `usageMetadata` (modality breakdown, `thoughtsTokenCount`, `toolUsePromptTokenCount`, `cachedContentTokenCount`, `serviceTier`) and Interactions `usage {total_*_tokens, *_by_modality, grounding_tool_count}`; billing dashboards in Google Cloud", GC, ["usageMetadata"], ["DOCUMENTED","LIVE_VERIFIED"], ""),607    True, "Org-level reports on OpenAI/Anthropic/xAI; xAI is the only one returning the dollar cost per call; Gemini only per-response token detail.", "endpoints.json (admin, management) · docs/xai/pricing.md · docs/gemini/generate-content.md")608row(S, "Audit / compliance data access",609    side(True, "`GET /v1/organization/audit_logs` (scope `api.audit_logs.read`); safety alerts/cases API", "GET /v1/organization/audit_logs", [], ["DOCUMENTED","ACCOUNT_RESTRICTED"], ""),610    side(True, "Compliance API (36 endpoints, Claude Enterprise Compliance Access Key): activities feed, chats, projects, files, sessions, roles, groups; DELETE operations", "GET /v1/compliance/activities", [], ["DOCUMENTED","ACCOUNT_RESTRICTED"], ""),611    side(True, "`GET /audit/teams/{teamId}/events` (Management API; administrative events only)", "GET /audit/teams/{teamId}/events", [], ["DOCUMENTED","ACCOUNT_RESTRICTED"], ""),612    side(False, "none on the Developer API (Cloud Audit Logs on Vertex AI)", "", [], ["DOCUMENTED"], ""),613    True, "Admin-action logs on OpenAI/Anthropic/xAI; Anthropic additionally exports end-user content (Claude Enterprise).", "docs/anthropic/compliance-and-iam.md · docs/xai/management-api.md")614row(S, "Spend limits",615    side(True, "org/project `spend_limit`, `spend_alerts` Admin endpoints; 429 `insufficient_quota` codes when hit", "POST /v1/organization/spend_limit", [], ["DOCUMENTED"], ""),616    side(True, "`/v1/organizations/spend_limits`, `/spend_limits/effective`, increase requests approve/deny; tier cap → 429 without `retry-after`; self-set limit → 400", "POST /v1/organizations/spend_limits", [], ["DOCUMENTED","ACCOUNT_RESTRICTED"], ""),617    side(True, "`GET/POST /v1/billing/teams/{team_id}/postpaid/spending-limits`, prepaid balance / top-up (Management API); per-key `qps/qpm/tpm` caps", "POST /v1/billing/teams/{team_id}/postpaid/spending-limits", [], ["DOCUMENTED","ACCOUNT_RESTRICTED"], ""),618    side(False, "tier spend caps ($250 / $2,000 / $20k+) and rolling 10-minute spend limits ($10 / $50 / $200) are enforced by Google, not configurable via API (Cloud Billing budgets instead)", "", [], ["DOCUMENTED"], ""),619    True, "API-settable on three providers; platform-imposed on Gemini.", "endpoints.json (admin) · rate-limits.json (gemini)")620row(S, "Cloud availability",621    side(True, "Azure OpenAI / Microsoft Foundry (`AzureOpenAI` clients, Azure libraries); regional hosts `us.|eu.|au.|jp.|in.api.openai.com`", "", [], ["DOCUMENTED"], "Azure surface not catalogued in this atlas"),622    side(True, "Amazon Bedrock (Mantle `bedrock-mantle.{region}.api.aws/anthropic/v1/messages` and legacy InvokeModel), Google Cloud Vertex AI (`rawPredict`), Microsoft Foundry (`/anthropic/v1/*`), Claude Platform on AWS; feature gaps per platform (no Batches/Files/Skills/server tools on Bedrock/Vertex)", "", [], ["DOCUMENTED","UNVERIFIED"], "24 cloud endpoint records"),623    side(True, "Google Cloud **Vertex AI Model Garden** (partner model) and **Microsoft Foundry** (Azure) — OpenAI-compatible chat + Responses, cloud billing; also OpenRouter, Vercel AI Gateway, Cloudflare, Cursor; **regional first-party endpoints** `https://us.api.x.ai/v1` (US-pinned, grok-4.6, 1.1×) and `https://eu-west-1.api.x.ai/v1` (undocumented, grok-4.3, LIVE_DISCOVERED); clusters us-east-1, us-west-2, us-central-1, eu-west-1, us-saltlake-2", "", [], ["DOCUMENTED","LIVE_DISCOVERED"], ""),624    side(True, "Gemini Developer API (`generativelanguage.googleapis.com`, global, API key) **vs Vertex AI / Gemini Enterprise Agent Platform** (`{location}-aiplatform.googleapis.com`, IAM only, ~40 regions, data residency, ZDR, CMEK, VPC-SC, provisioned throughput, supervised tuning, RAG/Agent Engine); one SDK, two backends; Developer-API-only: Interactions, Live, Files, File Search, agents, free tier", "", [], ["DOCUMENTED"], "Vertex surface not catalogued in this atlas"),625    True, "Claude and Grok are resold on other clouds; OpenAI and Gemini have first-party cloud twins (Azure/Foundry, Vertex).", "docs/anthropic/cloud-providers.md · docs/openai/data-residency-and-regions.md · docs/xai/sdks.md · docs/gemini/vertex-vs-gemini-api.md")626row(S, "Data residency",627    side(True, "project region at creation; regional hosts `us./eu./au./jp./in.api.openai.com`; 10 % uplift for models ≥2026-03-05; EU lacks `background:true`", "", [], ["DOCUMENTED","ACCOUNT_RESTRICTED"], ""),628    side(True, "`inference_geo: us|global` per request (Claude 4.6+; 1.1× multiplier for `us`); workspace `default_inference_geo`; `usage.inference_geo` echo; Bedrock/Vertex regional endpoints +10 %", "POST /v1/messages", ["inference_geo"], ["DOCUMENTED","FAILED_VERIFICATION"], "400 on Haiku 4.5 live"),629    side(True, "base-URL choice: `https://us.api.x.ai/v1` keeps request handling, inference, moderation and retained data in the US at **1.1×** token prices (grok-4.6 only; no image/video/voice); global `api.x.ai` gives no region guarantee", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "`eu-west-1.api.x.ai` serves grok-4.3 at global prices (undocumented)"),630    side(False, "no residency option on the Developer API (global endpoint); residency, CMEK and ~40 regions are Vertex AI features", "", [], ["DOCUMENTED"], ""),631    True, "Regional pinning costs ~10 % on OpenAI, Anthropic and xAI alike; Gemini requires moving to Vertex.", "docs/anthropic/regions-and-ips.md · docs/openai/data-residency-and-regions.md · docs/xai/pricing.md · docs/gemini/vertex-vs-gemini-api.md")632row(S, "Zero data retention / data-use terms",633    side(True, "ZDR/Modified retention by approval; `store:false` keeps reasoning encrypted; Live recordings and Agents sessions excluded", "", ["store"], ["DOCUMENTED"], ""),634    side(True, "Messages stateless → ZDR-eligible on Claude API (per model flag `zero_data_retention_eligible`); not eligible: Files API, MCP connector, programmatic tool calling, Managed Agents, Fable 5.1 / Mythos 5.1", "", [], ["DOCUMENTED"], ""),635    side(True, "team-wide **ZDR toggle** (console): response header `x-zero-data-retention: true|false`, `GET /v1/me` → `zdr_status: no_zdr|zdr`; disables `store`, `previous_response_id`, Files, Collections, Batch, deferred completions, stored media; default retention 30 days, not used for training; encrypted reasoning replay keeps ZDR + caching", "", [], ["DOCUMENTED","LIVE_VERIFIED"], "our team: `no_zdr`"),636    side(True, "**Unpaid Services** (free tier): prompts/responses may be used to improve Google products, with human review; **Paid Services**: not used for training, 55-day abuse logging; ZDR **not achievable** on the Developer API (grounding stores 30 days; Interactions state unless `store:false`) — Vertex AI offers ZDR; EEA/UK/CH end-user apps must use Paid Services", "", ["store"], ["DOCUMENTED"], ""),637    True, "ZDR is a program (OpenAI), a per-model eligibility (Anthropic), a team switch (xAI) and unavailable on Gemini's Developer API.", "models.json (anthropic capabilities.zero_data_retention_eligible) · docs/xai/management-api.md · docs/gemini/authentication-headers-versions.md")638row(S, "OpenAI-compatibility layer",639    side(True, "the native surface (Responses + Chat Completions)", "POST /v1/chat/completions", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),640    side(False, "none — Anthropic exposes only its own Messages format (partners such as xAI implement it)", "", [], ["DOCUMENTED"], ""),641    side(True, "**native**: the whole inference API is OpenAI-shaped (`/v1/chat/completions`, `/v1/responses` incl. items and SSE events, `/v1/batches`, `/v1/files`, `/v1/images/*`, `/v1/realtime` events); rejected/ignored OpenAI fields: `background`, `metadata` (Responses 400), `logit_bias` 400, `stop`/penalties on reasoning models 400, `logprobs` ignored, `store` ignored on Chat, non-function tools 422, `images.edit()` multipart unsupported; extras: `reasoning_effort`, `reasoning_content`, `deferred`, `max_turns`, `top_k`, `min_p`, `cost_in_usd_ticks`", XR, [], ["DOCUMENTED","LIVE_VERIFIED"], "plus an Anthropic-compatible `/v1/messages` (deprecated)"),642    side(True, "`/v1beta/openai/*` (BETA): `chat/completions` (LIVE_VERIFIED), `embeddings`, `models[/{id}]`, `images/generations` (subset), `videos` (Sora-style Veo), `batches`; Bearer key required; `reasoning_effort` → `thinkingLevel` mapping; `extra_body.google {thinking_config, cached_content, safety_settings, tools[{google_search}]}`; `message.extra_content.google.thought_signature`; unknown params silently ignored; **no** Responses, Assistants, audio, files, fine-tuning, moderations", "POST /v1beta/openai/chat/completions", ["extra_body.google.thinking_config","extra_body.google.cached_content","reasoning_effort"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "7 endpoints; google.rpc error envelope"),643    True, "xAI is OpenAI-shaped by design; Gemini offers a partial adapter; Anthropic none.", "docs/xai/chat-completions.md · docs/xai/responses.md · docs/gemini/openai-compatibility.md")644645# ============================================================ Managed agents platforms646S = "Managed agents platforms"647row(S, "Managed agent harness",648    side(True, "Agents API (beta `OpenAI-Beta: agents=v1`): `POST /v1/agents` (model, instructions, reasoning, text, tools, multi_agent), sessions, turns, items, events, environments, templates, vaults; Codex harness; 34 + 9 endpoints", "POST /v1/agents", ["model","instructions","tools","multi_agent"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "gpt-5.4-nano rejected; gpt-5.6-luna accepted"),649    side(True, "Claude Managed Agents (beta `managed-agents-2026-04-01`): `POST /v1/agents` (name, model, system, tools, mcp_servers, skills, multiagent) with **versions**, `/v1/sessions` + events/stream, environments, deployments (cron), vaults, memory stores, dreams, tunnels, user profiles; 96 endpoints", "POST /v1/agents", ["name","model","system","tools","mcp_servers","skills","multiagent"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "Claude 4.5+ models"),650    side(True, "no agent resource: the **Responses API agentic loop** (server-side tools iterate inside one request, bounded by `max_turns`; stored responses + `previous_response_id` = the session); `grok-4.20-multi-agent-0309` (BETA) as a built-in multi-agent model; **Grok Build** (`grok-build-0.1` PREVIEW model + `grok` CLI BETA: TUI/headless/ACP, MCP, hooks, skills, subagents, sandbox) is a client-side harness", XR, ["tools","max_turns","store","previous_response_id"], ["DOCUMENTED","LIVE_VERIFIED","BETA"], "Skills API 404 for this team"),651    side(True, "**Interactions API** agents (`agent` instead of `model`): Deep Research (`deep-research-preview-04-2026`, `-max-`, `agent_config {collaborative_planning, thinking_summaries, visualization}`, background only, ≤60 min), Antigravity coding agent (`antigravity-preview-09-2026`, Linux sandbox 4 vCPU/16 GB, `agent_config {model, max_total_tokens}`, hooks), custom managed agents `POST /v1beta/agents {base_agent, agent_config, system_instruction, tools, base_environment}` (≤1,000/project, no versioning); environments, credentials, triggers (cron), webhooks", IX, ["agent","agent_config","environment","background"], ["DOCUMENTED","BETA","PREVIEW","LIVE_VERIFIED"], "Deep Research LIVE_VERIFIED (create → in_progress → cancel); custom agents / triggers / credentials not tested; sandbox compute unbilled in preview"),652    True, "Four different shapes: agent → session → events (OpenAI, Anthropic), a stateful request loop (xAI), agent-as-model inside Interactions (Gemini).", "docs/comparisons/agents-platforms.md · docs/xai/responses.md · docs/xai/grok-build.md · docs/gemini/interactions-api.md")653row(S, "Create an agent session / run",654    side(True, "`POST /v1/agents/sessions {agent|agent_id, environment (required: none|openai_hosted|self_hosted), input, stream, vault_ids}` → 201 `agent.session`", "POST /v1/agents/sessions", ["agent_id","environment","input","stream"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),655    side(True, "`POST /v1/sessions {agent, environment_id (required), initial_events[], resources[], vault_ids[], budget, title}` → 200 `session`", "POST /v1/sessions", ["agent","environment_id","initial_events","budget"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),656    side(True, "`POST /v1/responses {model, input, tools[], max_turns, store}` → the stored response is the session; continue with `previous_response_id`", XR, ["model","input","tools","max_turns"], ["DOCUMENTED","LIVE_VERIFIED"], ""),657    side(True, "`POST /v1beta/interactions {agent|model, input, background, store, environment, tools, webhook_config}` → `interaction {id, status, steps[]}`; chain with `previous_interaction_id`", IX, ["agent","input","background","previous_interaction_id"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "`/v1/interactions` GA UNVERIFIED"),658    True, "See FAQ Q5 for the body-level comparison.", "endpoints.json · docs/faq.md Q5")659row(S, "Send input / events to a session",660    side(True, "`POST /v1/agents/sessions/{id}/events` with `agent.session.input.message|tool_result|cancel` → 202", "POST /v1/agents/sessions/{session_id}/events", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),661    side(True, "`POST /v1/sessions/{id}/events` with `user.message|interrupt|tool_confirmation|custom_tool_result|tool_result|define_outcome`, `system.message`", "POST /v1/sessions/{session_id}/events", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),662    side(True, "a new `POST /v1/responses` with `previous_response_id` (user message or `function_call_output` / `shell_call_output` items)", XR, ["previous_response_id","input[](function_call_output)"], ["DOCUMENTED","LIVE_VERIFIED"], ""),663    side(True, "a new `POST /v1beta/interactions` with `previous_interaction_id` and `input` (user text or `function_result` steps); `POST …/cancel` to stop", IX, ["previous_interaction_id","input"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "`interaction.requires_action` for function calls"),664    True, "Dedicated event endpoints (OpenAI, Anthropic) vs chained requests (xAI, Gemini).", "streaming-events.json (client→server)")665row(S, "Session event stream",666    side(True, "SSE via `POST /sessions {stream:true}` or `GET …/events?stream=true`; 31 event types `agent.session.*`, `agent.output.*`", "GET /v1/agents/sessions/{session_id}/events", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),667    side(True, "`GET /v1/sessions/{id}/events/stream` (+ per-thread `/threads/{id}/stream`); 37 event types `agent.*`, `session.*`, `span.*`, `event_start/delta`", "GET /v1/sessions/{session_id}/events/stream", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),668    side(True, "the ordinary Responses SSE stream (24 recorded events incl. `response.code_interpreter_call.*`, `response.web_search_call.*`, `response.mcp_call.*`) or `wss://api.x.ai/v1/responses`", XR, ["stream"], ["DOCUMENTED","LIVE_VERIFIED"], ""),669    side(True, "Interactions SSE (`stream:true`): `interaction.created → interaction.status_update → step.start → step.delta {text|thought_signature|arguments_delta|function_result|*_call…} → step.stop → interaction.completed → done [DONE]`; resumable with `GET …?stream=true&last_event_id=`; 15 recorded events (5 legacy names RETIRED 2026-06-08)", IX, ["stream","last_event_id"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),670    True, "", "streaming-events.json")671row(S, "Hosted sandbox",672    side(True, "`environment.type: openai_hosted {packages, setup_commands, network, env, skills, plugins, files, environment_template_id}`; `/workspace`; artifacts from `/workspace/outputs`; ~1 h idle expiry; container rates", "POST /v1/agents/sessions", ["environment"], ["DOCUMENTED","BETA"], ""),673    side(True, "`POST /v1/environments {type: cloud, …}` (Ubuntu 24.04, 8 GB RAM, 10 GB disk, `/workspace`, `/mnt/session/{uploads,outputs}`, `/mnt/memory`); state kept 30 days; $0.08/session-hour", "POST /v1/environments", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),674    side(False, "no hosted sandbox for agents (the `code_interpreter` tool runs Python without a container object; Grok Build sandboxes locally)", XR, [], ["DOCUMENTED"], ""),675    side(True, "`POST /v1beta/environments {sources[] (repository ≤500 MB | gcs ≤2 GB | inline ≤1 MB/file), network (unrestricted|disabled|allowlist with credentials), from_environment}`; Antigravity sandbox 4 vCPU / 16 GB (Python 3.12, Node 22); files `GET …/files/{path}`, `PUT /upload/…/files/{path}`; idle after 15 min, deleted after 7 days; compute **unbilled during preview**", "POST /v1beta/environments", ["sources","network"], ["DOCUMENTED","BETA","PREVIEW","LIVE_VERIFIED"], "live GET showed `storage.tier: free`, 1 GiB project limit"),676    True, "Three hosted sandboxes (OpenAI, Anthropic, Gemini); none on xAI.", "docs/openai/agents-environments-and-vaults.md · docs/anthropic/managed-agents.md §8 · docs/gemini/interactions-api.md")677row(S, "Self-hosted execution",678    side(True, "`environment.type: self_hosted {workspace_directory}` + `codex exec-server --remote …` executor with environment key `CODEX_API_KEY`; outbound only", "POST /v1/agents/sessions", ["environment"], ["DOCUMENTED","BETA"], ""),679    side(True, "`type: self_hosted` environment = work queue (`/environments/{id}/work`, poll/ack/heartbeat/stop) + worker (`ant beta:worker`, SDK `EnvironmentWorker`) with environment key `sk-ant-oat01-…`", "GET /v1/environments/{environment_id}/work/poll", [], ["DOCUMENTED","BETA"], ""),680    side(True, "client-side by construction: `shell {environment: local}` and `function` tools end the server loop and hand control back; Grok Build CLI runs everything locally", XR, ["tools[type=shell].environment"], ["DOCUMENTED","LIVE_VERIFIED"], ""),681    side(False, "no self-hosted worker protocol; function calls (`interaction.requires_action`) are the only client-side hook", IX, [], ["DOCUMENTED"], ""),682    True, "Worker protocols on OpenAI/Anthropic; plain tool round-trips on xAI/Gemini.", "endpoints.json (managed-agents)")683row(S, "Credential vaults / secrets",684    side(True, "`/v1/vaults`, `/vaults/{id}/credentials` (rotate/delete); referenced by `vault_ids[]` and `mcp.credential_id`", "POST /v1/vaults", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "9 endpoints"),685    side(True, "`/v1/vaults`, `/vaults/{id}/credentials` (`mcp_oauth` with refresh, `environment_variable`), `mcp_oauth_validate`; `vault_credential.refresh_failed` webhook", "POST /v1/vaults", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "13 endpoints"),686    side(False, "pass `authorization` / `headers` on the `mcp` tool per request; no vault", XR, ["tools[type=mcp].authorization"], ["DOCUMENTED"], ""),687    side(True, "`/v1beta/credentials` (`bearer_token`, `oauth2`, `environment_variable` with `injection_location`, `trusted_domains`); write-only secrets; referenced from environment network allowlists", "POST /v1beta/credentials", [], ["DOCUMENTED","BETA","PREVIEW"], "5 endpoints, not tested"),688    True, "Three secret stores; xAI inlines credentials.", "endpoints.json")689row(S, "Multi-agent / subagents",690    side(True, "`multi_agent {enabled, max_concurrent_subagents (6)}`; `/sessions/{id}/subagents[/{id}/items|turns]`; items `create_subagent_call`, `wait_for_subagents_call`…; also Responses beta `responses_multi_agent=v1`", "GET /v1/agents/sessions/{session_id}/subagents", ["multi_agent"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),691    side(True, "`multiagent {type: coordinator, agents[] (≤20, incl. self and one advisor)}`; threads (`/sessions/{id}/threads`, ≤25 concurrent); events `agent.thread_message_*`", "GET /v1/sessions/{session_id}/threads", ["multiagent"], ["DOCUMENTED","BETA"], ""),692    side(True, "`grok-4.20-multi-agent-0309` (BETA): the model itself fans out to 4 or 16 agents per `reasoning.effort`; no subagent resources; Grok Build CLI has client-side subagents", XR, ["reasoning.effort"], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "live output carried `\\confidence{80}` markers"),693    side(False, "no sub-agents or delegation for custom agents (docs); Deep Research orchestrates internally", IX, [], ["DOCUMENTED"], ""),694    True, "Orchestration APIs on OpenAI/Anthropic; a multi-agent model on xAI; internal only on Gemini.", "docs/comparisons/agents-platforms.md · docs/models/xai-models.md")695row(S, "Session budgets",696    side(False, "no documented budget parameter; turn error code `session_budget_exceeded` exists", "", [], ["DOCUMENTED","UNVERIFIED"], ""),697    side(True, "`budget {type: limit, max_list_cost {amount (cents), currency: USD}}` enforced between model requests; `session.budget_reached` webhook", "POST /v1/sessions", ["budget"], ["DOCUMENTED","BETA"], ""),698    side(True, "`max_turns` per Responses request (turn budget)", XR, ["max_turns"], ["DOCUMENTED","LIVE_VERIFIED"], ""),699    side(True, "Antigravity `agent_config.max_total_tokens` → `status: incomplete`", IX, ["agent_config(antigravity).max_total_tokens"], ["DOCUMENTED","PREVIEW"], ""),700    False, "Money (Anthropic), turns (xAI), tokens (Gemini) — not interchangeable.", "docs/anthropic/managed-agents.md §13 · docs/xai/responses.md · docs/gemini/interactions-api.md")701row(S, "Outcome grading (define outcome + rubric)",702    NO,703    side(True, "`user.define_outcome` event → grader loop (`max_iterations` ≤20), `span.outcome_evaluation_*` events, `outcome_evaluations[]` on the session", "POST /v1/sessions/{session_id}/events", [], ["DOCUMENTED","BETA"], ""),704    NO, NO, False, "Anthropic-only.", "docs/anthropic/managed-agents.md §13")705row(S, "Server-side memory stores",706    NO,707    side(True, "`/v1/memory_stores` (+ memories, versions, redact); mounted at `/mnt/memory`; beta `agent-memory-2026-07-22`; Dreams (`/v1/dreams`, `dreaming-2026-04-21`) reorganise them", "POST /v1/memory_stores", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "14 + 5 endpoints"),708    NO, NO, False, "Anthropic-only.", "endpoints.json")709row(S, "Scheduled runs",710    NO,711    side(True, "`/v1/deployments` (cron) → `/v1/deployment_runs`; pause/unpause/run now", "POST /v1/deployments", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),712    NO,713    side(True, "`/v1beta/triggers {schedule (cron), time_zone, display_name, max_consecutive_failures, execution_timeout_seconds, interaction}`; `PATCH {status: paused|active}`; `POST|GET …/executions`", "POST /v1beta/triggers", ["schedule","time_zone","interaction"], ["DOCUMENTED","BETA","PREVIEW"], "7 endpoints, not tested"),714    True, "Anthropic deployments ≈ Gemini triggers.", "endpoints.json")715row(S, "Artifacts / deliverables",716    side(True, "`/sessions/{id}/artifacts[/{id}/content]` from `/workspace/outputs` (≤200 MiB each)", "GET /v1/agents/sessions/{session_id}/artifacts", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], ""),717    side(True, "files written to `/mnt/session/outputs` → `GET /v1/files?scope_id=<session>` + `/content`", "GET /v1/files", [], ["DOCUMENTED","BETA"], ""),718    side(False, "tool outputs (`code_interpreter_call.outputs`, image/video `file_output`) via `include` or the Files API; no artifact resource", XR, ["include"], ["DOCUMENTED"], ""),719    side(True, "environment files: `GET /v1beta/environments/{env}/files/{path}?alt=media` (file bytes or tar), legacy `GET /v1beta/files/environment-{env}:download`; Deep Research reports as `model_output` steps (text/image)", "GET /v1beta/environments/{environment}/files/{path}", [], ["DOCUMENTED","BETA","PREVIEW","LIVE_VERIFIED"], "partial 200 live"),720    True, "", "docs/openai/agents-environments-and-vaults.md §2 · docs/gemini/interactions-api.md")721row(S, "Embeddable chat UI & workspace agents",722    side(True, "ChatKit (`OpenAI-Beta: chatkit_beta=v1`, `/v1/chatkit/sessions|threads`) and Workspace Agents (`api.chatgpt.com/v1/workspace_agents/{id}/trigger`)", "POST /v1/chatkit/sessions", [], ["DOCUMENTED","BETA","LIVE_VERIFIED"], "Agent Builder shuts down 2026-11-30"),723    NO,724    side(False, "Grok Apps / Grok Bot integrations are consumer products, not an embeddable API (docs/xai/grok-apps-and-integrations.md)", "", [], ["DOCUMENTED"], ""),725    side(False, "AI Studio and Firebase AI Logic are builder/SDK surfaces, not an embeddable chat API", "", [], ["DOCUMENTED"], ""),726    False, "OpenAI-only.", "docs/openai/chatkit.md · docs/openai/workspace-agents.md")727row(S, "Client-side agent framework / CLI",728    side(True, "Agents SDK (`openai-agents`, `@openai/agents`) — loop over Responses API; handoffs, guardrails, tracing", "", [], ["DOCUMENTED"], ""),729    side(True, "Claude Agent SDK / `ant` CLI (`ant beta:sessions`, `ant apply`); SDK `tool_runner` helpers", "", [], ["DOCUMENTED"], "Claude Agent SDK not catalogued in this atlas beyond the migration mapping"),730    side(True, "**Grok Build CLI** (`curl -fsSL https://x.ai/cli/install.sh | bash`; `grok`, `grok -p … --output-format json`, `grok agent stdio` (ACP); `~/.grok/config.toml` `api_backend = chat_completions|responses|messages`; MCP servers, hooks, skills, plugins, subagents, Landlock/Seatbelt sandbox; reads CLAUDE.md/AGENTS.md) — BETA; xai-sdk `tool_runner`-style helpers absent", "", [], ["DOCUMENTED","BETA"], ""),731    side(True, "google-genai SDK automatic function calling (Python callables, `maximum_remote_calls` 10) and `mcpToTool()`; Genkit, Firebase AI Logic, Vercel AI SDK, LangGraph/CrewAI/LlamaIndex integrations; Antigravity is the hosted coding agent", "", [], ["DOCUMENTED","BETA"], ""),732    True, "", "docs/openai/agents-sdk.md · docs/anthropic/cli.md · docs/xai/grok-build.md · docs/gemini/sdks.md")733734# ============================================================ Model customisation & evaluation735S = "Model customisation & evaluation"736row(S, "Fine-tuning / tuning",737    side(True, "`/v1/fine_tuning/jobs` (SFT, DPO, RFT, vision) on gpt-4.1*, gpt-4o*, o4-mini — **DEPRECATED**: no new jobs after 2027-01-06; our key 403 `training_not_available`", "POST /v1/fine_tuning/jobs", ["model","training_file","method"], ["DOCUMENTED","DEPRECATED","ACCOUNT_RESTRICTED"], "no GPT-5.x/6 fine-tuning"),738    NO,739    side(False, "none offered by xAI (capability matrix row 'fine-tuning: none')", "", [], ["DOCUMENTED"], ""),740    side(False, "`tunedModels.*` (12 endpoints) still in the v1beta discovery document but **RETIRED** on the Developer API since the Gemini 1.5 Flash-001 deprecation (May 2025): create/list/get → 501 UNIMPLEMENTED; no tunable 3.x/2.x model; use Vertex AI supervised tuning", "POST /v1beta/tunedModels", [], ["DOCUMENTED","DEPRECATED","RETIRED"], "Gemma 4 `tuning: not available`"),741    False, "Only OpenAI still accepts jobs, and only until 2027-01-06.", "docs/openai/fine-tuning.md · docs/gemini/tuning.md · docs/models/xai-models.md")742row(S, "Evals",743    side(True, "`/v1/evals`, runs, output items; graders — **DEPRECATED**: read-only 2026-10-31, shutdown 2026-11-30", "POST /v1/evals", [], ["DOCUMENTED","DEPRECATED","LIVE_VERIFIED"], "12 endpoints"),744    NO, NO,745    side(False, "no evals API on the Developer API (Vertex AI evaluation service)", "", [], ["DOCUMENTED"], ""),746    False, "OpenAI-only (deprecated).", "docs/openai/evals.md")747row(S, "Graders (standalone)",748    side(True, "`/v1/fine_tuning/alpha/graders/{run,validate}`", "POST /v1/fine_tuning/alpha/graders/run", [], ["DOCUMENTED","DEPRECATED","BETA","LIVE_VERIFIED"], ""),749    NO, NO, NO, False, "OpenAI-only.", "docs/openai/graders.md")750row(S, "Stored completions / distillation",751    side(True, "Chat `store:true` + `metadata` → list/retrieve/update/delete stored completions; distillation via SFT", "GET /v1/chat/completions", ["store","metadata"], ["DOCUMENTED","LIVE_VERIFIED"], ""),752    NO,753    side(False, "Chat `store`/`metadata` silently accepted; no stored-completion retrieval endpoints (Responses store instead)", "POST /v1/chat/completions", ["store"], ["DOCUMENTED","LIVE_DISCOVERED"], ""),754    NO, False, "OpenAI-only.", "docs/openai/chat-completions.md · parameters.json (xai store)")755row(S, "Reusable prompt templates",756    side(True, "`prompt {id, version, variables}` on Responses — **DEPRECATED**, shutdown 2026-11-30", "POST /v1/responses", ["prompt"], ["DOCUMENTED","DEPRECATED"], ""),757    NO, NO,758    side(False, "no prompt registry on the API (AI Studio saves prompts client-side); `cachedContents` reuse a prefix", "", [], ["DOCUMENTED"], ""),759    False, "OpenAI-only (deprecated).", "docs/openai/deprecations.md")760761# ============================================================ Legacy / retired surfaces762S = "Legacy / retired surfaces"763row(S, "Retired agent / thread APIs",764    side(False, "Assistants API **RETIRED 2026-08-26** — 404 empty body; 23 operations mapped to Conversations/Responses/Agents", "GET /v1/assistants", [], ["RETIRED","DOCUMENTED"], "`OpenAI-Beta: assistants=v2` historical"),765    NO, NO,766    side(False, "Interactions v1beta legacy schema (`outputs` → `steps`, old SSE names `interaction.start`, `content.*`) removed 2026-06-08; `total_reasoning_tokens` → `total_thought_tokens`", IX, [], ["RETIRED","DOCUMENTED"], ""),767    False, "", "docs/openai/assistants-retired.md · docs/gemini/interactions-api.md")768row(S, "Retired media models / endpoints",769    side(False, "DALL·E 2/3 RETIRED 2026-05-12; `/v1/images/variations` 404; Sora 2 + Videos API shut down 2026-09-24", "POST /v1/images/variations", [], ["RETIRED","DEPRECATED"], ""),770    NO,771    side(False, "`grok-2-image(-1212)` RETIRED (404); `grok-imagine-image-pro` → `-quality` (DEPRECATED, retires 2026-11-02 → grok-imagine-image-2.0 low); Live Search 410", "POST /v1/images/generations", [], ["RETIRED","DEPRECATED"], ""),772    side(False, "Imagen 3/4 (`:predict`) RETIRED 2026-08-17; Veo 2.0/3.0 RETIRED 2026-06-30; `gemini-2.5-flash-image` DEPRECATED → 2026-10-02; `gemini-omni-flash-preview` → 2026-09-30; half-cascade Live models RETIRED 2025-12-09", "POST /v1beta/models/{model}:predict", [], ["RETIRED","DEPRECATED"], ""),773    False, "", "docs/openai/images.md · docs/xai/deprecations-and-release-notes.md · docs/gemini/deprecations-and-changelog.md")774row(S, "Retired text models",775    side(False, "gpt-3.5-turbo-instruct/babbage/davinci shut down 2026-09-28; o1/o3-mini/o4-mini/gpt-4/gpt-4-turbo 2026-10-23; gpt-5 2025 snapshots, o3 2026-12-11; codex ≤5.2, deep-research, computer-use-preview retired", "", [], ["DEPRECATED","RETIRED"], ""),776    side(False, "RETIRED on the Claude API: Opus 4.1 (2026-08-05), Sonnet 4 / Opus 4 (2026-06-15), Claude 3.x, 2.x, 1.x, Instant; some still served on Bedrock/Vertex", "POST /v1/messages", [], ["RETIRED"], "404 `not_found_error`"),777    side(False, "**RETIRED 2026-05-15 with redirects**: `grok-3`, `grok-4-0709`, `grok-4-fast-*`, `grok-4-1-fast-*` → `grok-4.3` (billed at 4.3 rates; `GET /v1/models/grok-3` returns the grok-4.3 object), `grok-code-fast-1` → `grok-build-0.1`; LEGACY/UNVERIFIED: `grok-2-*`, `grok-3-mini`, `grok-beta`, `grok-vision-beta`, `grok-4-latest`", "GET /v1/models/{model_id}", [], ["RETIRED","LEGACY"], "no consolidated deprecations page; ~60-day notice observed"),778    side(False, "Gemini 2.0 Flash/-Lite RETIRED 2026-06-01; 2.5 previews 2025-11/2026-03; `gemini-3-pro-preview` 2026-03-09 (id repointed to 3.1 Pro), `gemini-3.1-flash-lite-preview` 2026-05-25; **Gemini 2.5 Pro/Flash/Flash-Lite 'no longer available to new users'** (404, undocumented); `gemini-3.1-flash-lite` DEPRECATED → 2027-05-07; `gemini-embedding-001` → 2028-05-14; `text-embedding-004` 2026-01-14", GC, [], ["RETIRED","DEPRECATED","ACCOUNT_RESTRICTED"], "shut-down ids still appear in `GET /v1beta/models`"),779    False, "Retirement means 404 on Anthropic/Gemini, a dated shutdown on OpenAI, and a **silent redirect** on xAI.", "deprecations.json · models.json")780row(S, "Retired / deprecated beta headers, parameters and SDKs",781    side(True, "`OpenAI-Beta: realtime=v1` (legacy `/v1/realtime/sessions` → 404), `assistants=v2`; `prompt_cache_retention`, `truncation: auto`, `user` (→ `safety_identifier`) legacy", "", [], ["LEGACY","FAILED_VERIFICATION"], ""),782    side(True, "RETIRED: `context-1m-2025-08-07`, `computer-use-2024-10-22`, `max-tokens-3-5-sonnet-2024-07-15`; DEPRECATED: `mcp-client-2025-04-04`; LEGACY (GA, header optional): prompt-caching, message-batches, pdfs, token-counting, files-api, skills, structured-outputs, extended-cache-ttl, code-execution-2025-05-22, interleaved/fine-grained streaming, effort-2025-11-24…", "", [], ["RETIRED","DEPRECATED","LEGACY"], ""),783    side(True, "no headers to retire; DEPRECATED params/features: `max_tokens` (→ `max_completion_tokens`), `logprobs`/`top_logprobs` (ignored ≥4.20), Anthropic-compatible `/v1/messages`, `x_search` per-call billing (→ 2026-09-21), `zdr_status: pii_scrubbing`, Management `teamId` (→ `scope`/`scopeId`); LEGACY: `/v1/completions`, `/v1/complete`, Live Search", "", [], ["DEPRECATED","LEGACY","RETIRED"], ""),784    side(True, "DEPRECATED: `temperature/topP/topK` guidance (2026-07-21), `thinkingBudget` (LEGACY on 3.x), `HARM_CATEGORY_CIVIC_INTEGRITY` (→ `enableEnhancedCivicAnswers`), `googleSearchRetrieval`, **standard API keys** (rejected from Sept 2026), legacy SDKs `google-generativeai` / `@google/generative-ai` (2025-11-30); LEGACY: PaLM methods, `responseSchema`/`responseJsonSchema` (→ `responseFormat`), `mediaChunks`, `speechState`", "", [], ["DEPRECATED","LEGACY"], ""),785    False, "", "generated/fragments/headers/anthropic-beta-headers.json · deprecations.json (xai, gemini api_features)")786787# ============================================================ xAI-specific billing / lifecycle mechanics (kept in their thematic sections)788S = "Service tiers, limits, safety"789row(S, "Per-request dollar cost in the response",790    side(False, "token counts only (`usage`); costs via the Admin `GET /v1/organization/costs` report", "", [], ["DOCUMENTED"], ""),791    side(False, "token counts only; costs via `/v1/organizations/cost_report`", "", [], ["DOCUMENTED"], ""),792    side(True, "`usage.cost_in_usd_ticks` on **every** inference response (Chat, Responses, images, videos; 1 USD = 10^10 ticks; April 2026) — the effective price after cache, long-context, priority and regional multipliers; batch `cost_breakdown` (SDK/gRPC)", XR, ["usage.cost_in_usd_ticks"], ["DOCUMENTED","LIVE_VERIFIED"], "catalogue endpoints return no usage/cost"),793    side(False, "token counts only (`usageMetadata`, Interactions `usage`); costs in Google Cloud Billing", GC, [], ["DOCUMENTED"], ""),794    False, "xAI-only.", "docs/xai/pricing.md · docs/xai/responses.md")795S = "Legacy / retired surfaces"796row(S, "Retired model ids keep resolving (redirect aliases)",797    side(False, "retired ids fail with `model_not_found`; `shutdown_date` exposed on `GET /v1/models`", "GET /v1/models/{model}", [], ["DOCUMENTED","LIVE_VERIFIED"], ""),798    side(False, "retired ids → 404 `not_found_error` (some still served on Bedrock/Vertex)", "POST /v1/messages", [], ["DOCUMENTED"], ""),799    side(True, "retired slugs **redirect** to their replacement and are billed at the replacement's price: `grok-3`, `grok-4-0709`, `grok-4-fast-*`, `grok-4-1-fast-*` → `grok-4.3` (verified: `GET /v1/models/grok-3` returns the grok-4.3 object), `grok-code-fast-1` → `grok-build-0.1`, `grok-imagine-image-pro` → `-quality` → `-2.0 low`; `response.model` reveals the target", "GET /v1/models/{model_id}", [], ["DOCUMENTED","RETIRED","LIVE_VERIFIED"], "6 `retired_redirect` records in models.json"),800    side(False, "shut-down ids stay **listed** in `GET /v1beta/models` but generation fails (404); one documented repoint: `gemini-3-pro-preview` → `gemini-3.1-pro-preview` (2026-03-09); `-latest` aliases hot-swap targets", "GET /v1beta/models", [], ["DOCUMENTED","LIVE_DISCOVERED"], ""),801    False, "xAI-only behaviour (silent redirect); Gemini has one documented id repoint.", "deprecations.json (xai) · docs/xai/deprecations-and-release-notes.md")802803# ---------------------------------------------------------------- render804def esc(s):805    return str(s).replace("|", "\\|").replace("\n", " ")806807def cell(sd):808    if not sd["supported"] and sd["how"] == "not offered":809        return "— not offered" + (f"<br>*{esc(sd['notes'])}*" if sd["notes"] and sd["notes"] != NO["notes"] else "")810    parts = [esc(sd["how"])]811    if sd["endpoint"]:812        parts.append(f"**Endpoint:** `{esc(sd['endpoint'])}`")813    if sd["params"]:814        parts.append("**Params:** " + ", ".join(f"`{esc(p)}`" for p in sd["params"]))815    if sd["status"]:816        parts.append("**Status:** " + " · ".join(f"`{s}`" for s in sd["status"]))817    if sd["notes"]:818        parts.append(f"*{esc(sd['notes'])}*")819    return "<br>".join(parts)820821sections = []822for r in ROWS:823    if r["section"] not in sections: sections.append(r["section"])824by_count = {n: [r for r in ROWS if r["provider_count"] == n] for n in range(0, 5)}825unique = {p: [r for r in ROWS if r["providers_supporting"] == [p]] for p in PROVIDERS}826combos = {}827for r in ROWS:828    if r["provider_count"] in (2, 3):829        combos.setdefault("+".join(r["providers_supporting"]), []).append(r["feature"])830portable_n = sum(1 for r in ROWS if r["portable"])831832md = []833md.append("# Feature × Provider matrix — OpenAI · Anthropic · xAI · Gemini\n")834md.append(f"**Status:** synthesis of `generated/*.json` (endpoints, parameters, tools, models, headers, pricing, streaming-events, webhook-events, deprecations) and the domain pages under `docs/`; every status shown is the status recorded in those files (`LIVE_VERIFIED` means called successfully with this atlas's keys on {TODAY}; xAI probes ran on a Tier 0 team, Gemini probes on a free-tier key — hence `ACCOUNT_RESTRICTED` on paid-only Gemini features and on xAI's Management/Skills/Embeddings). Machine-readable twin: `generated/compatibility/cross-provider-feature-matrix.json` (same rows, `openai`/`anthropic`/`xai`/`gemini` objects per record, `providers_supporting[]`, `provider_count`).")835md.append("**Sources:** the `ref` column of the JSON twin names, per row, the generated file or docs page each cell was taken from. Canonical vendor pages: https://developers.openai.com/api/docs · https://platform.claude.com/docs/en · https://docs.x.ai/developers · https://ai.google.dev/gemini-api/docs.")836md.append(f"**Last verified:** {TODAY}\n")837md.append("Legend — **Portable** = the same task can be expressed with an equivalent parameter on **every provider that offers it** (mapping in the per-topic pages; a feature offered by one provider only is never portable); “— not offered” = no documented surface. Statuses use the atlas vocabulary (`DOCUMENTED`, `LIVE_VERIFIED`, `LIVE_DISCOVERED`, `BETA`, `PREVIEW`, `GA`, `LEGACY`, `DEPRECATED`, `RETIRED`, `ACCOUNT_RESTRICTED`, `UNVERIFIED`, `FAILED_VERIFICATION`, `DOCUMENTATION_INCOMPLETE`).\n")838md.append("## Contents\n")839for i, s in enumerate(sections, 1):840    n = sum(1 for r in ROWS if r["section"] == s)841    anchor = s.lower().replace(' ', '-').replace('/', '').replace(',', '').replace('&', '').replace('—','').replace('--','-')842    md.append(f"{i}. [{s}](#{anchor}) ({n} rows)")843md.append(f"\n**Totals:** {len(ROWS)} features — on all four providers: {len(by_count[4])} · on three: {len(by_count[3])} · on two: {len(by_count[2])} · on one: {len(by_count[1])} · on none (legacy/absent everywhere): {len(by_count[0])} · marked portable: {portable_n}.\n")844md.append("| Coverage | Count | Features |\n|---|---|---|")845md.append(f"| All four | {len(by_count[4])} | " + "; ".join(esc(r['feature']) for r in by_count[4]) + " |")846for k, feats in sorted(combos.items(), key=lambda kv: (-len(kv[0].split('+')), kv[0])):847    md.append(f"| {k.replace('+', ' + ')} | {len(feats)} | " + "; ".join(esc(f) for f in feats) + " |")848for p in PROVIDERS:849    md.append(f"| {LABEL[p]} only | {len(unique[p])} | " + "; ".join(esc(r['feature']) for r in unique[p]) + " |")850md.append(f"| None | {len(by_count[0])} | " + "; ".join(esc(r['feature']) for r in by_count[0]) + " |")851852for s in sections:853    md.append(f"\n## {s}\n")854    md.append("| Feature | OpenAI (how / endpoint / params / status) | Anthropic | xAI | Gemini | Portable | Notes on differences |")855    md.append("|---|---|---|---|---|---|---|")856    for r in ROWS:857        if r["section"] != s: continue858        md.append(f"| **{esc(r['feature'])}**<br>*{r['provider_count']}/4* | {cell(r['openai'])} | {cell(r['anthropic'])} | {cell(r['xai'])} | {cell(r['gemini'])} | {'yes' if r['portable'] else 'no'} | {esc(r['notes'])}<br>*Ref:* {esc(r['ref'])} |")859860md.append("\n## Reading the matrix programmatically\n")861md.append("```bash\n# all features unique to xAI\njq '[.records[] | select(.providers_supporting == [\"xai\"]) | .feature]' generated/compatibility/cross-provider-feature-matrix.json\n# features on all four providers that are marked portable\njq '[.records[] | select(.provider_count == 4 and .portable) | .feature]' generated/compatibility/cross-provider-feature-matrix.json\n# every Gemini cell that is ACCOUNT_RESTRICTED (paid-tier feature probed with a free key)\njq '[.records[] | select(.gemini.status|index(\"ACCOUNT_RESTRICTED\")) | {feature, endpoint: .gemini.endpoint}]' generated/compatibility/cross-provider-feature-matrix.json\n# every beta-gated Anthropic cell\njq '[.records[] | select(.anthropic.status|index(\"BETA\")) | {feature, endpoint: .anthropic.endpoint}]' generated/compatibility/cross-provider-feature-matrix.json\n```\n")862md.append("Related pages: [index](index.md) · [models](models.md) · [state management](state-management.md) · [tool execution](tool-execution.md) · [streaming](streaming.md) · [agents platforms](agents-platforms.md) · [pricing](pricing.md) · [caching and reasoning](caching-and-reasoning.md) · [realtime and media](realtime-and-media.md) · [endpoint catalogue](../endpoints/index.md) · [FAQ](../faq.md).\n")863864open(f"{ROOT}/docs/comparisons/features.md", "w").write("\n".join(md))865866out = {867    "record_type": "cross_provider_feature_matrix",868    "generated_at": TODAY,869    "providers": PROVIDERS,870    "description": "Feature-by-feature comparison of the OpenAI, Anthropic, xAI and Gemini public APIs. Each provider object: supported (bool), how (free text), endpoint (canonical METHOD /path or empty), params (parameter paths as used in generated/parameters.json), status (atlas status vocabulary), notes. providers_supporting = providers with supported=true; portable = the same task is expressible on every provider that offers it (never true for single-provider features). ref = generated file / docs page the row was derived from.",871    "status_vocabulary": ["DOCUMENTED","LIVE_DISCOVERED","LIVE_VERIFIED","BETA","PREVIEW","GA","LEGACY","DEPRECATED","RETIRED","ACCOUNT_RESTRICTED","UNVERIFIED","FAILED_VERIFICATION","DOCUMENTATION_INCOMPLETE"],872    "human_twin": "docs/comparisons/features.md",873    "counts": {"features": len(ROWS), "on_all_four": len(by_count[4]), "on_three": len(by_count[3]), "on_two": len(by_count[2]), "on_one": len(by_count[1]), "on_none": len(by_count[0]), "portable": portable_n,874               "unique": {p: [r["feature"] for r in unique[p]] for p in PROVIDERS},875               "combinations": combos,876               "per_provider_supported": {p: sum(1 for r in ROWS if r[p]["supported"]) for p in PROVIDERS}},877    "records": ROWS,878}879json.dump(out, open(f"{ROOT}/generated/compatibility/cross-provider-feature-matrix.json", "w"), indent=1, ensure_ascii=False)880print("rows", len(ROWS), "four", len(by_count[4]), "three", len(by_count[3]), "two", len(by_count[2]), "one", len(by_count[1]), "none", len(by_count[0]), "portable", portable_n)881print("unique", {p: len(unique[p]) for p in PROVIDERS})882print("per_provider", out["counts"]["per_provider_supported"])883