Files API
Use the Files API to upload and manage documents for your organization. Files are org-scoped — a file is only visible to the organization that created it.
After upload, reference a file by file_id: a file part on
Chat Completions, or an input_file part on
the Responses API. See Sending files
for the request shapes and for when to upload rather than inline a document.
All requests require a valid API key:
Authorization: Bearer $SUBQ_API_KEYSee Authentication for details.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /v1/files | Upload a file (multipart) |
GET | /v1/files | List the org's files |
GET | /v1/files/{file_id} | Retrieve one file |
DELETE | /v1/files/{file_id} | Delete a file |
Limits
- Max size: 50 MB per file.
- Purpose:
assistants(only value accepted today). - Supported types: plain text (
.txt,.md,.csv,.tsv), JSON / JSONL, XML, PDF, and Word (.doc,.docx).
File object
| Field | Type | Description |
|---|---|---|
id | string | File identifier (file_…). Use as file_id in Chat Completions or Responses. |
object | string | Always "file". |
bytes | number | Size in bytes. |
created_at | number | Unix timestamp (seconds) when the file was created. |
expires_at | number or null | Expiration timestamp, if any. |
filename | string | Original file name. |
purpose | string | Intended purpose (assistants). |
status | string or null | Lifecycle status (see below). |
Statuses
| Status | Meaning |
|---|---|
uploaded | Bytes stored and validated. Non-text files may still be extracting text. |
processed | Content available for Chat Completions and Responses. Text files reach this immediately. |
error | Processing failed. (Reserved.) |
Upload file
POST /v1/filesUpload bytes through the API as multipart/form-data.
| Field | Required | Description |
|---|---|---|
file | Yes | The file part. |
purpose | Yes | Must be assistants. |
The file part must carry a Content-Type from the supported types.
A part sent as application/octet-stream is rejected with unsupported_file_type,
so set the type explicitly when your HTTP client does not infer it from the
filename — as the TypeScript example below does with toFile().
Response
{
"id": "file_abc123",
"object": "file",
"bytes": 12345,
"created_at": 1753742400,
"expires_at": null,
"filename": "report.pdf",
"purpose": "assistants",
"status": "uploaded"
}List files
GET /v1/files| Param | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Page size (1–10000). |
order | string | desc | Sort by creation time: asc or desc. |
after | string | — | Keyset cursor; start after this file id. |
purpose | string | — | Optional filter (assistants). |
Response
{
"object": "list",
"data": [
{
"id": "file_abc123",
"object": "file",
"bytes": 12345,
"created_at": 1753742400,
"expires_at": null,
"filename": "report.pdf",
"purpose": "assistants",
"status": "processed"
}
],
"first_id": "file_abc123",
"last_id": "file_abc123",
"has_more": false
}Paginate with last_id as the next after value until has_more is false.
Retrieve file
GET /v1/files/{file_id}Returns the File object, or 404 if missing or owned by another org.
Delete file
DELETE /v1/files/{file_id}Removes stored bytes and metadata.
Response
{
"id": "file_abc123",
"object": "file",
"deleted": true
}Errors
Errors use the OpenAI shape:
{
"error": {
"message": "No such File object: file_abc123",
"type": "invalid_request_error",
"code": "not_found",
"param": null
}
}| HTTP | code | When |
|---|---|---|
400 | validation_error | Missing or invalid params |
400 | unsupported_file_type | MIME type not in the supported set |
401 | invalid_api_key | Missing or invalid API key |
403 | org_suspended | Organization is suspended or inactive |
404 | not_found | File missing or owned by another org |
413 | file_too_large | Upload exceeds 50 MB |
Related
- Sending files — referencing an uploaded file in a request
- Chat Completions API —
fileparts onmessages - Responses API —
input_fileparts oninput - Authentication — API keys