API
Authentication, workspace context, resource operations, request contracts, errors, and limits.
Use the resource API to find workspaces, manage datasources and saved notebooks, run sessions, and work with workspace files. Start with the authentication headers, then jump to the resource you need. Paths are relative to https://app.querio.ai; replace values in braces with returned IDs or a datasource slug, and URL-encode path and query values.
The Embedded API is a separate integration with its own tokens and conversation endpoints. Public board sharing is covered in Share an Explore or board.
The OpenAPI request-discovery export describes 59 selected operations and their request inputs. Response bodies and exact statuses are partial, so it is not a complete SDK contract.
Jump to identity and workspaces, datasources and catalog, secret metadata, saved notebooks, execution, workspace files, working copies and Git, or responses and limits.
Authentication and request context
Send a bearer access token obtained through Querio's OAuth login, or a personal API key created in workspace settings under API keys, where permitted. Keep tokens out of source files, URLs and logs.
| Header | Contract |
|---|---|
Authorization: Bearer TOKEN | Authenticates the caller. An invalid explicit bearer token fails; it does not fall back to a browser login. |
Querio-Workspace-Id: WORKSPACE_ID | Selects the workspace for resource operations. Identity/workspace discovery and workspace creation do not require an existing workspace selection. |
Querio-Session-Id: SESSION_ID | Required for Code Mode, current-session changeset inspection and live environment files. It selects live work, not a workspace or a credential. |
Content-Type: application/json | Use for JSON request bodies. Workspace file transfers use raw bytes; the deprecated table import uses multipart form data. |
Personal API keys are bound to their workspace and checked against the user's current membership and permissions. A token or selected workspace does not grant additional permissions. Stored API-key scopes are not a substitute for effective authorization. See Users, roles and groups.
For example, this read checks identity without selecting a workspace:
curl --fail-with-body 'https://app.querio.ai/api/v2/me' \
-H "Authorization: Bearer $QUERIO_ACCESS_TOKEN"The JSON result contains userId and nullable email. Get your workspace ID from /api/v2/workspaces, then send it in Querio-Workspace-Id for resource requests. The workspace_id query parameter does not select the workspace.
Identity and workspaces
| Method | Path | Request and result |
|---|---|---|
| GET | /api/v2/me | No body. Returns authenticated userId and nullable email. |
| GET | /api/v2/workspaces | No body. Returns an array of available workspaces with id and name. |
| GET | /api/gated/workspace | Deprecated. Reads the selected workspace using the workspace header. Existing CLI workspace inspection uses this route; no replacement is defined here. |
| POST | /api/v3/workspaces | Provision with name and requestId. Returns workspace identity, plan, state and the request ID. Subject to account and onboarding permissions. |
For workspace provisioning, use a trimmed name of 1-120 characters and a requestId of 1-128 letters, digits, underscores or hyphens. Optional fileMode is canonical or changeset; git: true selects changeset mode. Optional context contains a nonempty include array and an exclude array of nonempty patterns.
{"name":"Analysis workspace","requestId":"setup-example-1"}A new completed provision returns 201; a completed retry can return 200. If provisioning is incomplete, 503 includes workspaceId and requestId. Retry with the same request ID and name. Reusing the ID with a different name or file mode returns 409. Creation does not change the caller's local workspace selection. Existing-account/team limits can reject creation with 403.
Datasources and catalog
| Method | Path | Request and result |
|---|---|---|
| GET | /api/v3/datasource-connections/schema | Returns the connection schema, including provider-specific fields. |
| GET | /api/v3/datasources/{slug}/setup | Returns url and next instructions for browser setup of a new slug. Does not create a datasource. Existing slug: 409. |
| GET | /api/v3/datasources/{slug} | Returns id, slug, kind, name, revision, configured and embedded. No credential value readback. |
| POST | /api/v3/datasources | Creates datasource metadata, optionally with a complete connection. Returns metadata with 201. Duplicate slug: 409. |
| GET | /api/cee/workspace/catalog/available-schemas | Query slug. Returns live schema names and catalog membership. |
| GET | /api/cee/workspace/catalog/available-tables | Query slug and schema. Returns live table names and catalog membership. |
| POST | /api/cee/workspace/catalog/pull | JSON slug, optional targets, all and refresh. Performs synchronous introspection and saves catalog metadata. |
Datasource creation requires slug and either kind or connection. If both are supplied, their kinds must match. Optional name is a trimmed display name up to 120 characters or null. testConnection defaults to false and requires a connection when true. A slug is 1-120 characters, starts with a letter or digit, and otherwise allows letters, digits, ., _ and -.
For browser setup, give the returned url to the person connecting the datasource. After they complete the form, read its metadata and add the needed tables to the catalog. Keep credentials out of agent prompts and tool arguments. For a direct connection request, use the returned connection schema and Datasources and credentials.
configured: true means a credential exists. It does not establish that this caller can query. Querying and live introspection require datasource permission and exactly one authorized credential. A successful supplied-connection test does not establish saved credential access.
Catalog targets select schema names or schema.table names. all and refresh default to false. Prefer explicit targets; refresh updates already-catalogued tables rather than discovering new ones. A pull returns slug, dsType, catalogPath, counts, elapsed time and per-schema results. Inspect each schema's error: successful schemas can coexist with a failed schema. The pull runs synchronously. Cancelling the request does not undo catalog writes.
Datasource management and connection tests
| Method | Path | Request and result |
|---|---|---|
| GET | /api/v3/datasources | No body. Returns {"items":[...]} containing datasource metadata the caller can read. |
| POST | /api/v3/datasource-connections/test | JSON connection, matching the connection schema. Tests supplied credentials without saving. |
| PUT | /api/v3/datasources/{slug} | Deprecated. Complete connection, optional name and testConnection. Replaces the stable Default credential and returns datasource metadata. |
| DELETE | /api/v3/datasources/{slug} | No body. Deletes the datasource, its credentials and associated grants. Returns {"slug":"SLUG","deleted":true}. |
| POST | /api/v3/datasources/{slug}/test | No body. Tests using the caller's authorized saved credential. |
All datasource operations require workspace runtime connection permission. Metadata listing filters by datasource:read; a saved test requires that permission and exactly one usable credential. An unsaved test uses the supplied connection without resolving saved credential assignments. Creation and replacement require datasourceCredential:write; deletion requires datasourceCredential:delete.
Connection tests return ok, message and elapsedMs: 200 for a successful probe, 400 for a completed failed probe. Transport/upstream failures can return other errors. Responses do not echo supplied credential values or native driver errors. testConnection defaults to false; testing before a save must succeed before the connection is saved.
The deprecated PUT is a complete replacement, not a partial credential patch. It does not accept a caller-supplied expected revision. Use the credential-specific PUT below for an explicit identity and revision check. In the deprecated PUT, omitting name preserves the datasource display name and null clears it; it does not rename a credential. A missing Default credential returns 409. Replacement does not rotate the account at the database provider.
Deleting a datasource keeps catalog/context files, uploaded data, memory and other workspace files. Recreating the same slug creates a new datasource identity; it does not restore deleted grants.
Named datasource credentials
| Method | Path | Request and result |
|---|---|---|
| GET | /api/v3/datasources/{slug}/credentials | No body. Returns items containing credential metadata. |
| POST | /api/v3/datasources/{slug}/credentials | JSON name, complete connection, optional testConnection. Returns credential metadata with 201. |
| GET | /api/v3/datasources/{slug}/credentials/{credentialId} | No body. Returns that credential's metadata. |
| PUT | /api/v3/datasources/{slug}/credentials/{credentialId} | JSON positive integer expectedRevision, complete connection, optional name and testConnection. Returns updated metadata. |
| DELETE | /api/v3/datasources/{slug}/credentials/{credentialId} | Query positive integer expectedRevision. Returns {"deleted":true,"id":"CREDENTIAL_ID"}. |
Listing, reading, creating and replacing credential records require datasourceCredential:write on the datasource; deletion requires datasourceCredential:delete. These operations also require workspace runtime connection permission. Credential management does not grant datasourceCredential:use.
Metadata contains id, name, revision, default, createdAt and updatedAt. Connection values are never returned. Names are trimmed, 1-120 characters and unique within the datasource. The complete connection must match its datasource's backend kind and fit within 1 MiB of encoded JSON. testConnection defaults to false. Replacement preserves the ID and increments the revision; it does not update the database provider's account itself.
Creating a duplicate name or using a stale revision returns 409; reload before retrying. A credential ID from another datasource returns 404. Default cannot be deleted while other credentials exist. The first normal credential is assigned to Everyone; further credentials are not. Review effective grants before execution using Users, roles and groups.
Opaque secret metadata
| Method | Path | Request and result |
|---|---|---|
| GET | /api/v3/secrets | Query optional kind, after and limit (1-100, default 50). Returns items and nullable nextCursor. |
| GET | /api/v3/secrets/{id} | No body. Returns metadata, never the value. |
These reads return secret metadata, including id, workspaceId, name, kind, metadata, revision and timestamps. They never return values or ciphertext. Keep sensitive information out of metadata. Generic secret operations exclude the reserved datasource and datasource-credential kinds; use datasource credential operations instead.
Listing requires secret:list; reading one secret requires secret:read on that secret. Listing is workspace-wide metadata discovery, not permission to read a value. An invalid pagination cursor returns 400.
Saved notebooks
| Method | Path | Request and result |
|---|---|---|
| POST | /api/v3/notebooks | JSON with optional title and serialization; {} is valid. Returns the saved notebook with 201. |
| GET | /api/v3/notebooks/{id} | Returns id, title, serialization, createdAt and updatedAt. |
| PATCH | /api/v3/notebooks/{id} | Requires last-read expectedUpdatedAt plus title, serialization or both. Returns the updated notebook. |
title, when supplied, must be nonempty after trimming. expectedUpdatedAt is the saved notebook's timestamp, including timezone. A changed timestamp returns 409 with Notebook changed; reload before updating. Replacing saved serialization while its notebook session is open returns 409 with Close the notebook session before changing saved serialization. Title-only updates can occur while open.
For example, after reading the notebook, send its actual timestamp:
{"expectedUpdatedAt":"2026-10-25T12:00:00.000Z","title":"Reviewed analysis"}Use Code Mode for live cell authoring. Saved serialization, stored outputs and live Python values are different states; see Notebooks and Environments, sessions and runs.
Environments, sessions and execution
| Method | Path | Request and result |
|---|---|---|
| POST | /api/v3/execution-environments | JSON {} or {"changesetId":"CHANGESET_ID"}. Returns environment identity and state with 201. |
| GET | /api/v3/execution-environments/{environmentId} | Returns environment identity, workspace and state. |
| DELETE | /api/v3/execution-environments/{environmentId} | Close after its sessions close. Returns 204 without a body. |
| POST | /api/v3/notebook-sessions | JSON notebookId, environmentId, optional mode and config. Returns session snapshot with 202; wait for ready. |
| GET | /api/v3/notebook-sessions/{id} | Inspect or restore a saved session. Can restart compute for an open session. |
| DELETE | /api/v3/notebook-sessions/{id} | Save and close. Returns 204; a failed pre-close save leaves the session open. |
| GET | /api/v3/notebook-sessions/{id}/executions | History, oldest first. Optional after cursor and limit from 1-100, default 50. Returns items and nullable nextCursor. |
| POST | /api/v3/notebook-sessions/{id}/events | Submit the run-all request below. Returns success, runId and conversationId after acceptance. |
| GET | /api/v3/runs/{id} | Deprecated. Current shared run lookup, used by the CLI. Returns recorded status and outcome. |
| POST | /api/v3/runs/{id}/cancel | Deprecated. Request cancellation of a pending/running run; inspect status afterward. Terminal run: 409. |
| POST | /api/cee/kernel/execute | Code Mode: JSON code, optional tool_call_id, plus session header. Returns captured execution result synchronously. |
Open an explicit session with returned notebook and environment IDs:
{
"notebookId":"NOTEBOOK_ID",
"environmentId":"ENVIRONMENT_ID",
"mode":"edit",
"config":{"datasourceSlugs":[],"variables":{}}
}mode defaults to edit; run executes unchanged saved cells without authoring them. config.datasourceSlugs defaults to an empty array and config.variables to an empty string-to-string map. Variables configure queries, not Python globals. Custom variables require notebook update permission even in run mode. An environment hosts one active notebook session; explicit opens of the same saved notebook also conflict. Creation does not execute cells.
Wait for session state: "ready" before submitting work. Other states include starting, closing, closed and failed; inspect error on failure. A session snapshot includes id, notebookId, environmentId, workspaceId, mode, config, state, error and activeRunId. An environment being ready is not notebook readiness.
For whole-notebook execution, POST this body to the session's /events path:
{"type":"run-all","data":{"cacheMode":"default"}}Keep the returned runId. Acceptance is not completion. Recorded statuses are pending, running, completed, failed and cancelled. A run includes id, kind, sessionId, input, output, error and creation/start/completion timestamps. The shared lookup/cancel routes remain deprecated without a replacement specified here. GET .../executions lists history; it is not the execution submission path. This reference documents the run-all event subset.
For synchronous scratchpad execution, POST to /api/cee/kernel/execute with the session header:
{"code":"print(6 * 7)"}Check success, errors, stdout, stderr and output, even after HTTP 200. This call does not return a durable run ID. Successful editable execution waits for notebook saving. If saving fails after execution, effects can remain: keep the session open, inspect it and resolve saving before closing. Do not replay authoring code as a save workaround.
Close only resources you own or were asked to close: session first, environment second. A timeout or disconnected client does not establish closure, cancellation or rollback. See Environments, sessions and runs for restoration, ownership and cleanup rules, and CLI for the command-line workflow.
Canonical workspace files
These paths address canonical workspace files. A session header does not redirect them to its working copy.
| Method | Path | Request and result |
|---|---|---|
| GET | /api/v3/files/stat | Query path. Returns path, type, size, timestamps and opaque revision. |
| GET | /api/v3/files/list | Query path (default .), limit (default 200, maximum 1,000), optional cursor. Returns entries and nullable cursor. |
| GET | /api/v3/files/read | Query path, optional If-Match. Returns raw application/octet-stream bytes and quoted revision in ETag. |
| PUT | /api/v3/files/write | Query path; raw bytes or a JSON content envelope, plus explicit write intent. Returns created and file info. |
| POST | /api/v3/files/mkdir | JSON path. Creates a directory; its parent must exist. |
For canonical writes, send raw bytes as application/octet-stream, even when the file contains JSON. application/json instead expects {"encoding":"utf8","content":"file text"} or {"encoding":"base64","content":"canonical padded base64"}. Both the JSON body and decoded file are limited to 100 MiB; malformed base64 is rejected without replacing the file.
For a write, use If-None-Match: * to create only, If-Match: "REVISION" to replace the last-read revision, or If-Match: * to replace an existing file without comparing revisions. Alternatively supply query flags create and overwrite as true or false; omitted flags are false. Do not combine flags with revision headers. See Write intent and revisions for the complete conditions.
Reads and writes are limited to 100 MiB per file. Paths are workspace-relative; traversal, reserved paths and writes through symlinks are rejected. Creating a directory or writing a file does not create missing parent directories or ingest queryable tables. See Files and versions for revisions, reserved paths, permissions and recovery.
For live change batches, reconnect behavior and conditional writes, see Files and versions.
Canonical removal and rename
| Method | Path | Request and result |
|---|---|---|
| POST | /api/v3/files/remove | JSON path and required boolean recursive, plus If-Match. Returns {"ok":true}. |
| POST | /api/v3/files/rename | JSON oldPath, newPath and required boolean overwrite, plus If-Match. Returns {"ok":true}. |
Removal requires workspaceFs:delete; rename requires workspaceFs:rename. Use the source's quoted revision in If-Match, or * to skip revision comparison. Missing conditions return 428; changed revisions return 412. These operations use the same workspace-relative and reserved-path limits as other file operations. Root mutations, ancestor/descendant moves, incompatible destination types and replacement of nonempty directories are rejected. A nonempty directory requires recursive: true for removal.
Live environment files
Environment operations require the workspace header and Querio-Session-Id of an active notebook session owned by the requesting runtime identity and bound to the named environment. A mismatched workspace is rejected; an unavailable or mismatched environment returns 404. A closed or invalid session is rejected. These operations do not fall back to canonical files.
| Method | Path | Request and result |
|---|---|---|
| GET | /api/v3/environments/{environmentId}/files/stat | Query path; returns file metadata. |
| GET | /api/v3/environments/{environmentId}/files/list | Query path, limit, optional cursor; returns a directory page. |
| GET | /api/v3/environments/{environmentId}/files/read | Query path, optional If-Match; returns raw bytes and ETag. |
| PUT | /api/v3/environments/{environmentId}/files/write | Query path, raw bytes and explicit write intent; returns created and info. |
| POST | /api/v3/environments/{environmentId}/files/mkdir | JSON path; returns {"ok":true}. |
| POST | /api/v3/environments/{environmentId}/files/remove | JSON path, required boolean recursive, and If-Match; returns {"ok":true}. |
| POST | /api/v3/environments/{environmentId}/files/rename | JSON oldPath, newPath, required boolean overwrite, and If-Match; returns {"ok":true}. |
These use the same byte encodings, revision/intent rules, parent-directory requirements, reserved paths and 100 MiB file limit as canonical operations. Listing defaults to 200 entries, maximum 1,000. Reads use workspaceFs:read, writes workspaceFs:write, directory creation workspaceFs:create-directory, removal workspaceFs:delete and rename workspaceFs:rename, in addition to runtime identity checks. Inspect existing effects after an interrupted mutation; failed requests are not automatically replayed after service restart.
Working copies and Git transfer
These operations inspect working copies and transfer Git content. They do not install GitHub, connect a repository or configure CI. For that workflow, see Use Git and CI sync and the Querio CLI.
| Method | Path | Request and result |
|---|---|---|
| GET | /api/v3/changesets/current | Session header required. Returns the working copy bound to that session's environment. |
| GET | /api/v3/changesets/current/diff | Session header required. Returns its changes, including available inline diffs. |
| GET | /api/v3/changesets | Returns canonicalVersion and working-copy items. |
| POST | /api/v3/changesets | JSON {} for default source or {"baseVersion":"VERSION_ID"} for an explicit source. Creates a working copy. |
| GET | /api/v3/changesets/{changesetId} | Returns working-copy status and changes. |
| POST | /api/v3/changesets/git/import | JSON source and files. Imports supplied committed bytes; returns version with 201. |
| POST | /api/v3/changesets/git/patch | JSON changesetId and nonempty paths. Checkpoints and exports selected changes as application/octet-stream patch bytes. |
| POST | /api/v3/changesets/git/promote | Imported version plus expectedCanonicalVersion. Returns canonicalVersion and sourceVersion after conditional publication. |
Status identifies id, baseVersion, canonicalVersion, baseIsCurrent, checkpointId and changes. These IDs are opaque; a file revision, Git commit and source version are different values. Canonical-mode environments do not have a changeset to inspect.
An import's source has repository, commit, config_path and config_sha256. commit is a 40- or 64-character lowercase hexadecimal commit ID; config_sha256 has 64 lowercase hexadecimal characters. Each file has workspace-relative path, base64 content and optional kind: file (default), executable or symlink. The encoded request is limited to 64 MiB. Import does not fetch a repository or verify external approval or ancestry.
Direct promotion requires an imported Git version and the expected canonical version. A stale version returns 409. It preserves unrelated canonical files and removes formerly Git-managed paths absent from the new source; existing working copies do not change. Inspect actual state after a failed publication before retrying because application across files is not a single transaction.
The promotion path also accepts changesetId, expectedCanonicalVersion and paths. With a GitHub connection, that branch can create a pull request for selected edits. Without a connection, it publishes the whole checkpoint; paths is not a partial-publication guarantee. See Files and versions and Use Git and CI sync before choosing either form.
Context /reload only rebuilds context from the session's current directory. It does not import, publish or switch source versions.
For execution result operations and history pagination, see Environments, sessions and execution. For run states and stored results, see Run states and results.
Responses, errors and limits
JSON resource responses do not share one universal envelope. A 204 has no body; file and patch reads return bytes. Response schemas are incomplete for some operations: an empty or unspecified response schema does not mean the actual response is empty. Check the operation's result fields and content type, and handle non-success responses before decoding success data.
| Status or condition | Meaning and recovery |
|---|---|
400 | Invalid operation, path or connection request. Correct the request; a probe can fail without saving anything. |
401 | Missing, expired or revoked authentication. Renew the intended credential. |
403 | Missing action, workspace, runtime or datasource access. Selection is not authorization. |
404 | Resource is missing, unavailable in the selected workspace, or hidden from this operation. Check IDs and context. |
409 | Concurrent change, existing resource, active session/run, ambiguous credential access or source-version conflict. Inspect current state before retrying. |
412 | File revision changed. Reload and review before replacement. |
413 | File or encoded transfer exceeds its limit. |
422 | Invalid typed request. Webapp validation returns {"error":"Invalid request","issues":[...]}; other handlers can return different error bodies. |
428 | File write lacks required intent/revision conditions. |
5xx, timeout or lost response | Outcome may be uncertain. Inspect the resource and existing effects before repeating a mutation. |
Common webapp errors use an error string; do not assume every proxy, runtime or file error has that same shape. A successful HTTP response is also not sufficient proof of successful code, complete catalog introspection or usable data access. Datasource selection failures and exact credential-resolution errors are documented in Users, roles and groups.
Keep notebook timestamps, file revisions and expected canonical versions from the latest read. These detect different conflicts and are not interchangeable. No universal rate limit, retry policy, execution timeout or retention period is specified here. For the command-line workflow, see CLI; for embedded conversations, use the separate Embedded API.
Last updated on October 27, 2026