Skip to main content

Overview

The Uploads API provides endpoints to upload, list, and delete files for specific threads. Uploaded files are stored in thread-specific directories and can be accessed by AI agents. Certain file types (PDF, Office documents) are automatically converted to markdown.

Upload Files

POST /api/threads/{thread_id}/uploads

Upload multiple files to a thread’s uploads directory

Path Parameters

thread_id
string
required
The thread ID to upload files to

Request Body

Multipart form data with one or more files:
files
file[]
required
List of files to upload (multipart/form-data)

Response

success
boolean
required
Whether the upload was successful
files
array
required
List of uploaded file information
message
string
required
Success message with upload count

Example Request

curl -X POST http://localhost:8001/api/threads/abc123/uploads \
  -F "[email protected]" \
  -F "[email protected]" \
  -F "[email protected]"

Example Response

{
  "success": true,
  "files": [
    {
      "filename": "document.pdf",
      "size": "1048576",
      "path": "sandbox/threads/abc123/uploads/document.pdf",
      "virtual_path": "/mnt/user-data/uploads/document.pdf",
      "artifact_url": "/api/threads/abc123/artifacts/mnt/user-data/uploads/document.pdf",
      "markdown_file": "document.md",
      "markdown_path": "sandbox/threads/abc123/uploads/document.md",
      "markdown_virtual_path": "/mnt/user-data/uploads/document.md",
      "markdown_artifact_url": "/api/threads/abc123/artifacts/mnt/user-data/uploads/document.md"
    },
    {
      "filename": "image.png",
      "size": "524288",
      "path": "sandbox/threads/abc123/uploads/image.png",
      "virtual_path": "/mnt/user-data/uploads/image.png",
      "artifact_url": "/api/threads/abc123/artifacts/mnt/user-data/uploads/image.png"
    },
    {
      "filename": "data.csv",
      "size": "2048",
      "path": "sandbox/threads/abc123/uploads/data.csv",
      "virtual_path": "/mnt/user-data/uploads/data.csv",
      "artifact_url": "/api/threads/abc123/artifacts/mnt/user-data/uploads/data.csv"
    }
  ],
  "message": "Successfully uploaded 3 file(s)"
}

Auto-Conversion to Markdown

The following file types are automatically converted to markdown using markitdown:
  • .pdf - PDF documents
  • .ppt, .pptx - PowerPoint presentations
  • .xls, .xlsx - Excel spreadsheets
  • .doc, .docx - Word documents
Both the original file and the converted markdown file are saved and accessible.

Error Responses

400
Bad Request
No files provided or invalid filename
{
  "detail": "No files provided"
}
500
Internal Server Error
Upload failed
{
  "detail": "Failed to upload file.pdf: [error details]"
}

Security

  • Filenames are sanitized to prevent path traversal attacks
  • Only the filename component is used (directory paths are stripped)
  • Files with unsafe names (., .., containing / or \) are rejected

List Uploaded Files

GET /api/threads/{thread_id}/uploads/list

List all files in a thread’s uploads directory

Path Parameters

thread_id
string
required
The thread ID to list files for

Response

files
array
required
List of files with metadata
count
integer
required
Total number of files

Example Request

curl http://localhost:8001/api/threads/abc123/uploads/list

Example Response

{
  "files": [
    {
      "filename": "document.pdf",
      "size": 1048576,
      "path": "sandbox/threads/abc123/uploads/document.pdf",
      "virtual_path": "/mnt/user-data/uploads/document.pdf",
      "artifact_url": "/api/threads/abc123/artifacts/mnt/user-data/uploads/document.pdf",
      "extension": ".pdf",
      "modified": 1705318200.0
    },
    {
      "filename": "document.md",
      "size": 4096,
      "path": "sandbox/threads/abc123/uploads/document.md",
      "virtual_path": "/mnt/user-data/uploads/document.md",
      "artifact_url": "/api/threads/abc123/artifacts/mnt/user-data/uploads/document.md",
      "extension": ".md",
      "modified": 1705318201.0
    }
  ],
  "count": 2
}

Empty Directory

If no files have been uploaded:
{
  "files": [],
  "count": 0
}

Delete Uploaded File

DELETE /api/threads/{thread_id}/uploads/{filename}

Delete a file from a thread’s uploads directory

Path Parameters

thread_id
string
required
The thread ID
filename
string
required
The filename to delete

Response

success
boolean
required
Whether the deletion was successful
message
string
required
Success message

Example Request

curl -X DELETE http://localhost:8001/api/threads/abc123/uploads/document.pdf

Example Response

{
  "success": true,
  "message": "Deleted document.pdf"
}

Error Responses

403
Forbidden
Access denied (path traversal attempt)
{
  "detail": "Access denied"
}
404
Not Found
File not found
{
  "detail": "File not found: document.pdf"
}
500
Internal Server Error
Deletion failed
{
  "detail": "Failed to delete document.pdf: [error details]"
}

File Storage

Directory Structure

backend/
└── sandbox/
    └── threads/
        └── {thread_id}/
            └── uploads/
                ├── document.pdf
                ├── document.md  (auto-converted)
                ├── image.png
                └── data.csv

Virtual Paths

Files are accessible to AI agents via virtual paths:
/mnt/user-data/uploads/{filename}
Agents can read and process these files using their file tools.

Sandbox Synchronization

For non-local sandboxes (e.g., E2B), files are automatically synced:
  1. Upload: Files are saved to host storage and synced to sandbox
  2. Agent Access: Agents read files from sandbox virtual paths
  3. Source of Truth: Host storage remains the source of truth

Use Cases

Upload Files from Frontend

async function uploadFiles(threadId: string, files: File[]) {
  const formData = new FormData();
  files.forEach(file => {
    formData.append('files', file);
  });
  
  const response = await fetch(
    `http://localhost:8001/api/threads/${threadId}/uploads`,
    {
      method: 'POST',
      body: formData
    }
  );
  
  return response.json();
}

List and Display Files

async function listFiles(threadId: string) {
  const response = await fetch(
    `http://localhost:8001/api/threads/${threadId}/uploads/list`
  );
  const { files, count } = await response.json();
  
  return files.map(file => ({
    name: file.filename,
    size: file.size,
    url: `http://localhost:8001${file.artifact_url}`,
    modified: new Date(file.modified * 1000)
  }));
}

Delete File

async function deleteFile(threadId: string, filename: string) {
  const response = await fetch(
    `http://localhost:8001/api/threads/${threadId}/uploads/${filename}`,
    { method: 'DELETE' }
  );
  return response.json();
}

Access Uploaded Files

After uploading, files can be accessed via:
  1. Artifacts API: GET /api/threads/{thread_id}/artifacts/mnt/user-data/uploads/{filename}
  2. Agent Tools: Agents can read files using their virtual paths
// Download file
const response = await fetch(
  `http://localhost:8001/api/threads/abc123/artifacts/mnt/user-data/uploads/document.pdf?download=true`
);
const blob = await response.blob();

Artifacts API

Access uploaded files

Gateway Overview

Learn about the Gateway API

Build docs developers (and LLMs) love