POST
/v1/filesFiles
Upload and manage files used elsewhere in the API: batch input JSONL, Assistants/RAG attachments, and vision inputs. Upload is multipart/form-data; everything else (list, retrieve, delete, download content) is JSON/bytes. Files are private to your developer account. Bearer key only (client tokens are rejected 403).
Request
- HTTP
- POST
- URL
- /v1/files
- Auth
- api_key
Try it
# upload a JSONL for batch processing
curl https://api.fightclub.pro/v1/files \
-H "Authorization: Bearer $FC_API_KEY" \
-F purpose=batch -F file=@input.jsonl
# => { "id":"file_abc", "object":"file", "bytes":1048576, "purpose":"batch", ... }
# list, then download the content
curl "https://api.fightclub.pro/v1/files?purpose=batch&limit=20" \
-H "Authorization: Bearer $FC_API_KEY"
curl https://api.fightclub.pro/v1/files/file_abc/content \
-H "Authorization: Bearer $FC_API_KEY" -o input.jsonlExample response
{
"id": "file_xyz789",
"object": "file",
"bytes": 482113,
"filename": "handbook.pdf",
"purpose": "attachments",
"mime_type": "application/pdf",
"created_at": 1782300000
}A representative 200 body. Ids and timestamps are illustrative.
Body parameters
| Name | Type | Default | Description |
|---|---|---|---|
| file* | binary | — | The file content, sent as a multipart/form-data part. Max 512 MB. |
| purpose* | string | — | batch (bulk input JSONL), attachments (RAG / Assistants), or vision (image input). Note: OpenAI's "assistants" value is not accepted here, use attachments. |
* required.
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
| purpose | string | optional | On GET /v1/files: filter the list by purpose. |
| limit | integer | 20 | Page size for the list endpoint (max 100). |
| after | string | optional | Cursor: the last file id from the previous page. |
Headers
| Header | Dir | Description |
|---|---|---|
| Authorization | req → | Bearer <api_key>. Client tokens cannot call /v1/files (403 endpoint_not_allowed_for_client_token). |
| Content-Type | req → | multipart/form-data for upload; the SDK sets this for you. |
Response fields
| Name | Type | Description |
|---|---|---|
| id | string | File id (file_*). |
| object | string | "file". |
| bytes | integer | Stored size in bytes. |
| created_at | integer | Unix timestamp. |
| filename | string | Original filename. |
| purpose | string | Echoed purpose. |
| mime_type | string | Detected content type. application/octet-stream uploads are sniffed from the extension. |
| expires_at | integer | null | Unix timestamp the file is auto-purged, or null if it does not expire. |
Errors
- 401
missing_tokenNo Authorization header was sent. - 401
invalid_auth_schemeThe scheme was neither Bearer nor Client. - 401
invalid_token_formatA Bearer token not prefixed ko_. - 401
invalid_tokenThe API key is unknown, revoked or expired. - 403
insufficient_scopeThe key is valid but lacks the required scope. - 403
endpoint_not_allowed_for_client_tokenA client token tried to use /v1/files. - 400
missing_purposepurpose is required. - 400
missing_fileNo file part in the multipart body. - 400
invalid_purposepurpose must be batch, attachments or vision. - 413
file_too_largeOver the 512 MB per-file limit. - 409
file_in_useDELETE blocked: the file is still referenced (e.g. by a vector store or batch). - 404
not_foundNo such file (also cross-tenant).
See the full error reference.
Related routes
| GET | /v1/files | List your files. Query: purpose, limit (default 20, max 100), after. |
| GET | /v1/files/{id} | Retrieve one file's metadata. |
| DELETE | /v1/files/{id} | Delete a file (409 file_in_use if still referenced). |
| GET | /v1/files/{id}/content | Download the raw bytes (streamed). |
Notes
- ·Upload is the only multipart endpoint; list/retrieve/delete return JSON and /content streams the bytes back.
- ·A batch input file must be uploaded with purpose=batch before POST /v1/batches will accept it.
- ·Delete is blocked while a file is referenced; detach it from the vector store or wait for the batch to finish, then retry.