Properties
| Name | Type | Description |
|---|---|---|
| job_id | string | |
| state | object | |
| position | object | 1-indexed place in the queue, while queued. |
| eta_seconds | object | Estimated seconds until this job finishes, from recent completion durations. None while no completions have been recorded yet. |
| queue_wait_ms | integer | Time spent queued. Still climbing while queued; frozen at the real wait once the job starts running. |
| is_heavy_query | object | PRO-3635: whether the query (or, for a multi-query operation, its heaviest sub-query) scored above the 'typical query' band on pyca's structural cost estimator -- a hint that slowness is query-side, n |
| poll_after_ms | object | How long the client should wait before polling again. Absent on a terminal state, which needs no further polling. |
| error | object | |
| result | object | |
| result_json | object | Non-tabular result payload, for jobs whose result doesn't fit QueryJobResult's columns/rows shape (e.g. PRO-3395's batched framework insight queries, each already normalized to plain JSON-safe records |
| max_cell_chars | object | Per-cell character cap the worker applied to this result's string cells (see truncate_wide_cells), or null when nothing was shortened. Mirrors SQLQueryResponse.max_cell_chars. |
| truncated | boolean | True if `result`'s rows are a prefix of the real query result -- the worker applied the same byte-payload trim run_query's own sync path uses (see trim_rows_for_payload) before caching, because the re |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/api-evangelist/carbon-arc/main/json-schema/carbon-arc-query-job-response-schema.json",
"title": "QueryJobResponse",
"x-generated": "2026-10-07",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/carbon-arc-openapi.json#/components/schemas/QueryJobResponse",
"properties": {
"job_id": {
"type": "string",
"title": "Job Id"
},
"state": {
"$ref": "#/$defs/QueryJobState"
},
"position": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Position",
"description": "1-indexed place in the queue, while queued."
},
"eta_seconds": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Eta Seconds",
"description": "Estimated seconds until this job finishes, from recent completion durations. None while no completions have been recorded yet."
},
"queue_wait_ms": {
"type": "integer",
"title": "Queue Wait Ms",
"description": "Time spent queued. Still climbing while queued; frozen at the real wait once the job starts running.",
"default": 0
},
"is_heavy_query": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Is Heavy Query",
"description": "PRO-3635: whether the query (or, for a multi-query operation, its heaviest sub-query) scored above the 'typical query' band on pyca's structural cost estimator -- a hint that slowness is query-side, not necessarily system-side load. None if no cost estimate has been recorded for this job yet (e.g. still queued)."
},
"poll_after_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Poll After Ms",
"description": "How long the client should wait before polling again. Absent on a terminal state, which needs no further polling."
},
"error": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Error"
},
"result": {
"anyOf": [
{
"$ref": "#/$defs/QueryJobResult"
},
{
"type": "null"
}
]
},
"result_json": {
"anyOf": [
{},
{
"type": "null"
}
],
"title": "Result Json",
"description": "Non-tabular result payload, for jobs whose result doesn't fit QueryJobResult's columns/rows shape (e.g. PRO-3395's batched framework insight queries, each already normalized to plain JSON-safe records). Mutually exclusive with `result` -- a job populates exactly one of the two, based on what its task cached."
},
"max_cell_chars": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Max Cell Chars",
"description": "Per-cell character cap the worker applied to this result's string cells (see truncate_wide_cells), or null when nothing was shortened. Mirrors SQLQueryResponse.max_cell_chars."
},
"truncated": {
"type": "boolean",
"title": "Truncated",
"description": "True if `result`'s rows are a prefix of the real query result -- the worker applied the same byte-payload trim run_query's own sync path uses (see trim_rows_for_payload) before caching, because the result exceeded MAX_PAYLOAD_BYTES. Lives on this envelope rather than QueryJobResult itself: QueryJobResult documents a done job's cached result as always complete, which is no longer true for a trimmed sql_editor job (bugbot finding: 'Async SQL trim hides truncation'), and callers already check SQLQueryResponse.truncated on the sync path -- this mirrors it.",
"default": false
}
},
"type": "object",
"required": [
"job_id",
"state"
],
"$defs": {
"QueryJobColumn": {
"properties": {
"name": {
"type": "string",
"title": "Name"
},
"type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Type"
}
},
"type": "object",
"required": [
"name"
],
"title": "QueryJobColumn"
},
"QueryJobResult": {
"properties": {
"columns": {
"items": {
"$ref": "#/$defs/QueryJobColumn"
},
"type": "array",
"title": "Columns"
},
"rows": {
"items": {
"items": {},
"type": "array"
},
"type": "array",
"title": "Rows"
},
"row_count": {
"type": "integer",
"title": "Row Count"
}
},
"type": "object",
"required": [
"columns",
"rows",
"row_count"
],
"title": "QueryJobResult",
"description": "A finished job's rows, in the same column/row *structure* as\n``SQLQueryResponse`` — columns plus a row matrix — so PRO-3283's SQL editor\nmigration is a rename rather than a reshape. Note the ``type`` caveat above:\nthe structure translates, the type vocabulary does not.\n\nNo ``applied_limit``/``limit_injected`` here: those describe a caller's\nown SQL rewrite, which happens before submission, not anything the job\nknows about. ``truncated`` also isn't here -- see\n``QueryJobResponse.truncated`` instead: a done job's *cached* result can\nnow be a worker-applied byte-payload trim (not just a caller's own\nrewrite), so that flag belongs on the envelope wrapping this, not on the\nrow/column structure itself."
},
"QueryJobState": {
"type": "string",
"enum": [
"queued",
"running",
"done",
"failed",
"cancelled"
],
"title": "QueryJobState",
"description": "Job lifecycle, mirroring pyca's ``QueryStatusTracker`` states.\n\nOne collapsed ``queued``, with no separate \"waiting for a worker\" vs\n\"waiting for the ConcurrencyGate\" state (PRO-3278 decision): the two are\nindistinguishable to the person waiting.\n\nBe aware of where the worker actually draws that line today. It calls\n``mark_running`` *before* ``async_read_query``, and the gate is acquired\ninside that call, so a job parked on the gate reports ``running`` — with no\nposition, no ETA, and a ``queue_wait_ms`` frozen at pickup — rather than\n``queued``. Under a saturated gate, which is the condition this whole system\nexists to make visible, that understates the wait by exactly the gate wait.\nMoving ``mark_running`` past gate admission is a change to the worker\n(PRO-3281), tracked separately.\n\nAn enum rather than a bare ``str`` so a state pyca adds later surfaces as\na loud, explicit failure in ``QueryJobService`` instead of flowing through\nto clients that have no branch for it."
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/carbon-arc-query-job-response"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.