/s3/* REST endpoints that let API clients upload, list, download, and delete files against the platform’s configured bucket without needing the underlying MinIO or S3 credentials. The backend holds the credentials, generates a short-lived presigned URL, and the client uploads directly to the object store.
There is a separate, higher-level flow for agent session attachments under
POST /sessions/{sessionId}/files/upload-sign — see the REST API introduction. Use the endpoints on this page when you need general-purpose storage that isn’t tied to a specific chat session.Authentication
All endpoints accept the standard API-key header:x-api-key also works, and browser clients may authenticate with a NextAuth session JWT via Authorization: Bearer <token>. See Authentication for details.
Key namespacing
Uploads are automatically scoped to the caller:
The server-configured
s3prefix (see S3 storage) is prepended on top of that. Clients should not construct their own key paths — the server rewrites the key it returns.
Simple upload (single PUT)
Use this for files that comfortably fit in a single HTTP request (typical rule of thumb: up to a few hundred MB, depending on your network).1. Request a presigned URL — POST /s3/sign
Response:
key is the object key without the user/global and s3prefix segments. Keep it — you’ll need it to reference the file later. The presigned URL expires after 24 hours.
2. Upload the bytes
Content-Type header must match the type you sent in step 1, or the signature will fail.
Multipart upload (large files)
Use multipart when the file is too large for a single request or you need parallel/resumable uploads.1. Initiate — POST /s3/multipart
/s3/sign, key here is the full key including all prefixes — the multipart protocol re-signs each part from this key, so you must pass it back verbatim on subsequent calls.
2. Sign each part — GET /s3/multipart/{uploadId}/{partNumber}?key=<key>
partNumber must be an integer between 1 and 10000. Upload each part with a PUT to the returned URL and capture the ETag header from the response.
3. Complete — POST /s3/multipart/{uploadId}/complete
Additional multipart endpoints
Working with uploaded files
Keys returned by
/s3/list are prefixed with the bucket name (e.g. exulu-uploads/api/uuid-_EXULU_report.pdf) — pass that full string to /s3/download and /s3/delete.
Availability
These endpoints are only mounted when the deployment is configured withCOMPANION_S3_* variables. If file uploads are not configured the backend logs [EXULU] skipping uppy file upload routes at startup and every /s3/* request will 404. See S3 storage for the operator setup.