Give an agent files and data

Create a store, put documents and files in it, attach it to an agent

A store is a workspace-owned place an agent can read from and write to. It holds two different things, and the difference matters:

  • Documents are JSON objects in named collections. The agent queries and writes them - a list of leads it is working through, the notes it took, a record per customer.
  • Files are whatever you upload: a PDF, a Markdown file, a page of prose. The agent reads them as text.

Nothing an agent does is remembered by a store unless it writes it there, and everything it writes stays until you delete it.

Stores are in beta and enabled per workspace. Without the grant every store endpoint answers 402.

Create a store

POST
/v1/stores
1curl -X POST https://api.speechify.ai/v1/stores \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "name": "news"
6}'

Give it a name and a description that says what is in it. An attached agent is shown both, and they are how it decides whether to look here at all - “Customer contracts, one document per account” earns a lookup that “store1” does not.

Put documents in it

A document is a JSON object with an id you choose, inside a collection you name. There is no schema to declare: the collection is created by the first write.

PUT
/v1/stores/:store_id/collections/:collection/documents/:document_id
1curl -X PUT https://api.speechify.ai/v1/stores/store_01jqr8x9zg5k2m3n4p5q6r7s8t/collections/items/documents/2026-09-02-openai-ships \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "data": {}
6}'

Choose an id derived from the content - a URL, a slug, an account number - so writing the same thing twice updates one document instead of making two.

Read them back by id, or query a collection with filters and ordering:

POST
/v1/stores/:store_id/collections/:collection/documents/query
1curl -X POST https://api.speechify.ai/v1/stores/store_01jqr8x9zg5k2m3n4p5q6r7s8t/collections/items/documents/query \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: application/json" \
4 -d '{}'

Only top-level string, number, boolean and null fields are queryable, and results are paged - follow next_cursor.

Writing many at once is one call:

POST
/v1/stores/:store_id/collections/:collection/documents/batch
1curl -X POST https://api.speechify.ai/v1/stores/store_01jqr8x9zg5k2m3n4p5q6r7s8t/collections/items/documents/batch \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "writes": [
6 {
7 "op": "set"
8 }
9 ]
10}'

Upload files

POST
/v1/stores/:store_id/assets
1curl -X POST https://api.speechify.ai/v1/stores/store_01jqr8x9zg5k2m3n4p5q6r7s8t/assets \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: multipart/form-data" \
4 -F file=@"[object Object]"

A multipart upload, up to 25 MiB per file. You get an asset_... id back; that id is what you hand the agent.

Read the bytes back whenever you need them:

GET
/v1/stores/:store_id/assets/:asset_id/bytes
1curl https://api.speechify.ai/v1/stores/store_01jqr8x9zg5k2m3n4p5q6r7s8t/assets/asset_01jqr8x9zg5k2m3n4p5q6r7s8t/bytes \
2 -H "Authorization: Bearer <token>"

Attach the store to an agent

POST
/v1/agents/:agent_id/stores/:store_id
1curl -X POST https://api.speechify.ai/v1/agents/agent_01jqr8x9zg5k2m3n4p5q6r7s8t/stores/store_01jqr8x9zg5k2m3n4p5q6r7s8t \
2 -H "Authorization: Bearer <token>"

Attaching is what puts the store tools in the agent’s hands. From then on a run of that agent can call store_query, store_get, store_put, store_delete and store_read_asset without you configuring anything else - see Run an agent asynchronously.

What the agent can actually read

store_read_asset extracts text from PDF, plain text, Markdown and HTML only, and refuses a file over 10 MiB - which is lower than the 25 MiB a store will happily accept. A DOCX, an EPUB or an image comes back as an error the agent reads and works around, which means the run still succeeds, without the document. If the format matters, convert before you upload.

Point the agent at a file by putting the id in the run’s instruction or variables. Your application knows which document its user opened; the agent does not need to go looking.

1{
2 "instruction": "Summarize the attached contract and list every renewal date.",
3 "variables": { "contract": "asset_01kr41f8m2p7q3v9x0y1z2a3b4" }
4}

Limits

Per document: 256 KiB. Per file: 25 MiB to store, 10 MiB to read into a run. Your plan sets how many stores you may have, how many documents each holds, and the total bytes - a document library reaches the byte ceiling long before the count. Breaching one is a 409 naming which ceiling it was: store_limit_reached, store_document_limit_reached or store_bytes_limit_reached.

Next