Theme
LLM files
Upload images and PDFs, then reference the returned file IDs in chat completions. Files belong to the account that uploaded them.
Authentication and model support
Use a server-side API key with llm:write to upload or delete, and llm:read to list or inspect files. {"llm":"access"} grants both. Read model capabilities before uploading. Images require vision; PDFs require both document and vision. Only use advertised capabilities. Each completion rechecks file ownership, expiry and compatibility with the selected model's provider.
Upload a file
Upload one image or PDF for a compatible LLM. Requires llm:write.
| Field | Required | Rules |
|---|---|---|
file | Yes | Exactly one nonempty file, at most 4 MiB |
model | No | Public model ID from /v1/models; choose one that supports the file type |
purpose | No | vision for images or document for PDFs; must match the detected type |
Supported formats are PNG, JPEG, WebP, GIF and PDF. PDFs must have at most 100 pages and pass provider validation. Audio, video, DOCX, external URLs, data URIs and arbitrary provider file IDs are unsupported. The server checks the file contents. Omit unused optional fields instead of sending empty values. Unknown or repeated fields are rejected.
bash
curl --fail-with-body 'https://api.voicelab.uz/v1/files' \
-H "Authorization: Bearer $VOICELAB_API_KEY" \
-F "model=${VOICELAB_MODEL:?Choose a model with document and vision capabilities}" \
-F 'purpose=document' \
-F 'file=@report.pdf;type=application/pdf'If model is omitted, the server chooses a configured upload-capable provider. This does not guarantee that every model can later use that file.
201 Created returns metadata directly, without a data wrapper:
json
{
"id": "file_EXAMPLE",
"object": "file",
"bytes": 24576,
"filename": "report.pdf",
"purpose": "document",
"created_at": 1790856000,
"expires_at": 1793448000
}Both timestamps are Unix seconds. Save the returned opaque ID. Uploads have no Idempotency-Key deduplication contract; an automatic retry can create another file. After a lost response, inspect your file list before uploading again.
Use a file in a completion
Send the VoiceLab file ID in a user message to POST /v1/chat/completions:
json
{
"model": "MODEL_FROM_CATALOG",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Summarize this report."},
{"type": "file", "file": {"file_id": "file_EXAMPLE"}}
]
}],
"max_completion_tokens": 1024
}Replace the model and file placeholders with returned IDs. Content arrays allow 1–12 parts and at most four files per message. A developer conversation can reference at most 16 files in total. File parts are accepted only in user messages.
Media requests reserve a model-context-sized input budget plus the output cap. The server settles actual provider usage and releases the unused reservation. A short file ID can therefore require a larger available credit balance than a short text prompt. Uploading a file does not start a completion.
List files
List your available uploads. Requires llm:read.
| Query | Rules |
|---|---|
limit | 1–100; default 20 |
after | An account-owned file ID from the previous page's last_id |
purpose | Optional vision or document filter |
200 OK returns {"object":"list","data":[...],"has_more":false,"first_id":"file_EXAMPLE","last_id":"file_EXAMPLE"}. Entries use the upload metadata shape. When has_more is true, request the next page with after=last_id. Empty pages have empty first_id and last_id strings.
Get a file
Read account-owned file metadata. Requires llm:read.
Returns 200 with the same metadata shape as upload. There is no public file download endpoint. Expired, deleted or inaccessible files cannot be reused.
Delete a file
Revoke reuse and schedule provider file cleanup. Requires llm:write.
No body is required. 200 OK returns:
json
{"id":"file_EXAMPLE","object":"file","deleted":true}Deletion blocks reuse immediately. The server removes the provider's copy in the background and retries failed cleanup. Files expire after 30 days or at the provider's expiry, whichever comes first. Deleting a chat does not delete its uploads. The configured model provider processes uploaded content.
Limits and errors
Each account can have 25 active uploads and 100 upload attempts per rolling day. Uploads have a two-minute server deadline, with four concurrent uploads per account and 32 per API replica. These slots are separate from generation slots.
| HTTP | Code | Recovery |
|---|---|---|
413 | file_too_large | Reduce the multipart upload to one file within 4 MiB |
415 | unsupported_media_type | Send multipart form data |
422 | validation_error | Check fields, file size, filename and pagination |
422 | unsupported_attachment, invalid_attachment | Check detected format, purpose and PDF contents/page count |
422 | attachment_unavailable | Check ownership, expiry, provider binding and model capabilities |
429 | attachment_quota_exceeded | Remove unneeded active files or wait for the daily limit to clear |
503 | chat_unavailable | Storage or file processing is unavailable; inspect existing files before retrying an upload |
File errors use the standard error envelope, including request_id, even though successful file responses use the shapes above.