Upload one or more files to an existing chat session. Supported file types include documents (PDF, CSV, XLSX) and images (PNG, JPG).
chat_id is now required. Call Create Chat first to obtain one — uploads without chat_id return 400 MISSING_CHAT_ID, and an unknown ID returns 404 Chat not found.
Uploaded files are processed server-side: documents are parsed and chunked for retrieval, images are captioned and embedded. After uploading, reference the returned upload IDs in a Send Message request to attach them to a conversation turn.
This endpoint is rate-limited to 30 requests per minute per JWT . Excess requests return 429 with a Retry-After header.
Bearer token obtained from the authenticate endpoint.
One or more files to upload. Sent as multipart/form-data. Maximum 5 files per request, each up to 30 MB. Supported MIME types:
application/pdf
text/csv
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (XLSX)
image/png
image/jpeg
ID of an existing chat to attach the files to. Obtain one from Create Chat .
Response
The chat the files were uploaded to. If no chat_id was provided in the request, this is the newly created chat’s ID.
List of successfully processed uploads. Unique identifier for the upload. Use this in the upload_ids field when sending a message.
MIME type of the uploaded file.
Either "document" or "image".
Temporary download URL for the file. Expires after 1 hour.
ISO 8601 timestamp when the upload was created.
ID of the chat message this upload is attached to. null until the upload is referenced via upload_ids in a Send Message or WebSocket request.
curl -X POST https://api.trellis.sh/v1/chats/uploads \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "files=@report.pdf" \
-F "files=@data.csv" \
-F "chat_id=chat_abc123"
import requests
with open ( "report.pdf" , "rb" ) as pdf, open ( "data.csv" , "rb" ) as csv:
response = requests.post(
"https://api.trellis.sh/v1/chats/uploads" ,
headers = { "Authorization" : "Bearer YOUR_TOKEN" },
files = [
( "files" , ( "report.pdf" , pdf, "application/pdf" )),
( "files" , ( "data.csv" , csv, "text/csv" )),
],
data = { "chat_id" : "chat_abc123" },
)
result = response.json()
upload_ids = [u[ "id" ] for u in result[ "uploads" ]]
const form = new FormData ();
form. append ( "files" , pdfBlob, "report.pdf" );
form. append ( "files" , csvBlob, "data.csv" );
form. append ( "chat_id" , "chat_abc123" );
const response = await fetch ( "https://api.trellis.sh/v1/chats/uploads" , {
method: "POST" ,
headers: { Authorization: "Bearer YOUR_TOKEN" },
body: form,
});
const { chat_id , uploads } = await response. json ();
const uploadIds = uploads. map (( u ) => u.id);
200
400 Unsupported file type
400 Too many files
400 File too large
400 Missing chat_id
404 Chat not found
429 Rate limited
{
"chat_id" : "chat_abc123" ,
"uploads" : [
{
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"filename" : "report.pdf" ,
"mime_type" : "application/pdf" ,
"file_size" : 245760 ,
"upload_type" : "document" ,
"presigned_url" : "https://s3.amazonaws.com/..." ,
"created_at" : "2025-06-15T09:30:00Z" ,
"message_id" : null
},
{
"id" : "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ,
"filename" : "data.csv" ,
"mime_type" : "text/csv" ,
"file_size" : 1024 ,
"upload_type" : "document" ,
"presigned_url" : "https://s3.amazonaws.com/..." ,
"created_at" : "2025-06-15T09:30:01Z" ,
"message_id" : null
}
]
}
{
"detail" : "Unsupported file type 'application/octet-stream' for 'archive.bin'. Allowed: PNG, JPG, PDF, CSV, XLSX"
}
{
"detail" : "Maximum 5 files per request"
}
{
"detail" : "File 'large.pdf' exceeds 30MB limit (45.2MB)"
}
{
"detail" : {
"code" : "MISSING_CHAT_ID" ,
"message" : "Provide chat_id; create one via POST /v1/chats/create"
}
}
{
"detail" : "Chat not found"
}
{
"detail" : "Rate limit exceeded" ,
"retry_after_seconds" : 8
}