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

# OpenAI Files API and Uploads API

Status: DOCUMENTED · LIVE_VERIFIED (all 5 Files endpoints and all 4 Uploads endpoints called on 2026-09-18 with a project key; one LIVE_DISCOVERED behaviour on Uploads purposes). Sources: Files reference · Uploads reference · File inputs guide · Batch guide · Retrieval guide · OpenAPI openapi-master.yaml. Last verified: 2026-09-18. Machine-readable twins: generated/fragments/endpoints/openai-files-vectorstores-batch-finetuning-evals.json, generated/fragments/parameters/openai-files.json, openai-uploads.json, generated/fragments/objects/openai-platform-objects.json, generated/fragments/status-lifecycles/openai-lifecycles.json.

Files are the storage primitive shared by Batch, Fine-tuning, Evals, vector stores / file_search, and file inputs (input_file) to Responses. Uploads is the multipart variant for large files (> what a single POST /v1/files request can carry).

# 1. Endpoints

Method / path SDK (python / node) Notes 2026-09-18
POST /v1/files (multipart) client.files.create / client.files.create fields file, purpose, optional expires_after[anchor]=created_at, expires_after[seconds] 200, purposes user_data, batch, evals, assistants
GET /v1/files files.list ?purpose=, limit 1–10 000 (default 10 000), order asc/desc, after cursor 200
GET /v1/files/{file_id} files.retrieve 200; 404 No such File object after delete
DELETE /v1/files/{file_id} files.delete → {object:"file", id, deleted:true} 200
GET /v1/files/{file_id}/content files.content / files.retrieveContent raw bytes 200 for batch_output; 400 Not allowed to download files of purpose: user_data
POST /v1/uploads client.uploads.create JSON {filename, purpose, bytes, mime_type, expires_after?} 200, status pending
POST /v1/uploads/{id}/parts (multipart) uploads.parts.create field data (bytes chunk) → {object:"upload.part", id} 200
POST /v1/uploads/{id}/complete uploads.complete {part_ids:[ordered], md5?} → status completed, file populated 200
POST /v1/uploads/{id}/cancel uploads.cancel status cancelled; further parts → 400 200

No streaming, no beta header. All list endpoints use cursor pagination (after, limit) and return {object:"list", data, first_id, last_id, has_more}.

# 2. Purposes

purpose (request) Consumed by Content rules Download (/content)
assistants vector stores / file_search, Assistants (legacy), code interpreter supported MIME list (see §5), ≤ 5M tokens for vector stores not allowed for user content (docs)
batch Batch API input_file_id .jsonl, ≤ 200 MB, ≤ 50 000 lines, one model per file input: not needed; outputs (batch_output) downloadable (verified)
fine-tune training_file / validation_file .jsonl chat / preference / RFT formats results (fine-tune-results) downloadable
vision vision fine-tuning images JPEG/PNG/WEBP —
user_data Responses input_file, generic storage, vector stores any 400 not allowed (verified)
evals Evals run data_source.source.type=file_id .jsonl lines {"item":{…},"sample"?:{…}} —
response-only: assistants_output, batch_output, fine-tune-results produced by the platform downloadable

Observation: evals is accepted by the API and by the guide, and the OpenAPI enum lists it as well; the File object enum (response side) does not list evals, yet the live response returned "purpose": "evals".

# 3. Limits (documented) and retention

Item Value Source
Max size per file (POST /v1/files) 512 MB Files reference
Project storage cap 2.5 TB per project; no org-wide cap Files reference
Upload rate limit 1 000 requests/min per authenticated user Files reference
Batch input .jsonl ≤ 200 MB; ≤ 50 000 requests Files reference / Batch guide
Vector store ingestion ≤ 512 MB and ≤ 5 000 000 tokens per file; 2 000 attached files/min/org Retrieval guide / Files reference
Responses input_file ≤ 50 MB per file and per request (all files combined) File inputs guide
Uploads API one Upload ≤ 8 GB total; each Part ≤ 64 MB; Upload expires 1 hour after creation Uploads reference (observed expires_at = created_at + 3600)
expires_after.seconds 3 600 – 2 592 000 (1 h – 30 d), anchor created_at only OpenAPI
Default expiry purpose=batch files: 30 days (observed expires_at = created_at + 30 d); others: never (expires_at: null) Files reference (observed)

Observed on 2026-09-18: expires_after given as multipart fields (expires_after[anchor], expires_after[seconds]=3600) produced expires_at = created_at + 3600 on a user_data file. On POST /v1/uploads, passing expires_after {seconds: 3600} produced the same expires_at as without it (upload TTL is 1 h either way); the resulting File had expires_at: null — so expires_after on Uploads is UNVERIFIED as a File expiry mechanism.

# 4. Objects

File (object: "file"): id (file-…), bytes, created_at, expires_at (int | null), filename, purpose, status (deprecated: uploaded | processed | error — observed processed immediately), status_details (deprecated).

Upload (object: "upload"): id (upload_…), bytes (declared), created_at, expires_at, filename, purpose, status (pending | completed | cancelled | expired), file (File, only after complete).

UploadPart (object: "upload.part"): id (part_…), created_at, upload_id.

Lifecycles: see generated/fragments/status-lifecycles/openai-lifecycles.json (upload, file).

# 5. Supported formats for retrieval (assistants / user_data into vector stores)

.c .cpp .cs .css .doc .docx .go .html .java .js .json .md .pdf .php .pptx .py .rb .sh .tex .ts .txt with the MIME types listed in the Retrieval guide; text/* must be utf-8 / utf-16 / ascii. Images and audio are not indexable. (Responses input_file accepts a wider set incl. rich documents; see the tools agent's docs/tools/ pages.)

# 6. Uploads protocol (large files)

  1. POST /v1/uploads {filename, purpose, bytes, mime_type} → Upload pending. Declared bytes must equal the sum of parts at completion.
  2. POST /v1/uploads/{id}/parts for each chunk (≤ 64 MB each, any order, parallel allowed) — multipart field data.
  3. POST /v1/uploads/{id}/complete {part_ids: [in order], md5?} → completed, file.id usable everywhere a File is.
  4. Or POST …/cancel → cancelled (parts can no longer be added; verified 400).

Observed: the OpenAPI enum for purpose on POST /v1/uploads is assistants | batch | fine-tune | vision, yet user_data was accepted (200) and propagated to the resulting File → LIVE_DISCOVERED.

# 7. Errors seen

Call HTTP Body
GET /files/{id}/content (user_data) 400 {"error":{"message":"Not allowed to download files of purpose: user_data","type":"invalid_request_error"}}
GET /files/{deleted} 404 {"error":{"message":"No such File object: file-…","type":"invalid_request_error","param":"id"}}
POST /uploads/{cancelled}/parts 400 Upload status is already in a cancelled state. Must be in a 'pending' state.

# 8. Cost

File storage itself is not billed (vector-store storage is, see vector-stores.md). The 2026-09-18 tests cost $0 for this area.