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 · 42 lines markdown
Rendered Raw Blame History
1# xAI Files API — upload, list, metadata, content, public URLs, attachments23**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, …).45**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`6**Last verified:** 2026-09-1978## Endpoints (`https://api.x.ai`, inference key)910| Method | Path | Body / query | Response | Live |11|---|---|---|---|---|12| 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) |13| 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 |14| GET | `/v1/files/{id}` | | `File` (404 `{code:"not-found", error:"File not found"}` after delete/expiry) | 200/404 |15| 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"}`** |16| DELETE | `/v1/files/{id}` | | `{id, deleted:true, object:"file"}` | 200 |17| POST | `/v1/files/{id}/public-url` | `{}` or `{expires_after}` | `{public_url, expires_at?}` | 200 png; txt → 400 unsupported type; TTL overflow → 400 |18| POST | `/v1/files/{id}/public-url/revoke` | | `{id, revoked:true, public_url}` / `{id, revoked:false}` | 200 |19| POST | `/v1/files:initialize`, `/v1/files:uploadChunks`, PUT `/v1/files/{id}` | listed in the reference without fields (chunked upload used by the SDK) | | UNVERIFIED |2021## File object22```json23{"id":"file_8377ab50-…","object":"file","bytes":95,"created_at":1789789835,"expires_at":null,"filename":"atlas-pixel2.png","purpose":"",24 "public_url":"https://files-cdn.x.ai/e7nuu0ZNSMGJuFIq_MFXmA/file_8377ab50-….png","public_url_expires_at":1789793436}25```26`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.2728## Public URLs (docs + live)29- 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.30- 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").31- 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.32- Anonymous `GET` of the CDN URL → 200 `image/png` (live).3334## Using files in chat35- **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.36- Chat Completions `{"type":"file","file":{"file_id"}}` → **400 "File content is not supported on /v1/chat/completions. Please use /v1/responses instead."**37- `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).38- Batch API JSONL input: upload the `.jsonl` then `POST /v1/batches {name, input_file_id}`.39- Imagine outputs can be stored directly as files (`storage_options`) — see the images agent.4041Examples: `examples/xai/files/` (sh/py/ts). Tests: `tests/xai/test_files.py`.42