Read a workspace file

Returns the bytes of a file the agent wrote into a thread's workspace

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Returns the bytes of a file the agent wrote into this thread's workspace, with the API key alone.

This is the endpoint for anything create_artifact produced — which is most of what a turn makes. Those files are ephemeral to the thread and are not project artifacts: they do not appear in the project artifact list, and no artifact SSE frame announces them. Only save_artifact_to_project promotes a file into the project library, and the agent does that when the user asks to keep it — so you cannot rely on it having happened.

The path is workspace, not artifacts, precisely because these are the files the project artifact list does not return.

Addressing a file

Both parts come off the stream:

PartWhere it comes from
threadIdThe turn's leading init frame.
filenameThe create_artifact tool_result payload.

The tool result reports the filename rather than a URL, so the route can change shape without stranding a client on a stale link.

filename is a single filename, not a path. A value containing / or .. is rejected with 400.

Basic Usage

curl --request GET \
  --url 'https://cloud.getwren.ai/api/v2/projects/1/threads/5/workspace/q3-revenue.html' \
  --header 'Authorization: Bearer <API_KEY>'

The response body is the file — there is no JSON envelope and no URL to follow:

<!doctype html>
<html>
  <head><title>Q3 revenue</title></head>
  <body>...</body>
</html>

The content type is inferred from the filename extension, falling back to application/octet-stream.

Query Parameters

ParameterTypeAccepted valuesDefaultDescription
modestringpreview · downloadpreviewpreview serves the bytes inline; download adds Content-Disposition: attachment carrying the filename.

mode defaults to preview here, whereas the presigned-URL endpoint defaults to download. That endpoint mints a link for a browser to follow; this one is normally read by your own code.

Security headers

HeaderWhen
X-Content-Type-Options: nosniffAlways.
Cache-Control: private, max-age=30Always.
Content-Security-Policy: sandboxRenderable documents — HTML, SVG, XML.
Referrer-Policy: no-referrerRenderable documents.

Artifact markup is generated by the agent, so it is treated as untrusted and kept on an opaque origin. Filenames the agent chose may be non-ASCII — on download the Content-Disposition carries an ASCII fallback plus an RFC 6266 filename* with the real name.

Error handling

StatusWhen
400Invalid project_id or thread_id, or a filename that is empty, ., .., or contains / or \.
401Missing or invalid API key.
404The project, the thread, or the file does not exist. A thread belonging to another project is reported the same way.
405Method not allowed — this endpoint is GET only.
501The artifact service is not configured on this deployment.

A file the thread never wrote and a git-server outage both surface as 404. If reads start failing across every thread, suspect the latter.

See Artifacts for how this compares with the project library, and a worked example.

🔗

Learn more


Path Params
integer
required

Project ID.

integer
required
string
required

A single filename, not a path. A value containing / or .. is rejected with 400.

Query Params
string
enum
Defaults to preview

preview serves the bytes inline; download adds Content-Disposition: attachment carrying the filename.

Allowed:
Headers
string
enum
Defaults to application/json

Generated from available response content types

Allowed:
Responses

Language
Credentials
Bearer
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
*/*
application/json