Run agentic-mode turns over a versioned SSE contract, then read back the artifacts, memory, skills and history that surround them.
Project availability: ⛔ Classic projects • ✅ Agentic projects only.
These endpoints operate on agentic projects. Calling them against a classic project fails.
Agentic mode runs a Wren agent against your project: it plans, queries your data, writes files, draws charts, and can ask you clarifying questions mid-turn. A turn is one request-and-response cycle; a thread is a sequence of turns that share context.
Start with Agentic-mode ask (SSE) — every other endpoint here supports a turn you started there.
Where the agent runs
Each thread gets its own sandbox: an isolated container that Wren provisions for it, holding that thread's workspace and nothing else.
- The agent's file writes, tool calls, and generated code stay inside that sandbox. One thread cannot read another's workspace, and no thread can reach anything outside its own project.
- Your database is reached through the same semantic layer the rest of Wren uses, so the agent sees exactly the models your project deploys.
- The turn's
roleis enforced inside the sandbox: atviewer(the default) the tools that mutate your model, knowledge, and skills are not given to the agent at all. - Sandboxes are reclaimed once a thread goes idle. Files the agent chose to keep survive that — they are in the thread's workspace, and artifacts are saved separately.
You do not provision, address, or clean up sandboxes; that is entirely handled for you.
Endpoints Overview
The turn — start here
| Endpoint | What it does |
|---|---|
POST /v2/stream/agent_ask | Start or continue a turn. Streams SSE. Omit threadId to start a new conversation. |
POST …/{threadResponseId}/user_input | Answer a clarifying question the agent raised. |
POST …/{threadResponseId}/cancellation | Stop a running turn. |
Non-streaming reads — for clients that can't hold a stream open
| Endpoint | What it does |
|---|---|
GET …/{threadResponseId}/status | Poll the turn's status. |
GET …/{threadResponseId}/result | Replay the finished turn's events in emission order. |
GET /v2/projects/{projectId}/threads/{threadId}/messages | Thread history, cursor-paginated. |
What surrounds a turn
| Group | Use it to |
|---|---|
| Artifacts | Fetch the charts, documents and files a turn produced — from the thread workspace, or from the project library once the user keeps one. |
| Memory | Give an end user context that persists across turns. |
| Skills | Install reusable procedures the agent can draw on. |
| Uploads | Stage files for a turn to work on. |
Authorization and end users
Everything here is authorized with an API key alone. An API key carries no user, which shapes three behaviors you need to design around when embedding Wren for your own end users:
| How it works | |
|---|---|
| Row-level security | Asserted per thread. Send X-Wren-Session-Properties on the turn that opens a thread — region=US,tier=pro. The bindings are fixed for that thread's lifetime; a follow-up sending different bindings is refused with 400. Open a new thread to query as someone else. |
| Artifacts | Listed project-wide, not per user. Deciding which of them a given end user may see is your responsibility. |
| Memory | Addressed by a namespace you choose. Use your own end-user id. |
Bindings are validated before anything runs: an unknown or type-mismatched key returns 400 and no turn starts. That is deliberate — silently dropping a binding could return rows the end user should never see.
Retries and concurrency
Send an Idempotency-Key on POST /v2/stream/agent_ask and a replayed request returns the original turn instead of starting — and billing — a second one. The key is claimed before any side effect, so a retry arriving while the original is still provisioning gets 409 rather than starting a duplicate; retry again once the original has settled and you get the replay.
One thread runs one turn at a time. A second concurrent request against the same threadId returns 409.
Idempotency and the single-active-turn guard are per-instance. Across a multi-instance deployment they are best-effort.
Errors
Error bodies follow ErrorResponse: an error message, plus a code and a top-level id when the failure came from inside a handler. Validation and auth pre-checks return error alone.
| Status | When |
|---|---|
400 | Malformed input — bad threadId, invalid memoryNamespace, unknown session-property key, session properties that contradict the ones the thread was opened with, invalid skill frontmatter. Also NO_DEPLOYMENT_FOUND, meaning the project has never been deployed |
401 | Missing or invalid API key (UNAUTHORIZED_API_KEY) |
404 | The project, thread, turn, artifact, or skill does not exist |
405 | Method not allowed on this path |
409 | Duplicate — a turn is already running on the thread, an Idempotency-Key is in flight, or the skill name is taken |
413 | Upload exceeds AGENT_FILE_UPLOAD_MAX_SIZE_MB |
415 | Unsupported Content-Type on skill create — use multipart/form-data or application/json |
429 | Out of credits, or a plan limit was hit |
501 | A dependency is not configured in this deployment (git-server, control-plane) |
502 | The storage backend rejected an upload |
503 | File storage is not configured for this deployment |
