Upload a file for a Research Agent session
Stage a file so it can be attached to a Research Agent turn. This is a two-step, presigned upload:
- POST /api/v2/files with the filename, MIME type, and exact byte size. The response returns a file_id and a short-lived presigned upload_url.
- PUT the raw file bytes to upload_url with the same Content-Type and a Content-Length matching size_bytes. Do not send an Authorization header on the PUT — the URL is already signed.
Then pass { "file_id": "..." } in the attachments array of a create-session or send-message request. Attached files are made available to the agent exactly as uploads made in the web interface are.
The request/response fields for this endpoint are deliberately snake_case (content_type, size_bytes, file_id, upload_url, expires_at), unlike the camelCase used elsewhere in the v2 surface. Files are capped at 30 MB, and a session accepts a bounded number of attachments; the upload_url and file_id expire at expires_at.
This endpoint is in early access. It returns 404 not_found unless the Research Agent API has been enabled for the authenticated account or organization.
Example
# 1. Register the upload
curl -X POST https://elicit.com/api/v2/files \
-H "Authorization: Bearer elk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"filename":"trial-results.pdf","content_type":"application/pdf","size_bytes":245678}'
# 2. Upload the bytes to the returned upload_url
curl -X PUT "{upload_url}" \
-H "Content-Type: application/pdf" \
--data-binary @trial-results.pdf
# 3. Attach {"file_id": "..."} to a create-session or /messages request
Request body
Example request
{
"filename": "trial-results.pdf",
"content_type": "application/pdf",
"size_bytes": 245678
}Response
Upload registered. PUT the file bytes to upload_url before it expires.
Example response
{
"file_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"expires_at": "2026-07-23T15:00:00.000Z"
}