Cells
A cell is one answer to one question about one subject. It carries the pages it was read from, a confidence score, and enough versioning to tell you whether it is still true of the documents underneath it.
The value
Two shapes, decided by the column's outputType. A typed column answers with { "type": …, "value": … }; an image or image_list column answers with an array of regions.
"value": [
{
"fileId": "ds_M3xJ8pQ1vK5nB7wT",
"page": 12,
"box": [0.08, 0.19, 0.94, 0.71],
"caption": "Ground floor plan, 1:100"
}
]A region names a page and a box of four numbers — xmin, ymin, xmax, ymax as 0–1 fractions of the page image. box: null means the whole page, which is what a failed locate falls back to. caption is what the model says it found: the verification signal a human scans, and the only part of an image answer a spreadsheet export can carry.
Nothing crops anything. Fetch the page through GET …/files/:fileId/items and clip to the box yourself.
Citations
Every answer that succeeded carries where it came from: a fileId, a 1-based page, the quote it was read from, and — when grounding located it on the page — a box in the same 0–1 fractions.
confidence is a number between 0 and 1. It is a triage signal for deciding which answers to check first, not a probability of correctness. Treat a low score as "look at this one" rather than "this is wrong".
Status, and running out of credits
| status | Means |
|---|---|
NOT_STARTED | The cell exists but has not been run. |
IN_QUEUE | Queued by a run, waiting for the extraction engine. |
IN_PROGRESS | Being answered. This is where the credit is spent. |
SUCCESS | Answered. |
ERROR | Failed, or blocked before it started. statusText and blockReason say which. |
blockReason is set when a cell never ran because there was nothing to pay with, or because the organisation's monthly spend cap would have been passed. That is a distinct state from an extraction that failed, and worth rendering differently — the app badges these "Out of credits" and "Spend cap" rather than "Error".
Only a hard zero stops anything. A run whose estimate exceeds the balance still goes ahead, because the estimate is an upper bound — cells are charged as they succeed, so a run can get most of the way through on less than its quote. Do not build a client that refuses to start work it has quoted.
Staleness has two axes
A cell is derived from a prompt and a set of documents, so it records both: columnVersion (which bumps on a prompt or type edit) and bundleVersion (which bumps when a bundle's membership changes).
stale: true means the cell is behind on either axis. It is computed for you rather than left to the client, because a client comparing only the column version would show a confidently wrong answer for a bundle that gained an amendment. Both, or neither.
Nothing re-runs on its own. A stale answer stays readable and stays flagged until someone starts a run.
Corrections are kept, not overwritten
humanOverride sits beside value, never on top of it. The extracted answer, its citations and its confidence all survive a correction, so what the model said and what a person decided are both recoverable. Clearing the override puts the cell back to showing the extraction.
A rerun never clobbers an overridden cell. A run silently skips those pairs — and does not charge for them.
List cells
GET/v2/workspaces/:workspaceId/tables/:tableId/cells
Requires Read on the workspace
Every cell in the table, unpaged, with stale already computed. Join to rows and columns on rowId / columnId.
Only cells that exist are returned. A table that has never been run has none, and a partly-run one has fewer than rows × columns.
curl https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/cells \
-H "x-api-key: $RAGEXTRACT_API_KEY"{
"success": true,
"total": 1,
"data": [ {
"id": "rcel_V2mR6xD9bK4jT8nW",
"rowId": "rrow_G3pL8qZ5tN1cH7yU",
"columnId": "rcol_D9sW4kF7nJ2xB6mV",
"status": "SUCCESS",
"statusText": null,
"blockReason": null,
"value": { "type": "text_quote", "value": "England and Wales" },
"citations": [
{
"fileId": "ds_M3xJ8pQ1vK5nB7wT",
"page": 27,
"quote": "This Agreement shall be governed by the laws of England and Wales.",
"box": [0.11, 0.42, 0.88, 0.47]
}
],
"confidence": 0.94,
"humanOverride": null,
"columnVersion": 1,
"bundleVersion": 1,
"stale": false,
"createdAt": 1756281600000,
"updatedAt": 1756281740000
}]
}Correct a cell
PUT/v2/workspaces/:workspaceId/tables/:tableId/cells/:cellId/override
Requires Read & write on the workspace
PUT, not POST: setting an override is idempotent and replaces whatever was there. The extracted value, its citations and its confidence are left alone.
The change is written to the cell's event log with the key that made it, so who corrected what is recoverable afterwards.
On an image cell, an override replaces the picture with text, permanently. Hand-authored regions are refused — there is no way to nudge a box through this API — so the correction for a wrong picture is a sentence describing the right one.
Parameters
value | object · requiredSent as JSON, not as a JSON string. { "type", "value" } matching the column's output type — and use fileId, not datasetId, in anything nested. |
|---|
curl -X PUT https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/cells/rcel_V2mR6xD9bK4jT8nW/override \
-H "x-api-key: $RAGEXTRACT_API_KEY" \
-H "content-type: application/json" \
-d '{"value": {"type": "text_quote", "value": "England & Wales"}}'{
"success": true,
"total": 1,
"data": {
"id": "rcel_V2mR6xD9bK4jT8nW",
"rowId": "rrow_G3pL8qZ5tN1cH7yU",
"columnId": "rcol_D9sW4kF7nJ2xB6mV",
"status": "SUCCESS",
"statusText": null,
"blockReason": null,
"value": { "type": "text_quote", "value": "England and Wales" },
"citations": [
{
"fileId": "ds_M3xJ8pQ1vK5nB7wT",
"page": 27,
"quote": "This Agreement shall be governed by the laws of England and Wales.",
"box": [0.11, 0.42, 0.88, 0.47]
}
],
"confidence": 0.94,
"humanOverride": { "type": "text_quote", "value": "England & Wales" },
"columnVersion": 1,
"bundleVersion": 1,
"stale": false,
"createdAt": 1756281600000,
"updatedAt": 1756368000000
}
}Clear a correction
DELETE/v2/workspaces/:workspaceId/tables/:tableId/cells/:cellId/override
Requires Read & write on the workspace
Drops the override only. The extracted value, citations and status are untouched, so the cell goes back to showing what extraction actually produced rather than becoming empty. The clearing is itself an event in the log.
Free, and it re-arms the cell: a subsequent run will answer it again, having skipped it while the override stood.
curl -X DELETE https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/cells/rcel_V2mR6xD9bK4jT8nW/override \
-H "x-api-key: $RAGEXTRACT_API_KEY"{
"success": true,
"total": 1,
"data": {
"id": "rcel_V2mR6xD9bK4jT8nW",
"rowId": "rrow_G3pL8qZ5tN1cH7yU",
"columnId": "rcol_D9sW4kF7nJ2xB6mV",
"status": "SUCCESS",
"statusText": null,
"blockReason": null,
"value": { "type": "text_quote", "value": "England and Wales" },
"citations": [
{
"fileId": "ds_M3xJ8pQ1vK5nB7wT",
"page": 27,
"quote": "This Agreement shall be governed by the laws of England and Wales.",
"box": [0.11, 0.42, 0.88, 0.47]
}
],
"confidence": 0.94,
"humanOverride": null,
"columnVersion": 1,
"bundleVersion": 1,
"stale": false,
"createdAt": 1756281600000,
"updatedAt": 1756281740000
}
}Read a cell's history
GET/v2/workspaces/:workspaceId/tables/:tableId/cells/:cellId/events
Requires Read on the workspace
The append-only audit under a cell: what was overridden, what the extraction had said, and who did it. actorId is the API key id for an API change, a user id for one made in the app.
data is a JSON string, not an object — parse it. Its contents vary by type.
curl https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/cells/rcel_V2mR6xD9bK4jT8nW/events \
-H "x-api-key: $RAGEXTRACT_API_KEY"{
"success": true,
"total": 2,
"data": [
{
"id": "rcev_B7kM3xR9nT5wQ1vD",
"cellId": "rcel_V2mR6xD9bK4jT8nW",
"type": "override_set",
"data": "{\"value\":{…},\"aiValue\":{…}}",
"actorId": "ukey_N5tR8mW3xC7bV1jH",
"createdAt": 1756368000000
},
{ "id": "rcev_F4jH8pL2sV6bN9mY", "cellId": "rcel_V2mR6xD9bK4jT8nW", "type": "override_cleared", ... }
]
}Read the per-document workings
GET/v2/workspaces/:workspaceId/tables/:tableId/cells/:cellId/facts
Requires Read on the workspace
On a bundled row, the answer each document gave before they were reduced to one — which is how you show why the amendment won. On a single-file row there is one fact, and it says the same thing the cell does.
⚠️ value and citations here are JSON strings, not objects, and the citations inside them still say datasetId. Unlike the cell payload, these are handed through unparsed. Parse them, and read datasetId where you would read fileId elsewhere.
curl https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/cells/rcel_V2mR6xD9bK4jT8nW/facts \
-H "x-api-key: $RAGEXTRACT_API_KEY"{
"success": true,
"total": 2,
"data": [
{
"id": "rfac_P6nW2dK8mB4xJ7tR",
"cellId": "rcel_V2mR6xD9bK4jT8nW",
"fileId": "ds_M3xJ8pQ1vK5nB7wT",
"role": "Master agreement",
"effectiveAt": 1704067200000,
"sortOrder": 0,
"status": "SUCCESS",
"value": "{\"type\":\"text_quote\",\"value\":\"England and Wales\"}",
"citations": "[{\"datasetId\":\"ds_…\",\"page\":27,…}]",
"confidence": 0.94,
"createdAt": 1756281700000
},
{ "id": "rfac_S9cQ5vN1zG3hL8kT", "fileId": "ds_K2nV7cX4jL9bR1sD", "role": "Amendment 1", ... }
]
}