Python 88.3%
TypeScript 7.6%
Shell 4.1%
1#!/usr/bin/env python32"""Hand-written xAI fragments: endpoints/xai-inference.json, tools/xai-tools.json, streaming-events/xai-inference.json."""3from __future__ import annotations4import json5from pathlib import Path6ROOT = Path(__file__).resolve().parents[2]7T = "2026-09-19"8D = "https://docs.x.ai/developers/"9REF = D + "rest-api-reference/"10SPEC = "https://docs.x.ai/openapi.json"11LV = ["DOCUMENTED", "LIVE_VERIFIED"]12def src(*urls):13 return [{"url": u, "retrieved_at": T} for u in urls]14def ver(result, status, note, method="live_api"):15 return {"method": method, "verified_at": T, "result": result, "http_status": status, "request_note": note}16def ep(api, method, path, name, desc, status, req=None, resp=None, stream=None, pag=None, sdk=None, verification=None, sources=None, **kw):17 r = {"provider": "xai", "api_family": api, "method": method, "path": path, "name": name, "description": desc, "status": status,18 "auth": "Authorization: Bearer <XAI_API_KEY> (inference API key; no version header)", "beta_header": None,19 "request": req or {"content_type": None, "body_ref": None}, "response": resp or {"content_type": "application/json", "schema_ref": None},20 "streaming": stream or {"supported": False, "events_ref": None}, "pagination": pag, "idempotency": "Not idempotent (POST) / idempotent (GET, DELETE)",21 "sdk": sdk or {"python": None, "node": None, "xai_sdk_python": None}, "verification": verification, "sources": sources or src(SPEC)}22 r.update(kw); return r23OAI = "https://api.x.ai/v1 via the OpenAI SDKs (base_url=https://api.x.ai/v1); no official xAI Node SDK"24E = []25CHAT = REF + "inference/chat-completions"26E.append(ep("chat_completions", "POST", "/v1/chat/completions", "Chat Completions: create", "Stateless OpenAI-compatible chat. xAI calls it the legacy predecessor of /v1/responses (new features land on Responses first). Supports deferred:true (returns request_id), reasoning_effort, response_format json_schema/json_object, function tools (only `function` and retired `live_search` tool types deserialize), n, seed, service_tier priority, prompt_cache_key/x-grok-conv-id caching, image_url parts. Live Search (search_parameters / web_search_options / live_search tool) → 410 RETIRED. File parts → 400 (use /v1/responses).",27 ["DOCUMENTED", "LEGACY", "LIVE_VERIFIED"], {"content_type": "application/json", "body_ref": "ChatRequest (parameters/xai-chat-completions.json)"}, {"content_type": "application/json", "schema_ref": "ChatResponse | StartDeferredChatResponse (deferred:true)"},28 {"supported": True, "events_ref": "streaming-events/xai-inference.json (chat.completion.chunk)", "transport": "data-only SSE, `data: [DONE]` terminator, no event: names"},29 None, {"python": "openai.OpenAI(base_url='https://api.x.ai/v1').chat.completions.create(...)", "node": "new OpenAI({baseURL:'https://api.x.ai/v1'}).chat.completions.create(...)", "xai_sdk_python": "client.chat.create(model=…) → chat.append(user(…)) → chat.sample() / chat.stream() / chat.defer() (gRPC, not this REST path)"},30 ver("success", 200, "grok-4.3 'Reply with OK.' max_completion_tokens=32 → 'OK.' with reasoning_content, 133 reasoning tokens, cached_tokens 192; stream, json_schema, tools (forced/parallel/round-trip/stream), image_url, deferred, n=2, seed, service_tier=priority, prompt caching all 200; logit_bias 400; presence_penalty 400 on grok-4.3; search_parameters/web_search_options 410"),31 src(CHAT, D + "model-capabilities/legacy/chat-completions", SPEC), rate_limit_headers_observed=["x-ratelimit-limit-requests", "x-ratelimit-remaining-requests", "x-ratelimit-limit-tokens", "x-ratelimit-remaining-tokens", "x-request-id"]))32E.append(ep("chat_completions", "GET", "/v1/chat/deferred-completion/{request_id}", "Chat Completions: fetch deferred result", "Poll a deferred chat completion. 202 with empty body while pending, 200 ChatResponse when done. Docs: result available exactly once within 24 h — live it was fetchable twice.", LV, None, {"content_type": "application/json", "schema_ref": "ChatResponse"}, None, None,33 {"python": "openai SDK: client.get('/chat/deferred-completion/{id}', cast_to=…) (no dedicated method)", "node": None, "xai_sdk_python": "chat.defer(timeout=…, interval=…)"},34 ver("success", 200, "first poll 202 (0 bytes), second poll 2 s later 200 'OK.'; third GET also 200"), src(CHAT, D + "advanced-api-usage/deferred-chat-completions")))35RESP = REF + "inference/responses"36E.append(ep("responses", "POST", "/v1/responses", "Responses: create", "Primary xAI text/agentic endpoint (OpenAI Responses-compatible). Stateful by default (store=true, 30-day retention), previous_response_id chaining, include reasoning.encrypted_content for stateless replay, server-side tools (web_search, x_search, code_interpreter/code_execution, file_search/collections_search, mcp, image_generation, shell; tool_search alpha), input_image / input_file attachments, text.format json_schema, reasoning {effort, summary}, max_turns, top_k/min_p. background/metadata → 400; instructions+previous_response_id → 400.",37 LV, {"content_type": "application/json", "body_ref": "ModelRequest (parameters/xai-responses.json)"}, {"content_type": "application/json", "schema_ref": "ModelResponse (objects: Response)"},38 {"supported": True, "events_ref": "streaming-events/xai-inference.json (responses.*)", "transport": "SSE with `event:` name == data.type and sequence_number; ends with response.completed (no [DONE] observed)"}, None,39 {"python": "client.responses.create / .stream / .parse / .retrieve / .delete / .input_items.list / .compact (openai SDK)", "node": "client.responses.create(...) etc.", "xai_sdk_python": "client.chat.create(model, store_messages=True|False, previous_response_id=…, use_encrypted_content=True, tools=[web_search(), …]) (gRPC)"},40 ver("success", 200, "grok-4.3 minimal → output [reasoning, message], usage 196/98 (96 reasoning), cached 192; stream 10 events; previous_response_id; store=false; include encrypted reasoning + replay; json_schema; function_call + function_call_output; input_image; input_file(file_id) → 'PINEAPPLE'; web_search/x_search/code_interpreter/mcp/file_search tool calls; compaction item replay"),41 src(RESP, D + "model-capabilities/text/generate-text", D + "tools/overview", SPEC), rate_limit_headers_observed=["x-ratelimit-limit-requests", "x-ratelimit-remaining-requests", "x-ratelimit-limit-tokens", "x-ratelimit-remaining-tokens", "x-request-id"]))42E.append(ep("responses", "GET", "/v1/responses/{response_id}", "Responses: retrieve", "Retrieve a stored response (30 days). LIVE_DISCOVERED: a response created with store=false was still retrievable (200) seconds later.", ["DOCUMENTED", "LIVE_VERIFIED", "LIVE_DISCOVERED"], None, {"content_type": "application/json", "schema_ref": "ModelResponse"}, None, None, {"python": "client.responses.retrieve(id)", "node": "client.responses.retrieve(id)", "xai_sdk_python": "client.chat.get_stored_completion(id)"}, ver("success", 200, "GET stored id → 200 (completed_at updated); after DELETE → 404; store=false id → 200"), src(RESP)))43E.append(ep("responses", "DELETE", "/v1/responses/{response_id}", "Responses: delete", "Delete a stored response → {id, object:'response', deleted:true}.", LV, None, {"content_type": "application/json", "schema_ref": "DeleteStoredCompletionResponse"}, None, None, {"python": "client.responses.delete(id)", "node": "client.responses.delete(id)", "xai_sdk_python": "client.chat.delete_stored_completion(id)"}, ver("success", 200, "deleted:true; subsequent GET 404"), src(RESP)))44E.append(ep("responses", "GET", "/v1/responses/{response_id}/input_items", "Responses: list input items", "List the stored input items of a response (limit 1-100 default 20, order asc|desc, after cursor). Not in the REST reference page; present in the OpenAPI spec.", LV, None, {"content_type": "application/json", "schema_ref": "ListInputItemsResponse"}, None, {"style": "cursor", "params": ["limit", "order", "after"], "fields": ["first_id", "last_id", "has_more"]}, {"python": "client.responses.input_items.list(id)", "node": "client.responses.inputItems.list(id)", "xai_sdk_python": None}, ver("success", 200, "{object:'list', data:[{content:'Reply with OK.', role:'user', type:'message', id:'item_0'}], has_more:false}"), src(SPEC)))45E.append(ep("responses", "POST", "/v1/responses/compact", "Responses: compact context", "Compact a full input window into one opaque `compaction` item (encrypted_content) to pass at the head of the next /v1/responses input. Returns object 'response.compaction' with usage.dropped_message_count.", LV, {"content_type": "application/json", "body_ref": "CompactRequest"}, {"content_type": "application/json", "schema_ref": "CompactResponse"}, None, None, {"python": "client.responses.compact(model=…, input=[…])", "node": "client.responses.compact({...})", "xai_sdk_python": "client.chat.compact_context(model, messages) / chat.compact()"}, ver("success", 200, "5-message conversation → cmp_… item, dropped_message_count 3, 138 output tokens (711 reasoning); follow-up response recalled 'A and B'"), src(RESP, D + "advanced-api-usage/context-compaction")))46LEG = REF + "inference/legacy"47E.append(ep("messages_compat", "POST", "/v1/messages", "Messages (Anthropic-compatible) — DEPRECATED", "Anthropic Messages-shaped endpoint (Bearer auth, no anthropic-version needed). Docs: 'Anthropic SDK compatibility is fully deprecated'. Live: still works with grok-4.3: text/thinking/tool_use blocks, tools with input_schema, tool_choice auto|any|tool, image blocks (url + base64), system string/array, streaming with Anthropic event names incl. thinking_delta. Rejected: top_k (400), stop_sequences on reasoning models (400), document blocks (422), tool_choice.disable_parallel_tool_use (400), Anthropic server tools (422). `thinking` param silently ignored.",48 ["DOCUMENTED", "DEPRECATED", "LIVE_VERIFIED"], {"content_type": "application/json", "body_ref": "MessageRequest (parameters/xai-messages-compat.json)"}, {"content_type": "application/json", "schema_ref": "MessageResponse"}, {"supported": True, "events_ref": "streaming-events/xai-inference.json (messages_compat)", "transport": "SSE with Anthropic event names (message_start … message_stop); no [DONE]"}, None,49 {"python": "anthropic.Anthropic(base_url='https://api.x.ai', api_key=XAI_API_KEY).messages.create(...) — unofficial; xAI recommends migrating", "node": "new Anthropic({baseURL:'https://api.x.ai'})", "xai_sdk_python": None},50 ver("success", 200, "minimal 'OK.' (usage input 4 + cache_read 192, output 86 incl. reasoning); forced tool_use + tool_result round trip; stream 11 events; /v1/messages/count_tokens → 404"), src(LEG, SPEC)))51E.append(ep("legacy", "POST", "/v1/complete", "Legacy Text Completions (Anthropic-compatible) — RETIRED in practice", "(Legacy) Anthropic /v1/complete shape. Live: every text model available to this key (incl. grok-4.20-0309-non-reasoning) → 400 'Raw sampling is not supported for reasoning models'.", ["DOCUMENTED", "LEGACY", "DEPRECATED", "RETIRED"], {"content_type": "application/json", "body_ref": "CompleteRequest"}, {"content_type": "application/json", "schema_ref": "CompleteResponse"}, None, None, None, ver("failure", 400, "grok-4.3 and grok-4.20-0309-non-reasoning → 400 invalid-argument 'Raw sampling is not supported for reasoning models'"), src(LEG, SPEC)))52E.append(ep("legacy", "POST", "/v1/completions", "Legacy Completions (OpenAI-compatible) — RETIRED in practice", "(Legacy) OpenAI /v1/completions shape, 'replaced by /v1/chat/completions'. Live: 400 'Raw sampling is not supported for reasoning models' on both live text models — no model on this key can use it.", ["DOCUMENTED", "LEGACY", "RETIRED"], {"content_type": "application/json", "body_ref": "SampleRequest"}, {"content_type": "application/json", "schema_ref": "SampleResponse"}, {"supported": True, "events_ref": None, "transport": "documented data-only SSE"}, None, {"python": "client.completions.create(...) (openai SDK)", "node": "client.completions.create(...)", "xai_sdk_python": None}, ver("failure", 400, "same 400 for grok-4.3 and grok-4.20-0309-non-reasoning"), src(LEG, SPEC)))53E.append(ep("embeddings", "POST", "/v1/embeddings", "Embeddings: create", "OpenAI-compatible embeddings. No embedding model is exposed to this key (GET /v1/embedding-models → {models: []}); POST → 404 not-found.", ["DOCUMENTED", "ACCOUNT_RESTRICTED"], {"content_type": "application/json", "body_ref": "EmbeddingRequest"}, {"content_type": "application/json", "schema_ref": "EmbeddingResponse"}, None, None, {"python": "client.embeddings.create(...)", "node": "client.embeddings.create(...)", "xai_sdk_python": None}, ver("restricted", 404, "model grok-embedding-small → 404 'does not exist or your team … does not have access'"), src(SPEC, REF + "inference/other")))54E.append(ep("embeddings", "GET", "/v1/embedding-models", "Embedding models: list", "List embedding models with pricing/modalities. Live: empty list.", LV, None, {"content_type": "application/json", "schema_ref": "ListEmbeddingModelsResponse"}, None, None, None, ver("success", 200, "{models: []}"), src(SPEC)))55OTH = REF + "inference/other"56E.append(ep("account", "POST", "/v1/tokenize-text", "Tokenize text", "Tokenize text with a model's tokenizer → token_ids[] {token_id, string_token, token_bytes}.", LV, {"content_type": "application/json", "body_ref": "TokenizeRequest"}, {"content_type": "application/json", "schema_ref": "TokenizeResponse"}, None, None, {"python": None, "node": None, "xai_sdk_python": "client.tokenize.tokenize_text(text, model)"}, ver("success", 200, "'Hello world!' grok-4.3 → 3 tokens"), src(OTH, SPEC)))57E.append(ep("account", "GET", "/v1/api-key", "API key info", "Introspect the calling API key (acls, team_id, blocked/disabled flags).", LV, None, {"content_type": "application/json", "schema_ref": "ApiKey"}, None, None, {"python": None, "node": None, "xai_sdk_python": "client.auth.get_api_key_info()"}, ver("success", 200, "acls ['api-key:model:*','api-key:endpoint:*']; create_time/modify_time empty strings"), src(OTH, SPEC)))58F = REF + "files/"59E.append(ep("files", "POST", "/v1/files", "Files: upload", "Multipart upload (file, optional purpose, expires_after 3600-2592000 s which must precede the file part). Max 50 MB (spec) / 512 MB (guide). Returns File.", LV, {"content_type": "multipart/form-data", "body_ref": "UploadFileMultipartRequest"}, {"content_type": "application/json", "schema_ref": "File"}, None, None, {"python": "client.files.create(file=…, purpose='assistants', expires_after={anchor:'created_at', seconds:N})", "node": "client.files.create({file, purpose, expires_after})", "xai_sdk_python": "client.files.upload(path|bytes|fileobj, filename=…, expires_after=…)"}, ver("success", 200, "200-byte text/plain with expires_after=3600 → id file_…, expires_at=created_at+3600, purpose '' (input 'assistants' not echoed); 95-byte PNG too"), src(F + "upload", D + "files/managing-files", SPEC)))60E.append(ep("files", "GET", "/v1/files", "Files: list", "List team files: limit (≤100), order, sort_by, pagination_token, filter (AIP-160), after (compat).", LV, None, {"content_type": "application/json", "schema_ref": "ListFilesResponse"}, None, {"style": "token", "params": ["limit", "pagination_token"], "end_condition": "page shorter than limit / pagination_token null"}, {"python": "client.files.list()", "node": "client.files.list()", "xai_sdk_python": "client.files.list(limit, order, sort_by, pagination_token, filter)"}, ver("success", 200, "limit=2 → 1 file, pagination_token null; filter=public_url != null → 1"), src(F + "manage")))61E.append(ep("files", "GET", "/v1/files/{file_id}", "Files: retrieve metadata", "File metadata; 404 {code:'not-found', error:'File not found'} after delete/expiry.", LV, None, {"content_type": "application/json", "schema_ref": "File"}, None, None, {"python": "client.files.retrieve(id)", "node": "client.files.retrieve(id)", "xai_sdk_python": "client.files.get(id)"}, ver("success", 200, "200 then 404 after delete"), src(F + "manage")))62E.append(ep("files", "DELETE", "/v1/files/{file_id}", "Files: delete", "Delete → {id, deleted:true, object:'file'}.", LV, None, {"content_type": "application/json", "schema_ref": "DeleteFileResponse"}, None, None, {"python": "client.files.delete(id)", "node": "client.files.delete(id)", "xai_sdk_python": "client.files.delete(id)"}, ver("success", 200, "deleted:true"), src(F + "manage")))63E.append(ep("files", "GET", "/v1/files/{file_id}/content", "Files: download content", "Raw bytes (application/octet-stream). ?format=text documented; live on a text/plain file → 404 {error:'Failed to retrieve file'}.", ["DOCUMENTED", "LIVE_VERIFIED"], None, {"content_type": "application/octet-stream", "schema_ref": None}, None, None, {"python": "client.files.content(id)", "node": "client.files.content(id)", "xai_sdk_python": "client.files.content(id)"}, ver("success", 200, "200 bytes identical to upload; format=text → 404"), src(F + "download")))64PU = D + "files/public-urls"65E.append(ep("files", "POST", "/v1/files/{file_id}/public-url", "Files: create public URL", "Permanent unauthenticated CDN URL (https://files-cdn.x.ai/<token>/<file_id>.<ext>). Only png/jpeg/gif/webp/mp4/webm/pdf (text/plain → 400). Idempotent: repeat call returns the same URL and updates expiry. expires_after may not exceed the file's remaining TTL (400). ≤1000 active URLs/team.", LV, {"content_type": "application/json", "body_ref": "CreatePublicUrlRequest ({} allowed)"}, {"content_type": "application/json", "schema_ref": "CreatePublicUrlResponse"}, None, None, {"python": None, "node": None, "xai_sdk_python": "client.files.create_public_url(file_id, expires_after=…)"}, ver("success", 200, "PNG without TTL + {} → public_url; anonymous GET 200 image/png; second call with expires_after 3600 → same URL + expires_at; txt → 400 unsupported content type; PNG with TTL 3600 + expires_after 3600 → 400 'at most 3599s'"), src(PU, SPEC)))66E.append(ep("files", "POST", "/v1/files/{file_id}/public-url/revoke", "Files: revoke public URL", "Revoke → {id, revoked:true, public_url}; no active URL → {id, revoked:false} (idempotent, no error).", LV, None, {"content_type": "application/json", "schema_ref": "RevokePublicUrlResponse"}, None, None, {"python": None, "node": None, "xai_sdk_python": "client.files.revoke_public_url(file_id)"}, ver("success", 200, "revoked:true then revoked:false"), src(PU, SPEC)))67E.append(ep("files", "POST", "/v1/files:initialize", "Files: chunked upload initialize", "Listed in the REST reference without documentation (chunked upload protocol used by the SDK progress upload). Not in OpenAPI.", ["DOCUMENTED", "UNVERIFIED"], None, None, None, None, None, ver("success", None, "not called", "docs_only"), src(F + "upload")))68E.append(ep("files", "POST", "/v1/files:uploadChunks", "Files: chunked upload chunks", "Listed in the REST reference without documentation. Not in OpenAPI.", ["DOCUMENTED", "UNVERIFIED"], None, None, None, None, None, ver("success", None, "not called", "docs_only"), src(F + "upload")))69E.append(ep("files", "PUT", "/v1/files/{file_id}", "Files: update (undocumented)", "Listed in the REST reference as 'API endpoint for PUT requests' without fields. Not in OpenAPI.", ["DOCUMENTED", "UNVERIFIED"], None, None, None, None, None, ver("success", None, "not called", "docs_only"), src(F + "manage")))70CS = REF + "collections/search"; CC = REF + "collections/collection"71E.append(ep("collections", "POST", "/v1/documents/search", "Collections: search documents", "Semantic/keyword/hybrid chunk search across collections (query, source.collection_ids, limit, filter AIP-160, retrieval_mode {type: hybrid|semantic|keyword, reranker…}, group_by, instructions). Base URL api.x.ai with the inference key.", ["DOCUMENTED", "LIVE_VERIFIED", "FAILED_VERIFICATION"], {"content_type": "application/json", "body_ref": "SearchRequest"}, {"content_type": "application/json", "schema_ref": "SearchResponse"}, None, None, {"python": None, "node": None, "xai_sdk_python": "client.collections.search(query, collection_ids, …)"}, ver("failure", 404, "fake id → 404 'not found or not accessible'; [] → 400 'Collection IDs cannot be empty'; freshly created collection with a document still DOCUMENT_STATUS_PROCESSING after 75 s → 404 (same message). No processed collection was available to obtain a 200 within the probe window."), src(CS, D + "files/collections/api", SPEC)))72COLL_NOTE = "Documented base URL https://management-api.x.ai + Management API key (401 'Invalid bearer token. Please ensure you use a valid management key.' with the inference key). LIVE_DISCOVERED: the same paths also exist on https://api.x.ai and accept the inference key (gRPC-gateway style: path ids must be repeated in the JSON body)."73def cep(method, path, name, desc, status, verification, req=None, resp=None, pag=None, sdk=None):74 return ep("collections", method, path, name, desc + " " + COLL_NOTE, status, req, resp, None, pag, sdk or {"python": None, "node": None, "xai_sdk_python": "client.collections.* (requires management_api_key in Client)"}, verification, src(CC, D + "files/collections/api"), documented_base_url="https://management-api.x.ai", live_base_url_observed="https://api.x.ai (inference key)")75LD = ["DOCUMENTED", "LIVE_DISCOVERED", "LIVE_VERIFIED", "ACCOUNT_RESTRICTED"]76E.append(cep("POST", "/v1/collections", "Collections: create", "Create a collection (collection_name, index_configuration.model_name, chunk_configuration, metric_space, field_definitions, collection_description). On api.x.ai `field_definitions` is required (may be []) and each definition needs key/required/inject_into_chunk/unique.", LD, ver("success", 200, "api.x.ai: {collection_name, field_definitions:[]} → collection_… (default grok-embedding-small, BytesConfiguration 4000/800); management-api.x.ai → 401"), {"content_type": "application/json", "body_ref": "CreateCollectionRequest (parameters/xai-files-collections-batches.json)"}, {"content_type": "application/json", "schema_ref": "Collection"}))77E.append(cep("GET", "/v1/collections", "Collections: list", "List collections (limit ≤100, order, sort_by, pagination_token, filter, team_id).", LD, ver("success", 200, "api.x.ai → {collections:[…], pagination_token:null}; management-api → 401"), None, {"content_type": "application/json", "schema_ref": "ListCollectionsResponse"}, {"style": "token", "params": ["limit", "pagination_token"]}))78E.append(cep("GET", "/v1/collections/{collection_id}", "Collections: get", "Collection metadata.", LD, ver("success", 200, "api.x.ai 200 with many undocumented fields (sharing, effective_privilege, is_owned, …)"), None, {"content_type": "application/json", "schema_ref": "Collection"}))79E.append(cep("PUT", "/v1/collections/{collection_id}", "Collections: update", "Update name/description/chunk_configuration/field_definition_updates. Live on api.x.ai: body must include collection_id and field_definition_updates (422 'missing field' otherwise) — not completed.", ["DOCUMENTED", "LIVE_DISCOVERED", "FAILED_VERIFICATION", "ACCOUNT_RESTRICTED"], ver("failure", 422, "{collection_name} → 422 missing field collection_id; {collection_id, collection_name} → 422 missing field field_definition_updates"), {"content_type": "application/json", "body_ref": "UpdateCollectionRequest"}, {"content_type": "application/json", "schema_ref": "Collection"}))80E.append(cep("DELETE", "/v1/collections/{collection_id}", "Collections: delete", "Delete a collection → 200 {}.", LD, ver("success", 200, "api.x.ai 200 {}"), None, {"content_type": "application/json", "schema_ref": "{}"}))81E.append(cep("POST", "/v1/collections/{collection_id}/documents/{file_id}", "Collections: add document", "Attach an uploaded Files-API file to a collection (indexing starts asynchronously; poll the document status). Live body on api.x.ai: {collection_id, file_id, fields}.", LD, ver("success", 200, "200 {} once collection_id+file_id were repeated in the body (422 otherwise); document then listed with status 1 (PROCESSING) for >75 s"), {"content_type": "application/json", "body_ref": "AddDocumentRequest {collection_id, file_id, fields{}}"}, {"content_type": "application/json", "schema_ref": "{}"}))82E.append(cep("POST", "/v1/collections/{collection_id}/documents", "Collections: upload document (multipart, guide only)", "Guide shows a one-step multipart upload (name, data, content_type, fields) on management-api.x.ai. Not in the REST reference; api.x.ai → 405.", ["DOCUMENTED", "FAILED_VERIFICATION"], ver("failure", 405, "api.x.ai multipart → 405 Method Not Allowed"), {"content_type": "multipart/form-data", "body_ref": "name, data, content_type, fields"}, None))83E.append(cep("GET", "/v1/collections/{collection_id}/documents", "Collections: list documents", "List documents with file_metadata, fields, status, error_message, last_indexed_at (+ live: chunk_count, chunks_processed_count).", LD, ver("success", 200, "1 document, status integer 1 while processing"), None, {"content_type": "application/json", "schema_ref": "ListDocumentsResponse"}, {"style": "token", "params": ["limit", "pagination_token", "filter", "sort_by", "order"]}))84E.append(cep("GET", "/v1/collections/{collection_id}/documents/{file_id}", "Collections: get document", "Document metadata + processing status.", LD, ver("success", 200, "status 1 (proto enum number, docs say string enum); 404 'Cannot find document metadata' before the document is added"), None, {"content_type": "application/json", "schema_ref": "Document"}))85E.append(cep("PATCH", "/v1/collections/{collection_id}/documents/{file_id}", "Collections: reindex document", "Regenerate indices for a document.", ["DOCUMENTED", "ACCOUNT_RESTRICTED", "UNVERIFIED"], ver("success", None, "not called", "docs_only")))86E.append(cep("DELETE", "/v1/collections/{collection_id}/documents/{file_id}", "Collections: remove document", "Remove a document from a collection → 200 {}. LIVE_DISCOVERED hazard: the underlying Files-API file was deleted as well (GET /v1/files/{id} → 404 afterwards), even when the document had never been successfully added.", LD, ver("success", 200, "200 {} ; file gone afterwards")))87E.append(cep("GET", "/v1/collections/{collection_id}/documents:batchGet", "Collections: batch get documents", "Get several documents' metadata (file_ids[] query). Live: could not find the accepted query encoding (file_ids=… → 'expected a sequence'; file_ids[]=… → 'missing field file_ids').", ["DOCUMENTED", "FAILED_VERIFICATION", "ACCOUNT_RESTRICTED"], ver("failure", 400, "two encodings → 400 deserialization errors")))88B = REF + "inference/batches"; BG = D + "advanced-api-usage/batch-api"89def bep(method, path, name, desc, status, verification, req=None, resp=None, pag=None):90 return ep("batches", method, path, name, desc, status, req, resp, None, pag, {"python": None, "node": None, "xai_sdk_python": "client.batch.create/add/get/list/list_batch_requests/list_batch_results/cancel"}, verification, src(B, BG), note="Not present in the OpenAPI spec (openapi.json has no /v1/batches paths); shape from the REST reference + live.")91E.append(bep("POST", "/v1/batches", "Batches: create", "Create a batch container {name} (or {name, input_file_id} for a sealed JSONL batch). expire_time = +30 days live. Discounted pricing (20% off on grok-4.3 / grok-4.20*), no rate-limit consumption; 2 creations/s/team.", LV, ver("success", 200, "{name:'atlas-probe'} → batch_… , state all zeros, expire_time create+30d"), {"content_type": "application/json", "body_ref": "{name, input_file_id?}"}, {"content_type": "application/json", "schema_ref": "Batch"}))92E.append(bep("GET", "/v1/batches", "Batches: list", "List team batches (limit, pagination_token).", LV, ver("success", 200, "limit=2 → 1 batch, pagination_token null"), None, {"content_type": "application/json", "schema_ref": "ListBatchesResponse"}, {"style": "token", "params": ["limit", "pagination_token"]}))93E.append(bep("GET", "/v1/batches/{batch_id}", "Batches: get", "Batch with aggregate state counters; poll until num_pending == 0.", LV, ver("success", 200, "2 requests: pending 2 at t=0, success 2 at t=11 s"), None, {"content_type": "application/json", "schema_ref": "Batch"}))94E.append(bep("POST", "/v1/batches/{batch_id}/requests", "Batches: add requests", "Add requests {batch_requests:[{batch_request_id, batch_request:{chat_get_completion|responses|image_generation|image_edit|video_generation|video_extension}}]}. Live: 200 with an EMPTY body; a `responses` request was accepted but its result came back as chat_get_completion.", LV, ver("success", 200, "2 requests (chat_get_completion + responses) → 200 null body"), {"content_type": "application/json", "body_ref": "AddBatchRequests"}, {"content_type": None, "schema_ref": "empty"}))95E.append(bep("GET", "/v1/batches/{batch_id}/requests", "Batches: list request metadata", "Per-request state (pending|succeeded|failed|cancelled), endpoint, model, timestamps (limit ≤1000, pagination_token).", LV, ver("success", 200, "both requests 'succeeded', endpoint 'xai_api.Chat/GetCompletion'"), None, {"content_type": "application/json", "schema_ref": "ListBatchRequestsResponse"}, {"style": "token", "params": ["limit", "pagination_token"]}))96E.append(bep("GET", "/v1/batches/{batch_id}/results", "Batches: list results", "Results {batch_request_id, batch_result:{response:{chat_get_completion:ChatCompletion}|error}} (limit ≤1000). Available as soon as individual requests finish; per-result cost in usage.cost_in_usd_ticks.", LV, ver("success", 200, "2 results, both chat_get_completion with reasoning_content, cost_in_usd_ticks 3887200 / 2187200 (≈$0.0004/$0.0002)"), None, {"content_type": "application/json", "schema_ref": "ListBatchResultsResponse"}, {"style": "token", "params": ["limit", "pagination_token"]}))97E.append(bep("POST", "/v1/batches/{batch_id}:cancel", "Batches: cancel", "Cancel pending requests; completed results stay. Live: works on an already-completed batch (sets cancel_time).", LV, ver("success", 200, "cancel_time set, state unchanged (2 success)"), None, {"content_type": "application/json", "schema_ref": "Batch"}))98E.append(bep("DELETE", "/v1/batches/{batch_id}", "Batches: delete (not offered)", "Not documented; probed → 405.", ["LIVE_DISCOVERED"], ver("failure", 405, "405 Method Not Allowed, empty body")))99(ROOT / "generated/fragments/endpoints/xai-inference.json").write_text(json.dumps({"_generated_by": "tmp/xai-inference/build_handwritten.py", "_generated_at": T, "_notation": "status per CLAUDE.md vocabulary; verification.request_note summarises the live probes of 2026-09-18/19 (raws in tmp-live/xai/)", "records": E}, indent=1, ensure_ascii=False))100print("endpoints", len(E))101102# ------------------------------------------------------------------ TOOLS103def tool(name, typ, cat, desc, models, endpoints, schema, choice, parallel, events, result, billing, limits, security, status, verification, sources, examples=None, **kw):104 r = {"provider": "xai", "name": name, "type": typ, "category": cat, "description": desc, "compatible_models": models, "compatible_endpoints": endpoints, "parameters_schema": schema, "tool_choice_support": choice, "parallel": parallel, "streaming_events": events, "result_shape": result, "billing": billing, "limitations": limits, "security": security, "beta_header": None, "status": status, "examples": examples or {"curl": None, "python": None, "typescript": None}, "verification": verification, "sources": sources}105 r.update(kw); return r106AGENTIC = ["grok-4.6", "grok-4.5", "grok-4.3", "grok-4.20-0309-reasoning", "grok-4.20-0309-non-reasoning", "grok-4.20-multi-agent-0309", "grok-build-0.1"]107TOOLS = [108 tool("Function calling", "function", "client", "Developer-defined function (JSON Schema parameters, object root or oneOf/anyOf of objects). Model emits tool calls; the app executes and returns results. Arguments always conform to the schema (strict implicit). Responses uses the flat shape {type, name, description, parameters}; Chat Completions the nested {type, function:{…}}. `strict` and `defer_loading` accepted (defer_loading → 403 alpha).", AGENTIC, ["POST /v1/chat/completions", "POST /v1/responses", "POST /v1/messages (Anthropic shape: name/description/input_schema)", "Batch API"],109 {"responses": {"type": "function", "name": "string (required)", "description": "string", "parameters": "JSON Schema object (required)", "strict": "boolean (ignored)", "defer_loading": "boolean (alpha, 403)"}, "chat_completions": {"type": "function", "function": {"name": "…", "description": "…", "parameters": {}}}},110 {"auto": True, "none": True, "required": True, "forced": {"chat": {"type": "function", "function": {"name": "…"}}, "responses": {"type": "function", "name": "…"}}}, True,111 ["chat: whole tool call in ONE chunk delta.tool_calls[{index,id,type,function}]", "responses: response.output_item.added(function_call) → response.function_call_arguments.delta (single delta with full JSON) → response.function_call_arguments.done → response.output_item.done"],112 {"chat": "choices[].message.tool_calls[] {id:'call-<uuid>-<n>', type:'function', function:{name, arguments}} + finish_reason 'tool_calls'", "responses": "output[] item {type:'function_call', id:'fc_…', call_id:'call-…', name, arguments, status}; reply with {type:'function_call_output', call_id, output}", "messages": "content[] {type:'tool_use', id, name, input} + stop_reason 'tool_use'; reply with tool_result block"},113 "Tokens only (no per-call fee).", ["≤350 tools per request (128 in batch docs)", "parameters root must be an object or union of objects (400 otherwise)", "max_turns resets after each client-side call"], "Executed by the caller; validate arguments.",114 LV, ver("success", 200, "chat: forced → 1 call, round trip → '18°C and sunny', tool_choice required → 2 parallel calls, parallel_tool_calls:false → 1, stream → single chunk; responses: forced function_call + function_call_output via previous_response_id → message; messages: tool_use + tool_result"), src(D + "tools/function-calling", SPEC)),115 tool("Web Search", "web_search", "server", "Server-side web search + page browsing (search, open_page, find_in_page actions; sub-tools web_search, web_search_with_snippets, browse_page, open_page, open_page_with_find; image search via enable_image_search; view_image via enable_image_understanding). Responses API only.", AGENTIC, ["POST /v1/responses", "Batch API (responses body)"],116 {"type": "web_search", "allowed_domains": "string[] ≤5 (exclusive with excluded_domains)", "excluded_domains": "string[] ≤5", "filters": {"allowed_domains": "…", "excluded_domains": "… (OpenAI-compatible nesting, accepted live)"}, "enable_image_understanding": "boolean", "enable_image_search": "boolean", "search_context_size": "REJECTED 400 if set (echoed as 'medium' in responses)", "user_location": "rejected (compat only)", "external_web_access": "rejected (compat only)"},117 {"auto": True, "none": True, "required": "documented for tools generally"}, True,118 ["response.output_item.added(web_search_call) → response.output_item.done (no *.searching events observed; not exercised in stream)"],119 {"item": "output[] {type:'web_search_call', id:'ws_…', status:'completed', action:{type:'search', query, sources[]?}|{type:'open_page', url}|{type:'find_in_page', url, pattern}}", "citations": "output_text.annotations[] url_citation {url, start_index, end_index, title} (live: indices 0/0, title=url); inline [[N]](url) markdown by default (disable with include:['no_inline_citations'])", "usage": "usage.server_side_tool_usage_details.web_search_calls, num_server_side_tools_used", "include": "web_search_call.action.sources"},120 "$5 per 1k successful calls (+ tokens); image search billed as web search; view_image billed as image tokens.", ["allowed_domains xor excluded_domains", "model may answer without searching (first probe answered the date from context without a call)"], "xAI-hosted browsing; URLs surfaced in citations.",121 LV, ver("success", 200, "grok-4.3 'open https://x.ai/news …' → web_search_call action open_page, web_search_calls=1, annotation url_citation; first probe (date question) produced no call"), src(D + "tools/web-search", D + "tools/citations", D + "pricing", SPEC)),122 tool("X Search", "x_search", "server", "Server-side search of X (keyword, semantic, user search, thread fetch; sub-tools x_keyword_search, x_semantic_search, x_user_search, x_thread_fetch; view_image/view_x_video). Responses API only.", AGENTIC, ["POST /v1/responses", "Batch API"],123 {"type": "x_search", "allowed_x_handles": "string[] ≤10 (spec) / ≤20 (guide); exclusive with excluded_x_handles", "excluded_x_handles": "string[]", "from_date": "YYYY-MM-DD", "to_date": "YYYY-MM-DD", "enable_image_understanding": "boolean", "enable_video_understanding": "boolean"},124 {"auto": True, "none": True}, True, ["response.output_item.added/done (not exercised in stream)"],125 {"item_documented": "output[] {type:'x_search_call'}", "item_live": "LIVE_DISCOVERED: output[] {type:'custom_tool_call', id:'ctc_…', call_id:'xs_call-…', name:'x_keyword_search'|'x_semantic_search', input:'{\"query\":…,\"limit\":…,\"mode\":\"Latest\"}', status}", "citations": "annotations[] url_citation to https://x.com/i/status/<id>; response.citations in xAI SDK", "usage": "server_side_tool_usage_details.x_search_calls"},126 "$5 per 1k calls until 2026-09-21 12:00 PT; then $5 per 1k posts fetched + $10 per 1k user profiles fetched.", ["handles list limits", "live item type differs from docs (custom_tool_call)"], "xAI-hosted.",127 ["DOCUMENTED", "LIVE_VERIFIED", "LIVE_DISCOVERED"], ver("success", 200, "allowed_x_handles ['xai'] → 1 x_keyword_search call (custom_tool_call), 3 url_citation annotations, x_search_calls=1; second run 2 calls"), src(D + "tools/x-search", D + "pricing", SPEC)),128 tool("Code Execution (Code Interpreter)", "code_interpreter", "server", "Sandboxed Python execution (NumPy/Pandas/Matplotlib/SciPy available, no network/filesystem persistence). Responses API type `code_interpreter`; alias `code_execution` accepted and normalised to `code_interpreter` in the response echo. xAI SDK name code_execution.", AGENTIC, ["POST /v1/responses", "Batch API"],129 {"type": "code_interpreter | code_execution (alias)", "container": "any (OpenAI compat, not needed)"}, {"auto": True, "none": True}, True,130 ["response.output_item.added(code_interpreter_call) → response.code_interpreter_call.in_progress → response.code_interpreter_call_code.delta → response.code_interpreter_call_code.done → response.code_interpreter_call.interpreting → response.code_interpreter_call.completed → response.output_item.done"],131 {"item": "output[] {type:'code_interpreter_call', id:'ci_…', code, outputs[], status}", "outputs": "only with include:['code_interpreter_call.outputs']: [{type:'logs', logs:'{\"stdout\":\"4\\n\",\"stderr\":\"\",\"exit_code\":0,\"command_timed_out\":false}'}] (JSON string) or {type:'image', url}", "chat_completions": "output_files[] with include code_execution_files_output (docs)", "usage": "server_side_tool_usage_details.code_interpreter_calls"},132 "$5 per 1k calls + tokens.", ["time/memory limits", "no network"], "Isolated sandbox.",133 LV, ver("success", 200, "'Run print(2+2)' → code_interpreter_call code 'print(2+2)', logs stdout '4', text '4', code_interpreter_calls=1; streamed variant emitted the 5 code_interpreter events"), src(D + "tools/code-execution", D + "tools/streaming-and-sync", SPEC), aliases=["code_execution"]),134 tool("Collections Search (File Search)", "file_search", "server", "RAG over Collections. Responses API type `file_search` with vector_store_ids = collection ids (`collections_search` accepted as alias but REQUIRES vector_store_ids, echoed as file_search). Citations use collections://<collection_id>/files/<file_id>.", AGENTIC, ["POST /v1/responses", "Batch API"],135 {"type": "file_search | collections_search (alias)", "vector_store_ids": "string[] collection ids (required)", "max_num_results": "integer", "filters": "any", "ranking_options": "any"}, {"auto": True, "none": True}, True, ["response.output_item.added/done (file_search_call)"],136 {"item": "output[] {type:'file_search_call', id:'fs_…', queries[], results[] (include file_search_call.results → {file_id, filename, score, text}), status completed|failed}", "citations": "collections://collection_id/files/file_id", "usage": "server_side_tool_usage_details.file_search_calls (docs also list document_search_calls)"},137 "$2.50 per 1k calls + tokens; storage $0.10/GiB/day.", ["collection must be indexed (document status PROCESSED) or the call fails"], "Team-scoped collections.",138 ["DOCUMENTED", "LIVE_VERIFIED"], ver("success", 200, "empty / still-indexing collection → file_search_call status 'failed', results [], text 'No documents.'; fake id also 200 with failed call; {type:'collections_search'} without vector_store_ids → 422"), src(D + "tools/collections-search", D + "files/collections", SPEC), aliases=["collections_search"]),139 tool("Remote MCP", "mcp", "mcp", "xAI connects to a remote MCP server (Streamable HTTP or SSE) and exposes its tools to the model; results are always returned in mcp_call items.", AGENTIC, ["POST /v1/responses", "Batch API", "Speech-to-Speech API"],140 {"type": "mcp", "server_url": "string (required)", "server_label": "string (required; prefixes tool names)", "server_description": "string", "allowed_tools": "string[] (empty = all; xAI SDK: allowed_tool_names)", "authorization": "string bearer token for the MCP server", "headers": "object (xAI SDK: extra_headers)", "require_approval": "accepted silently (docs: unsupported)", "connector_id": "docs: unsupported", "defer_loading": "alpha"},141 {"auto": True, "none": True}, True, ["response.output_item.added/done (mcp_call); not exercised in stream"],142 {"item": "output[] {type:'mcp_call', id:'mcp_…', server_label, name, arguments (JSON string), output (JSON string, always returned), error:'', status}", "tools_echo": "response.tools[] {type:'mcp', server_label, server_url, allowed_tools:[], headers:{}, server_description:''}", "usage": "server_side_tool_usage_details.mcp_calls"},143 "No per-call fee; tokens only (tool outputs count as input tokens).", ["no approval flow", "tool list injected into context (use allowed_tools)"], "Use HTTPS; credentials are forwarded to the MCP server by xAI.",144 LV, ver("success", 200, "deepwiki (https://mcp.deepwiki.com/mcp) → mcp_call name ask_question, output JSON, text 'Python SDK for xAI language models chat.', mcp_calls=1, 4024 total tokens"), src(D + "tools/remote-mcp", SPEC)),145 tool("Image Generation (tool)", "image_generation", "server", "In-conversation image generation tool (Imagine models). Documented on the tools pages; covered by the images agent. Accepted live in tools[] (echoed) without being called.", AGENTIC, ["POST /v1/responses"], {"type": "image_generation", "action": "string|null"}, {"auto": True}, None, None, {"item": "output[] {type:'image_generation_call', result (bare base64), prompt, status}; chat delta.images[]"}, "Imagine API per-image rates.", None, None, ["DOCUMENTED", "LIVE_VERIFIED"], ver("success", 200, "accepted in tools[] with tool_choice none (no generation)"), src(D + "tools/image-generation", SPEC)),146 tool("Attachment search (implicit)", "attachment_search", "server-implicit", "Not a tools[] entry: attaching input_file (file_id or file_url) to a Responses message automatically turns the request into an agentic document-search workflow. xAI SDK include value attachment_search_call_output.", AGENTIC, ["POST /v1/responses"], {"input": [{"type": "input_file", "file_id": "file_…", "file_url": "https://…"}]}, None, None, None, {"observed": "no visible tool item in output (only reasoning + message); answer grounded in the file ('PINEAPPLE')"}, "$10 per 1k calls (File Attachments).", ["not available on /v1/chat/completions (400)", "no batch mode"], None, LV, ver("success", 200, "200-byte txt attached by file_id → correct secret word; chat completions file part → 400"), src(D + "model-capabilities/files/chat-with-files", D + "pricing")),147 tool("Image understanding (view_image / view_x_video sub-tools)", "view_image", "server-subtool", "Not a tools[] type: enabling enable_image_understanding on web_search/x_search (or enable_video_understanding on x_search) lets the agent call view_image / view_x_video on media it finds. Direct image input is a content part (input_image / image_url), not a tool.", AGENTIC, ["POST /v1/responses (via web_search / x_search options)"], {"enable_image_understanding": "boolean on web_search|x_search", "enable_video_understanding": "boolean on x_search"}, None, None, None, {"usage": "SERVER_SIDE_TOOL_VIEW_IMAGE / SERVER_SIDE_TOOL_VIEW_X_VIDEO counts in the xAI SDK"}, "No invocation fee; image tokens billed.", None, None, ["DOCUMENTED"], ver("success", None, "flags accepted (enable_image_understanding:false echoed); no view_image call triggered", "docs_only"), src(D + "tools/web-search", D + "tools/x-search", D + "tools/tool-usage-details", D + "pricing")),148 tool("Shell (local)", "shell", "client", "Model emits shell_call items {action:{commands[], timeout_ms, max_output_length}} for the client to run locally and answer with shell_call_output. Accepted live; not in the tools guide pages (OpenAPI only).", AGENTIC, ["POST /v1/responses"], {"type": "shell", "environment": {"type": "local", "skills": "[{name, description, path}]"}}, {"auto": True, "none": True}, None, None, {"item": "shell_call / shell_call_output"}, "Tokens only.", None, "Runs on the caller's machine.", ["DOCUMENTED", "LIVE_VERIFIED"], ver("success", 200, "tools:[{type:'shell', environment:{type:'local'}}] accepted and echoed; no call triggered"), src(SPEC)),149 tool("Tool search (deferred tool loading)", "tool_search", "hosted", "Server-side tool search that loads function definitions marked defer_loading:true on demand (tool_search_call / tool_search_output items). Alpha.", AGENTIC, ["POST /v1/responses"], {"type": "tool_search", "execution": "string|null"}, None, None, None, {"items": "tool_search_call {arguments:{query, limit}, execution:'server'} → tool_search_output {tools[]}"}, None, ["alpha users only"], None, ["DOCUMENTED", "ACCOUNT_RESTRICTED"], ver("restricted", 403, "403 permission-denied 'The tool_search tool and defer_loading are only available for alpha users'"), src(SPEC)),150 tool("Live Search (legacy chat tool)", "live_search", "server", "Legacy Chat Completions tool variant {type:'live_search', sources:[{type:'web'|'x'|'news'|'rss', …}]} and the search_parameters/web_search_options fields. Retired: every use → 410 'Live search is deprecated. Please switch to the Agent Tools API'.", [], ["POST /v1/chat/completions (410)"], {"type": "live_search", "sources": "[{type:'web', allowed_websites, excluded_websites, country, safe_search}, {type:'x', included_x_handles, excluded_x_handles, post_favorite_count, post_view_count}, {type:'news', …}, {type:'rss', links[]}]"}, None, None, None, None, None, None, None, ["DOCUMENTED", "RETIRED"], ver("failure", 410, "410 on live_search tool, search_parameters and web_search_options"), src(CHAT, SPEC)),151]152(ROOT / "generated/fragments/tools/xai-tools.json").write_text(json.dumps({"$fragment": "xai-tools", "generated_by": "tmp/xai-inference/build_handwritten.py", "generated_at": T, "accepted_type_strings_live": ["function", "web_search", "x_search", "image_generation", "collections_search", "file_search", "code_execution", "code_interpreter", "mcp", "shell", "tool_search"], "accepted_type_strings_source": "422 error text on /v1/responses: \"unknown variant `web_search_preview`, expected one of `function`, `web_search`, `x_search`, `image_generation`, `collections_search`, `file_search`, `code_execution`, `code_interpreter`, `mcp`, `shell`, `tool_search`\"", "include_values": {"reasoning.encrypted_content": "encrypted reasoning on reasoning items", "web_search_call.action.sources": "sources on search actions", "code_interpreter_call.outputs": "logs/images of code runs", "file_search_call.results": "chunks of collections search", "no_inline_citations": "disable [[N]](url) markdown", "message.output_text.logprobs": "accepted, ignored"}, "records": TOOLS}, indent=1, ensure_ascii=False))153print("tools", len(TOOLS))154155# ------------------------------------------------------------------ STREAMING EVENTS156def sev(api, event, desc, schema=None, example=None, status=None, source=None, order=None, **kw):157 r = {"provider": "xai", "api": api, "direction": "server→client", "event": event, "description": desc, "schema": schema, "example": example, "status": status or LV, "source": source or SPEC}158 if order is not None: r["order_hint"] = order159 r.update(kw); return r160def raw(n):161 try: return json.load(open(ROOT / "tmp-live/xai" / f"{n}.json"))["raw"]162 except Exception: return []163def first_data(n, typ):164 for l in raw(n):165 if l.startswith("data:"):166 try: j = json.loads(l[5:])167 except Exception: continue168 if j.get("type") == typ:169 j = json.loads(json.dumps(j))170 if j.get("item", {}).get("encrypted_content"): j["item"]["encrypted_content"] = j["item"]["encrypted_content"][:20] + "…"171 if "response" in j: j["response"] = {k: v for k, v in j["response"].items() if k in ("id", "object", "status", "output", "usage", "store", "model")}172 return j173 return None174S = []175chunk_ex = [json.loads(l[5:]) for l in raw("chat_stream_reasoning") if l.startswith("data:") and l[5:].strip() != "[DONE]"]176S.append(sev("chat_completions", "chat.completion.chunk", "Data-only SSE line `data: {…}` (no event: name). Observed order (grok-4.3): [delta.role+reasoning_content]* → [delta.content]* → {delta:{}, finish_reason} → (stream_options.include_usage) {choices:[], usage} → `data: [DONE]`. Every chunk carries id, object, created (=0 live), model, system_fingerprint, service_tier. Tool calls arrive whole in one chunk (delta.tool_calls[{index, id, type:'function', function:{name, arguments}}]).", {"id": "string", "object": "chat.completion.chunk", "created": "integer (0 live)", "model": "string", "choices[].index": "integer", "choices[].delta": "{role?, content?, reasoning_content?, tool_calls?[], images?[]}", "choices[].finish_reason": "string|null (stop | length | tool_calls)", "usage": "Usage|null (only on the final usage chunk)", "citations": "array|null (last chunk, Live Search — retired)", "system_fingerprint": "string", "service_tier": "default|priority"}, chunk_ex[:4], source=D + "model-capabilities/text/streaming", order=0))177S.append(sev("chat_completions", "chat.completion.chunk (usage chunk)", "Final chunk when stream_options.include_usage=true: choices=[] and full usage (prompt/completion/total, details, num_sources_used, cost_in_usd_ticks).", None, next((json.loads(l[5:]) for l in raw("chat_stream") if l.startswith("data:") and '"choices":[]' in l), None), order=1))178S.append(sev("chat_completions", "[DONE]", "Terminator `data: [DONE]`.", None, "data: [DONE]", order=2))179resp_events = [180 ("response.created", "First event; response snapshot with status in_progress, output [], usage null, reasoning {effort:null, summary:null}.", 0),181 ("response.in_progress", "Second snapshot (same shape).", 1),182 ("response.output_item.added", "New output item (reasoning | message | function_call | code_interpreter_call | web_search_call …) with output_index; item.status in_progress.", 2),183 ("response.reasoning_summary_part.added", "Reasoning summary part opened {item_id, output_index, summary_index, part:{type:'summary_text', text:''}}.", 3),184 ("response.reasoning_summary_text.delta", "Reasoning summary text delta {delta, item_id, output_index, summary_index}. Emitted for grok-4.3 without any reasoning.summary setting.", 4),185 ("response.reasoning_summary_text.done", "Full summary text.", 5),186 ("response.reasoning_summary_part.done", "Summary part closed (part.text complete).", 6),187 ("response.output_item.done", "Item completed (reasoning item may carry encrypted_content when include requested; function_call carries final arguments; code_interpreter_call carries code + outputs).", 7),188 ("response.content_part.added", "Message content part opened {item_id, output_index, content_index, part:{type:'output_text', text:'', logprobs:[], annotations:[]}}.", 8),189 ("response.output_text.delta", "Text delta {delta, item_id, output_index, content_index}.", 9),190 ("response.output_text.done", "Full text {text, logprobs:[]}.", 10),191 ("response.content_part.done", "Content part closed (part with text/annotations).", 11),192 ("response.function_call_arguments.delta", "Function-call arguments delta — live a single delta containing the whole JSON string.", 12),193 ("response.function_call_arguments.done", "{arguments, item_id, name, output_index}.", 13),194 ("response.code_interpreter_call.in_progress", "Code interpreter call started {item_id, output_index}.", 14),195 ("response.code_interpreter_call_code.delta", "Code delta {delta}.", 15),196 ("response.code_interpreter_call_code.done", "Full code {code}.", 16),197 ("response.code_interpreter_call.interpreting", "Sandbox executing.", 17),198 ("response.code_interpreter_call.completed", "Execution finished (outputs appear in the following output_item.done).", 18),199 ("response.completed", "Final snapshot with full output[] and usage; completed_at set. Stream ends here (no `data: [DONE]` observed).", 19),200]201for name, desc, order in resp_events:202 ex = None203 for f in ("responses_stream_function", "responses_stream_code_interpreter", "responses_stream", "responses_stream_reasoning"):204 ex = first_data(f, name)205 if ex: break206 S.append(sev("responses", name, desc + " SSE framing: `event: <type>` line + `data: {…}` with sequence_number.", None, ex, source=RESP, order=order))207for name, desc in [("response.reasoning_text.delta", "Raw reasoning text delta — mentioned in the reasoning guide alongside reasoning_summary_text.delta; NOT observed live on grok-4.3 (only summary deltas)."), ("response.web_search_call.in_progress / .searching / .completed", "OpenAI-style web search progress events — not observed (web_search only exercised non-streaming)."), ("response.mcp_call.* / response.file_search_call.*", "Not observed; mcp/file_search only exercised non-streaming."), ("response.incomplete / response.failed / error", "Not observed.")]:208 S.append(sev("responses", name, desc, status=["DOCUMENTED", "UNVERIFIED"] if "reasoning_text" in name else ["UNVERIFIED"], source=D + "model-capabilities/text/reasoning"))209msg_raw = raw("messages_stream")210def mex(t):211 for l in msg_raw:212 if l.startswith("data:") and json.loads(l[5:]).get("type") == t: return json.loads(l[5:])213for name, desc, order in [("message_start", "Anthropic-compatible: {message:{id, type:'message', role, content:[], model, stop_reason:null, usage:{input_tokens, cache_creation_input_tokens, cache_read_input_tokens, output_tokens:0}}}.", 0), ("content_block_start", "Opens a block: {index, content_block:{type:'thinking', thinking:'', signature:''}} for reasoning, then {type:'text', text:''}. Live: index is 0 for BOTH blocks (Anthropic would use 0 and 1).", 1), ("content_block_delta", "{delta:{type:'thinking_delta', thinking}} or {delta:{type:'text_delta', text}} — live deltas carry no `index` field.", 2), ("content_block_stop", "{index}.", 3), ("message_delta", "{delta:{stop_reason:'end_turn', stop_sequence:null}, usage:{output_tokens}} (output_tokens includes reasoning).", 4), ("message_stop", "End of stream (no [DONE]).", 5)]:214 S.append(sev("messages_compat", name, desc + " Framing: `event: <name>` + `data: {…}`.", None, mex(name), status=["DOCUMENTED", "DEPRECATED", "LIVE_VERIFIED"], source=LEG, order=order))215(ROOT / "generated/fragments/streaming-events/xai-inference.json").write_text(json.dumps({"_generated_by": "tmp/xai-inference/build_handwritten.py", "_generated_at": T, "_notation": "api: chat_completions | responses | messages_compat; example = sanitized live SSE payload (2026-09-19, grok-4.3); order_hint = observed position", "records": S}, indent=1, ensure_ascii=False, default=str))216print("streaming", len(S))217