Files API
Upload a file once, get back an id, and use that id in as many requests as you like: documents in chat, images for vision, input lists for batches, and inputs and outputs for code execution. Files belong to your workspace; no other organisation can read them.
When to use it
- The same document is used in many requests.
- The file is bigger than the inline limits (10 MB for documents, 5 MB for images).
- You need to submit a batch, or collect files that code execution produced.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/files | Upload a file (multipart form). |
GET | /v1/files | List files, newest first. |
GET | /v1/files/{file_id} | Get one file’s details. |
GET | /v1/files/{file_id}/content | Download the bytes. |
DELETE | /v1/files/{file_id} | Delete a file now. |
All use Authorization: Bearer sk_live_.... Base URL https://app.syntic.ai/v1 (the paths above already include /v1).
Upload
POST /v1/files with Content-Type: multipart/form-data.
| Form field | Required | Details |
|---|---|---|
file | Yes | The file bytes, with a filename. |
purpose | Yes | document, vision, batch, code_input or skill. Controls which types are accepted. |
expires_after_days | No | 1 to 90. Defaults to 30. |
purpose | Accepted types |
|---|---|
document | PDF, DOCX, PPTX, XLSX, CSV, TXT, MD, HTML, JSON |
vision | PNG, JPEG, WebP, GIF |
batch | JSONL in the batch input format |
code_input | Any type |
skill | ZIP |
The file object
{
"id": "file_01JBW9Q6RZ",
"object": "file",
"filename": "lease.pdf",
"purpose": "document",
"bytes": 482113,
"mime_type": "application/pdf",
"created_at": 1791820800,
"expires_at": 1794412800,
"status": "ready",
"source": "upload",
"workspace_id": "wrk_01HZY"
}| Field | Description |
|---|---|
id | file_ prefix. Use it in requests. |
status | processing while it is scanned and prepared, then ready, or failed with status_detail. Requests that use a file still processing wait up to 30 seconds. |
source | upload, batch_output or code_execution. Files Syntic created for you can be downloaded the same way. |
expires_at | Unix seconds. The file is deleted at this time. null never happens: every file expires. |
List
GET /v1/files?purpose=document&limit=20&after=file_01JBW9Q6RZ
| Query | Details |
|---|---|
purpose | Filter by purpose. |
limit | 1 to 100, default 20. |
after_id | Return files after this id (the next page): the last_id of the previous page. |
before_id | Return files before this id (the previous page). |
{ "object": "list", "data": [ { "id": "file_01JBW9Q6RZ", "...": "..." } ], "has_more": false, "first_id": "file_01JBW9Q6RZ", "last_id": "file_01JBW9Q6RZ" }Download and delete
GET /v1/files/{id}/content returns the raw bytes with the stored Content-Type and a Content-Disposition filename. Uploaded files with purpose document or vision can be downloaded only by keys in the same workspace.
DELETE /v1/files/{id} returns {"id": "file_...", "object": "file", "deleted": true}. Requests already running keep their copy until they finish.
Examples
# Upload
curl https://app.syntic.ai/v1/files \
-H "Authorization: Bearer $SYNTIC_API_KEY" \
-F purpose=document \
-F file=@lease.pdf
# Use it
curl https://app.syntic.ai/v1/chat/completions \
-H "Authorization: Bearer $SYNTIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"Amara S1.2","stream":false,"messages":[{"role":"user","content":[
{"type":"file","file":{"file_id":"file_01JBW9Q6RZ"}},
{"type":"text","text":"Summarise the break clause."}]}]}'
# Delete
curl -X DELETE https://app.syntic.ai/v1/files/file_01JBW9Q6RZ \
-H "Authorization: Bearer $SYNTIC_API_KEY"Errors
| Status | code | Cause |
|---|---|---|
| 400 | invalid_purpose | Unknown purpose. |
| 400 | unsupported_file_type | Type not accepted for the purpose. |
| 400 | file_failed | The file is in failed status and cannot be used. |
| 404 | file_not_found | Unknown id, expired, deleted or in another workspace. Syntic never says which. |
| 409 | file_processing | Still processing after 30 seconds. Try again. |
| 413 | file_too_large | Over the size limit. |
| 507 | storage_quota_exceeded | Workspace storage is full. Delete files or raise the limit. |
Limits
| Limit | Value |
|---|---|
| File size | 100 MB (500 MB for batch and code_input) |
| Storage per workspace | 100 GB |
| Files per workspace | 10,000 |
| Retention | 1 to 90 days, default 30 |
Pricing and retention
Storage is free within the limits. Organisations with zero data retention can upload only with expires_after_days: 1, and files are removed as soon as the last request using them ends. See Data retention.
Build notes for the platform team
- Storage bucket per org, path
org/{org_id}/workspace/{workspace_id}/{file_id}; signed URLs never leave the API. - Malware scan on upload for
documentandcode_input;status: processingcovers it. - Every lookup filters by workspace; return
404, never403, for other tenants’ ids.