Upload File

Beta
Upload one file (multipart form field `file`, at most 25 MiB) so a run can be handed it: pass the returned `id` in `attachments` on `POST /v1/agents/{agent_id}/runs`, a team run, or a trigger's run spec. Scope it with `user_identity` to the person it belongs to, and only a run acting for that person can read it; leave it empty and any run in the workspace can. `kind` decides how long it lives. The default, `ephemeral`, is deleted automatically 14 days after upload (`expires_at`) - working material rather than a corpus; for documents an agent should search later, use a knowledge base. Send `kind: kept` for something that survives until you delete it, and give a `kept` file a `path` to publish it where a hosted-API route can serve it. A workspace's `kept` files are bounded by its plan; past the ceiling an upload answers `409` `file_storage_limit_reached`. An agent reads an attached file inside the run through its `read_file` tool: PDF, HTML, Markdown and plain text are extracted, and an image is transcribed and described by a vision model. Dark launch: requires the `durable_runs_access` entitlement (402 `durable_runs_not_in_plan` otherwise).

Authentication

AuthorizationBearer

Enter your API key with the Bearer prefix, e.g. ‘Bearer sk_…’.

Headers

Speechify-VersionstringOptional

Request

This endpoint expects a multipart form containing a file.
filefileRequired

The file to store (at most 25 MiB).

user_identitystringOptional

The person this file is for, in your own vocabulary - the same value a run, a conversation and a widget session take. Only a run acting for that person can read it. Omit for a workspace-wide file.

kindenumOptional

How long to keep it. ephemeral (the default) is working material for a run and is deleted after 14 days. kept survives until you delete it - use it for anything an agent produced that you intend to keep or serve.

Allowed values:
pathstringOptionalformat: "^[A-Za-z0-9][A-Za-z0-9._~-]*(/[A-Za-z0-9][A-Za-z0-9._~-]*)*$"<=512 characters
Publish the file under this name so a hosted-API route can serve it, for example `index.html` or `reports/q3.html`. Unique among the workspace's live files, and only valid on a `kept` file with no `user_identity` - a path on something that expires in a fortnight is a URL that breaks, and a route answers whoever holds the URL, so it has no person to scope to. A path already in use answers `409`.
project_idstringOptionalformat: "^proj_[0-9a-hjkmnp-tv-z]{26}$"

The project to create the file in, as a proj_... id; omit for the caller’s default.

Response headers

Speechify-Request-IdstringOptional
Unique identifier for this request, present on every response (2xx and non-2xx alike). If the caller sends a `Speechify-Request-Id` request header the server echoes it back (sanitized and length-capped) so one logical request can be traced end-to-end; otherwise the server generates a fresh value. Log it on every response and quote it in support requests - it is the stable handle that ties your observation to Speechify's server-side logs, and it matches the `request_id` field in the error envelope. The legacy alias `X-Request-ID` carries the same value and is still accepted on requests, until 2027-07-24. Prefer the un-prefixed name (RFC 6648).

Response

The stored file.
idstringformat: "^file_[0-9a-hjkmnp-tv-z]{26}$"
filenamestring
content_typestring

The file’s media type, normalised from the upload. An agent can read application/pdf, text/plain, text/markdown, text/html and image/* inside a run; any other type is stored and served but reports itself unreadable to the agent.

size_bytesinteger>=0
kindenum

The file’s lifetime, declared at upload. ephemeral is working material for a run and is deleted 14 days after upload; kept survives until you delete it and carries no expires_at at all. Only a kept file can be published at a path.

content_pathstring

The API path the bytes stream from (prepend the API host).

created_atdatetime
project_idstringOptionalformat: "^proj_[0-9a-hjkmnp-tv-z]{26}$"

The project the file belongs to; absent for the Default project.

user_identitystringOptional

The person this file was uploaded for. Only a run acting for that same person can read it. Absent means workspace-wide: any run in the workspace can.

pathstringOptionalformat: "^[A-Za-z0-9][A-Za-z0-9._~-]*(/[A-Za-z0-9][A-Za-z0-9._~-]*)*$"<=512 characters

The name a serving layer addresses this file by, unique among the workspace’s live files. Slash-separated segments of letters, digits and . _ ~ -; no leading slash and no ... Absent on a file nothing publishes.

sourceobjectOptional
The run whose tool call produced this file. Present only on a file Speechify captured from a tool's response, absent on a customer upload.
expires_atdatetimeOptional

When an ephemeral file is deleted automatically, 14 days after upload; after it passes, every read answers 404 and the bytes are collected. Absent on a kept file, which does not expire - rather than a far-future date you would have to recognise as “never”.

Errors

400
Bad Request Error
401
Unauthorized Error
402
Payment Required Error
404
Not Found Error
409
Conflict Error
413
Content Too Large Error
503
Service Unavailable Error