Resource API v3
Create notebooks, execute cells, run agents, and subscribe to live results.
The v3 API uses your existing workspace, notebook, and conversation records. It does not replace the existing APIs.
Use your normal authenticated API requests, including Authorization: Bearer <token> and Querio-Workspace-Id: <workspaceId>. See Developer access for credentials. Workspace and conversation permissions still apply.
Endpoints
All paths below start with /api/v3.
| Method | Path | Purpose |
|---|---|---|
| POST | /notebooks | Create a saved notebook |
| GET, PATCH | /notebooks/:notebookId | Read or update saved notebook configuration |
| POST | /execution-environments | Create an execution environment |
| GET, DELETE | /execution-environments/:environmentId | Inspect or close an environment |
| POST | /notebook-sessions | Open a notebook |
| GET, DELETE | /notebook-sessions/:sessionId | Inspect or close its live session |
| GET | /notebook-sessions/:sessionId/events | Subscribe to notebook events |
| POST, GET | /notebook-sessions/:sessionId/executions | Execute cells or list saved executions |
| POST | /agent-sessions | Create or open an agent conversation |
| GET, DELETE | /agent-sessions/:sessionId | Read configuration and history, or close the session |
| POST, GET | /agent-sessions/:sessionId/runs | Submit a prompt or list saved runs |
| GET | /agent-sessions/:sessionId/events | Subscribe to agent events |
| GET | /runs/:runId | Read a saved run and its results |
| POST | /runs/:runId/cancel | Request cancellation |
Create and execute a notebook
Create a saved notebook with POST /notebooks:
{
"serialization": {
"version": "1.0.0",
"app": { "options": {} },
"cells": [{ "cell_id": "example", "code": "1 + 1", "options": {} }],
"valid": true,
"ui_values": {}
},
"datasourceSlugs": [],
"variables": {}
}The response is 201 and includes the notebook id and updatedAt. All request fields are optional; {} creates an empty notebook. Variables are string-to-string mappings.
Create an environment with POST /execution-environments and body {}. Open the notebook with POST /notebook-sessions:
{
"notebookId": "<saved notebook id>",
"environmentId": "<environment id>",
"mode": "edit"
}The response is 202. Subscribe to the session's events to observe startup, or inspect its state with GET. Execution requires a ready session. The session uses the saved notebook ID. An environment has at most one active notebook session. An existing live session with the same ID, including one opened in the web UI, causes creation to return 409.
mode defaults to edit. Use run for a non-editing session. Opening a session does not automatically execute its cells.
Submit POST /notebook-sessions/:sessionId/executions:
{ "type": "all" }Or select existing cells, optionally supplying replacement code and cell configuration:
{
"type": "cells",
"cells": [{ "cellId": "example", "code": "2 + 2" }],
"cacheMode": "default"
}cacheMode accepts default, no-cache, or no-store. The response is 202 with a run ID. A busy session returns 409 rather than starting an overlapping execution.
Live notebook editing
Subscribe to /notebook-sessions/:sessionId/events for live notebook state and updates. Execute Python through the existing POST /api/cee/kernel/execute endpoint, with Querio-Session-Id: <sessionId> alongside your authentication and workspace headers. This is the same endpoint used by querio code exec, not a separate v3 execution implementation. Create an edit-mode session and wait for readiness before editing.
With the CLI authenticated and a workspace selected, set QUERIO_SESSION_ID to the opened session's ID and run querio code exec '<Python code>'. Use --json for the existing structured scratchpad response. Keep the SSE subscription active during normal editing operation.
The HTTP request body is:
{
"code": "from code_execution_environment import code_mode\nasync with code_mode.get_context() as ctx:\n ctx.create_cell('value = 2\\nvalue', cell_id='example')\n ctx.run_cell('example')\nprint(ctx.globals['value'])",
"tool_call_id": "create-example"
}Code-mode contexts support creating, reading, editing, moving, and deleting cells, changing layout, and running cells. Notebook changes use the existing asynchronous persistence mechanism; SSE carries cells-registered, cells-deleted, cell-op, and execution-completed operations. Reconnecting replays the current notebook state. Consumers should build their cell list from registration/deletion events, not from every cell operation: the stream also contains scratchpad activity.
The synchronous HTTP response is { success, output, stdout, stderr, errors }. Python and code-mode errors return HTTP 200 with success: false; inspect that field. Structural validation errors reject the edit, whereas code that commits and then fails during execution remains in the notebook for correction. tool_call_id is optional and is echoed on the terminal execution event. This endpoint does not create a durable Run record or a separately cancellable run ID.
Read ctx.cells['example'].code before editing existing code. Merely receiving that code over SSE does not update code-mode's read tracking. After the code-mode block, ctx.result contains revision, changed/deleted/run cell IDs, per-cell outputs, console outputs, and structured errors. Inspect it through the same Python scratchpad; no new HTTP response contract is introduced. For inspection, print(...) writes to stdout; use print(json.dumps(...)) when you want JSON. A final expression after an asynchronous code-mode block may not populate output.
Reopening restores code, not Python variables. To initialize all cells through querio code exec:
from code_execution_environment import code_mode
async with code_mode.get_context() as ctx:
for cell in ctx.cells:
ctx.run_cell(cell.id)Opening without auto-run leaves cells stale, not executed. Requesting a dependent cell also executes its stale dependencies. If execution fails with a runtime name error, correcting the underlying condition and rerunning the cell retries execution without requiring a code edit. Structural errors such as cycles and duplicate definitions must still be corrected before execution.
Update saved configuration
Close an active API notebook session before using PATCH. To update saved serialization, datasource selection, or variables, send PATCH /notebooks/:notebookId with the updatedAt value from your last GET:
{
"expectedUpdatedAt": "<updatedAt from GET>",
"variables": { "country": "GB" }
}At least one configuration field must be supplied. A stale timestamp or an open API notebook session returns 409. Reload the notebook before retrying a stale update. While a session is open, use the execution request's cell code overrides to change and run existing cells.
Run an agent
Create an agent session with inline configuration:
{
"environmentId": "<environment id>",
"notebookSessionId": "<optional ready notebook session id>",
"config": {
"model": "<model id>",
"instructions": "Answer briefly and explain your assumptions."
},
"context": { "datasourceSlugs": [] }
}Omit notebookSessionId for a standalone conversation. Omit model, instructions, or context to use saved/default configuration. A bound notebook must be ready in the same environment. Its binding cannot change during the agent session's lifetime.
A bound agent uses the notebook's saved ID. A new standalone conversation receives a saved ID. To reopen a standalone conversation, pass that ID as the optional id field. If both id and notebookSessionId are supplied, they must match.
Submit POST /agent-sessions/:sessionId/runs:
{ "prompt": "Summarize the results and highlight anything unusual." }The response is 202 with a run ID. Each submitted prompt is one run. GET the agent session to read its saved entries, config, and context, including conversation history that predates this API.
Results and pagination
GET /runs/:runId returns the run kind (notebook or agent), session ID, input, status, timestamps, output, and error. Terminal statuses are completed, failed, and cancelled.
Outputs use the existing structured run format: cell results, assistant messages, final-answer Markdown, warnings, and cached assets where available. Console output is streamed as notebook events; it is not necessarily a cell's saved result.
The execution and run collection endpoints list runs submitted through these API endpoints, oldest first. Both accept after and limit (default 50, maximum 100):
GET /api/v3/agent-sessions/:sessionId/runs?limit=20&after=<run id>Responses have { "items": [...], "nextCursor": "..." }. nextCursor is null at the end. Saved runs remain readable after their live sessions close.
Live events
The event endpoints return Server-Sent Events (text/event-stream). Each data frame has this envelope:
{
"type": "run-status",
"sessionId": "<session id>",
"runId": "<run id>",
"data": { "id": "<run id>", "status": "running" }
}runId is present when an event is associated with a run. Streams begin with a session snapshot and replay current notebook state or agent history. They then carry runtime events, including cell operations, console output, text/message updates, tool activity, and run status changes. Heartbeats are SSE comments.
Reconnect to receive current state; this is not a permanent log of every text delta. A slow subscriber may receive session.resync-required and should reconnect. session.closed ends a live subscription.
Cancellation, closing, and recovery
Cancellation returns 202 when accepted. Acceptance does not mean execution has stopped: observe events or GET the run until it becomes terminal. Cancelling an already-terminal run returns 409.
Deleting a notebook session closes its bound agents. Deleting an agent session leaves its notebook open. Closing either session retains saved content and history. Deleting an environment with attached sessions returns 409; it never deletes workspace files.
Open session descriptors are saved with the existing conversation record. After runtime resources restart, GET or reconnect to the same session ID to restore it and its bindings. Closed sessions remain closed. Restoration reloads saved content and history, not Python process memory, and does not replay an interrupted prompt or automatically rerun notebook cells. Environments without an open saved session are live resources and are not independently restored. A hard failure before a run's final callback can leave its saved status marked running; restoration does not reconcile that status.
Last updated on October 14, 2026