Skip to main content
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.
Authorization
string
required
Bearer token obtained from the authenticate endpoint.
files
file[]
required
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
chat_id
string
required
ID of an existing chat to attach the files to. Obtain one from Create Chat.

Response

chat_id
string
required
The chat the files were uploaded to. If no chat_id was provided in the request, this is the newly created chat’s ID.
uploads
array
required
List of successfully processed uploads.
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);
{
  "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
}