Results
Retrieve persisted query results. Every query execution persists its results asynchronously. Results transition through statuses: processing → ready (or failed). Once ready, the full result data can be retrieved by ID.
List results
/v1/resultsList stored results for the database named by the required X-Database-Id header.
Query parameters
limitinteger— Maximum number of results (default: 100, max: 1000)offsetinteger— Pagination offset (default: 0)
Headers
X-Database-Idstring— required. Database to scope the results to (required)
Response 200 — List of results
countinteger— required. Number of results returned in this response. Min:0has_moreboolean— required. Whether there are more results available after this pagelimitinteger— required. Limit used for this request. Min:0offsetinteger— required. Pagination offset used for this request. Min:0resultsResultInfo[] — requiredcreated_atstring— requirederror_messagestring,nullidstring— requiredstatusstring— required
{
"count": 0,
"has_more": true,
"limit": 0,
"offset": 0,
"results": [
{
"created_at": "2026-01-01T00:00:00Z",
"error_message": "string",
"id": "string",
"status": "string"
}
]
}
Errors
| Status | Description |
|---|---|
400 | Missing or malformed X-Database-Id header |
404 | Database not found |
Get result
/v1/results/{id}Retrieve a persisted query result by ID. The response format for the ready state is selected by Accept header or ?format= query param; non-ready states use the same status codes and JSON body shape regardless of format.
| Result status | Status × body |
|---|---|
ready + JSON | 200 application/json — GetResultResponse with columns, rows, etc. |
ready + Arrow | 200 application/vnd.apache.arrow.stream — schema, RecordBatches, EOS |
ready + CSV | 200 text/csv; charset=utf-8 — single header row, streamed batch-by-batch |
ready + Markdown | 200 text/markdown; charset=utf-8 — GitHub-flavored pipe table, streamed |
ready + Parquet | 200 application/vnd.apache.parquet — raw parquet bytes (no conversion) |
pending/processing | 202 application/json {status, result_id} + Retry-After |
failed | 409 application/json {status, result_id, error_message} |
| not found | 404 application/json (ApiErrorResponse) |
?format= accepts arrow, json, csv, md, parquet and takes precedence over Accept. markdown is accepted as a runtime alias for md. Use ?offset=N&limit=M to slice the result; offset defaults to 0 and limit is unbounded by default. Both must be non-negative; invalid values return 400. When a finite limit doesn't reach the end of the result, a Link header with rel="next" points at the following page. ?offset/?limit are ignored for format=parquet since that path returns the underlying file unchanged.
Ready responses (Arrow, CSV, Markdown, JSON) carry X-Total-Row-Count (the full result row count, independent of offset/limit). Responses are streamed end-to-end, so a client can disconnect at any time and the server stops reading.
IEEE special floats (±Inf, NaN) have no canonical JSON representation. For cross-format consistency the JSON, CSV, and Markdown paths emit them as null / empty cells, and JSON nullable[] is widened to match. The Arrow IPC and Parquet bodies are binary round-trip formats and preserve the raw IEEE values; callers cross-checking a result across CSV and Parquet should not byte-compare those slots.
Path parameters
idstring— required. Result ID
Query parameters
offsetinteger— Rows to skip (default: 0)limitinteger— Maximum rows to return (default: unbounded)formatResultsFormatQuery—arrow,json,csv,md, orparquet— overrides theAcceptheader.markdownis also accepted at runtime as an alias formd.
Headers
X-Database-Idstring— required. Database the result belongs to (required)
Response 200 — Result data. The body depends on the negotiated format: JSON callers receive GetResultResponse; Arrow callers receive an Arrow IPC stream; CSV callers receive comma-separated text (LF-terminated, double-quote escaped, RFC 4180-style quoting but not RFC 4180-strict on line endings); Markdown callers receive a single GitHub-flavored pipe table; Parquet callers receive the raw parquet bytes, served as-is. Non-finite floats (±Inf, NaN) render as null (JSON) or empty cells (CSV, Markdown) for cross-format consistency. Accept is treated as a flat content-type list — q= quality values are ignored; use ?format= to disambiguate.
columnsstring[] |nullerror_messagestring,nullnullableboolean[] |nullresult_idstring— requiredrow_countinteger,nullrowsany[][] |null— Array of rows, where each row is an array of column values.statusstring— required
{
"columns": [
"string"
],
"error_message": "string",
"nullable": [
true
],
"result_id": "string",
"row_count": 0,
"rows": [
[
null
]
],
"status": "string"
}
Response 202 — Result is still being computed (pending or processing). Poll the same URL.
columnsstring[] |nullerror_messagestring,nullnullableboolean[] |nullresult_idstring— requiredrow_countinteger,nullrowsany[][] |null— Array of rows, where each row is an array of column values.statusstring— required
{
"columns": [
"string"
],
"error_message": "string",
"nullable": [
true
],
"result_id": "string",
"row_count": 0,
"rows": [
[
null
]
],
"status": "string"
}
Errors
| Status | Description |
|---|---|
400 | Invalid offset, limit, or format. |
404 | Result not found. |
409 | Result computation failed. Body carries error_message describing the failure. |