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%
4.9 KB

# xAI Files API — upload, list, metadata, content, public URLs, attachments

Status: DOCUMENTED + LIVE_VERIFIED (2026-09-19: upload txt+png with TTL, list (+filter), get, content, public-url create/idempotent/anon fetch/revoke, delete, input_file attachment in Responses). Machine-readable: parameters/xai-files-collections-batches.json, endpoints/xai-inference.json, objects/xai-inference-objects.json (File, …).

Sources: https://docs.x.ai/developers/rest-api-reference/files/upload · …/files/manage · …/files/download · https://docs.x.ai/developers/files/managing-files · https://docs.x.ai/developers/files/public-urls · https://docs.x.ai/developers/model-capabilities/files/chat-with-files · https://docs.x.ai/developers/pricing#files-and-collections-pricing · OpenAPI UploadFileMultipartRequest, File, ListFilesParams, CreatePublicUrlRequest/Response, RevokePublicUrlResponse Last verified: 2026-09-19

# Endpoints (https://api.x.ai, inference key)

Method Path Body / query Response Live
POST /v1/files multipart: file (required), purpose? (ignored, echoed ""), expires_after? 3600–2592000 s — must precede file (also OpenAI deepObject expires_after[anchor]=created_at&expires_after[seconds]=N) File 200 (200 B txt, 95 B png)
GET /v1/files limit ≤100 (100), order asc|desc (desc), sort_by created_at|filename|size, pagination_token, filter (AIP-160: name, file_id, size_bytes, content_type, created_at, expires_at, upload_status, user_defined_id, public_url), after (compat) {data[], pagination_token} (null on last page) 200
GET /v1/files/{id} File (404 {code:"not-found", error:"File not found"} after delete/expiry) 200/404
GET /v1/files/{id}/content format=original|text raw bytes application/octet-stream 200 bytes identical; format=text on txt → 404 {error:"Failed to retrieve file"}
DELETE /v1/files/{id} {id, deleted:true, object:"file"} 200
POST /v1/files/{id}/public-url {} or {expires_after} {public_url, expires_at?} 200 png; txt → 400 unsupported type; TTL overflow → 400
POST /v1/files/{id}/public-url/revoke {id, revoked:true, public_url} / {id, revoked:false} 200
POST /v1/files:initialize, /v1/files:uploadChunks, PUT /v1/files/{id} listed in the reference without fields (chunked upload used by the SDK) UNVERIFIED

# File object

json
{"id":"file_8377ab50-…","object":"file","bytes":95,"created_at":1789789835,"expires_at":null,"filename":"atlas-pixel2.png","purpose":"",
 "public_url":"https://files-cdn.x.ai/e7nuu0ZNSMGJuFIq_MFXmA/file_8377ab50-….png","public_url_expires_at":1789793436}

purpose is stored for OpenAI-SDK compatibility only (echoed empty). Limits: 50 MB (spec) / 512 MB (guide) per file; text-based formats (txt, md, code, csv, json, pdf …). Storage $0.025/GiB/day, downloads $0.20/GiB. Files are team-scoped and permanent unless expires_after set.

# Public URLs (docs + live)

  • Eligible types: image/png, image/jpeg, image/gif, image/webp, video/mp4, video/webm, application/pdf (live error lists exactly these). ≤50 MiB; ≤1 000 active URLs per team.
  • Expiry: omit → inherits the file's expiry (never for permanent files); expires_after 1 h–30 d and ≤ file's remaining lifetime (live: file TTL 3600 + expires_after: 3600 → 400 "Set expires_after to at most 3599s, or omit it").
  • Idempotent: second create returns the same URL; a different expires_after updates the expiry in place (live: same URL + expires_at added). Revoke → next create issues a new token. Deleting the file revokes the URL.
  • Anonymous GET of the CDN URL → 200 image/png (live).

# Using files in chat

  • Responses only: {"type":"input_file","file_id":"file_…"} or {"type":"input_file","file_url":"https://…"} inside content[]. Attaching a file turns the request into an agentic attachment search ($10 per 1k calls; no visible tool item in output[]; live answer "PINEAPPLE" from a 200-byte txt, 294 input tokens, 200 reasoning tokens). Multiple files, mixing with input_image, and combining with code_interpreter are documented. No batch (n>1) mode. Multi-turn: previous_response_id or encrypted content.
  • Chat Completions {"type":"file","file":{"file_id"}} → 400 "File content is not supported on /v1/chat/completions. Please use /v1/responses instead."
  • input_image with file_id (spec) → live 400 "image_url must either be a base64-encoded image or a URL" (use a data URL or a public URL — e.g. the file's public URL).
  • Batch API JSONL input: upload the .jsonl then POST /v1/batches {name, input_file_id}.
  • Imagine outputs can be stored directly as files (storage_options) — see the images agent.

Examples: examples/xai/files/ (sh/py/ts). Tests: tests/xai/test_files.py.