Attach a file to a run

Upload a file, pass its id on the run, and the agent reads it

Someone sends your agent a receipt, a supplier PDF, a spreadsheet of listings. Upload it, name it on the run, and the agent reads it while it works.

Files are in beta and enabled per workspace, alongside durable runs. Without the grant every file endpoint answers 402.

Upload the file

POST
/v1/files
1curl -X POST https://api.speechify.ai/v1/files \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: multipart/form-data" \
4 -F file=@"[object Object]" \
5 -F project_id='{
6 "type": "json"
7}' \
8 -F user_identity='{
9 "type": "json"
10}'

A multipart upload, up to 25 MiB. You get a file_... id back.

Hand it to a run

POST
/v1/agents/:agent_id/runs
1curl -X POST https://api.speechify.ai/v1/agents/agent_01jqr8x9zg5k2m3n4p5q6r7s8t/runs \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "instruction": "Summarize this week'\''s open support tickets and draft a reply to the oldest."
6}'
1{
2 "instruction": "Read the attached invoice. What is the total, and when is it due?",
3 "attachments": ["file_01jqr8x9zg5k2m3n4p5q6r7s8t"]
4}

The agent is told what it is holding and reads a file with its read_file tool. Nothing else to configure: no store, no collection, no attaching a resource to the agent first.

A team run takes the same field, and so does a trigger’s run spec - a nightly job can work over a standing document.

What the agent can read

TypeWhat the agent gets
PDF, plain text, Markdown, HTMLThe extracted text, in reading order
PNG, JPEG, WebP, GIF and other imagesA transcription of every word in the picture, plus a short description of what it shows
Anything elseAn error the agent reads and works around

A long file arrives one slice at a time; the agent asks for the next slice itself. A file over 10 MiB is stored and downloadable but too large for an agent to read into a run.

A scanned PDF - a photograph saved as a document rather than a page of text - extracts to nothing, and the agent is told so rather than being handed an empty page. Upload the scan as an image instead, and it is transcribed.

Scope a file to one person

If your product has end users, scope each upload to the one it belongs to:

$curl -X POST https://api.sws.speechify.com/v1/files \
> -H "Authorization: Bearer $SPEECHIFY_API_KEY" \
> -F "file=@invoice.pdf" \
> -F "user_identity=acme-user-4821"

Only a run whose user_identity matches can read it. Start a run for a different person and the id is refused at admission - it does not exist as far as that run is concerned.

Leave user_identity off and the file is workspace-wide: any run in the workspace can read it. That is the right shape for your own operational documents, and the wrong one for your customers’ uploads.

A file the agent cannot read fails the request

Every id is checked when the run is created. An id that does not exist, has expired, or belongs to another person fails with a 400 naming attachments:

1{
2 "error": {
3 "code": "validation_failed",
4 "message": "attachment file_01jqr8x9zg5k2m3n4p5q6r7s8t does not exist, has expired, or belongs to another person",
5 "fields": { "attachments": "attachment file_01jqr8x9zg5k2m3n4p5q6r7s8t does not exist, has expired, or belongs to another person" }
6 }
7}

The run is never started over a file it cannot read, so an agent never answers confidently from a document that was not there.

When a tool answers with a file

If one of the agent’s tools responds with something that is not text - a generated PDF, a rendered chart, an exported sheet - the response is kept as a file and the agent is handed its id, which it can then read like any attachment. It shows up in GET /v1/files with a source naming the run that produced it.

Limits

  • 25 MiB per file to store, 10 MiB to read into a run.
  • 10 attachments per run.
  • A file is deleted 14 days after upload. expires_at on every file says exactly when; after it passes, every read answers 404. Delete one sooner with DELETE /v1/files/{file_id}.

Files are working material for a run, not a library. For documents an agent should search across many runs, use a knowledge base instead.

Next