Columns
A column is one question, asked of every row, with a declared output type. The type is not decoration — it is what makes an answer sortable, comparable and checkable rather than a paragraph.
The eight output types
| outputType | Answers with |
|---|---|
text_quote | A short piece of text, quoted or paraphrased from the document. |
number | A number. Stays a number whatever the table's locale. |
date | An ISO YYYY-MM-DD date. Always ISO — see below. |
boolean | Yes or no. |
categorical | One of a fixed set you declare in config.categories. |
list_scalar | A list of values. Costs more — more retrieval, longer generation. |
image | A picture: the page, or a region of it, that shows what was asked for. |
image_list | Several such regions. |
Columns in the product docs covers how to write a prompt that holds up, which is most of the work.
Image columns find pictures — they do not make them
An image column's value is a list of regions, each naming a fileId, a page, and a box of four numbers as 0–1 fractions of the page image. No cropped file is produced anywhere. The crop happens when you render it: fetch the page from GET …/files/:fileId/items and clip to the box. Because the box is fractional, it maps onto a re-render of the page at any resolution.
- It costs what a typed column costs. An image column makes no grounding calls and locating the region runs against a hard budget rather than a meter, so it is the flat
creditRateplus the usual bundle surcharge. There is no image rate. - A failed locate falls back to the whole page —
boxisnull. Vague, never wrong about which page. Treat "cropped to the region" as the normal case, not a guarantee. - Overriding an image cell replaces the picture with text, permanently. The API refuses hand-authored regions, so there is no way to adjust a box through it.
What a column costs
creditRate is the credits charged per cell on success, and you set it: an integer from 4 to 40, defaulting to 4. Typed and scalar columns sit at the default; list and enumeration columns want more, because they fan out into more retrieval and a longer generation.
The rate is identical at every tier. Tiers gate capacity, never price. On a bundled row the bundle surcharge is added on top.
Editing a column does not rewrite its answers
Every column carries a version. Changing the prompt or the outputType bumps it, and every cell that was answered against an earlier version comes back with stale: true. Nothing is recomputed and nothing is charged until you run it again.
config and creditRate do not bump the version. Neither changes the question, so neither invalidates an answer. Renaming a column does not either.
The config field
A JSON string, passed through verbatim in both directions and validated only for length. Two keys are defined:
categories(andcategoryColors) — acategoricalcolumn's closed set. Extraction readscategoriesand names the set in the prompt, so a categorical column without it has no set to choose from.dateDisplay—"exact"(the default) or"relative". Display only. The cell's value staysYYYY-MM-DDeither way, and a client that wants "in 6 days" computes it from its own clock. The API deliberately returns no derived day count, because a cell is extracted once and never re-run — a countdown is only true at the moment it is rendered.
Unrecognised keys are stored and returned untouched.
isCompositional
false (the default) reads each document in a bundle separately and reduces — the right shape for "what does this contract say". true spreads one retrieval budget across the whole subject and answers in a single call — the right shape for a question whose answer spans documents, like "how many amendments are there". It also changes how the bundle surcharge is computed.
List columns
GET/v2/workspaces/:workspaceId/tables/:tableId/columns
Requires Read on the workspace
Columns in sortOrder, including archived ones — filter on archivedAt if you are rendering a grid.
curl https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/columns \
-H "x-api-key: $RAGEXTRACT_API_KEY"{
"success": true,
"total": 1,
"data": [ {
"id": "rcol_D9sW4kF7nJ2xB6mV",
"tableId": "rev_Qm5xC9bV3nK7sAeR",
"name": "Governing law",
"prompt": "Which law governs this agreement? Answer with the jurisdiction named in the governing law clause.",
"outputType": "text_quote",
"config": null,
"isCompositional": false,
"creditRate": 4,
"sortOrder": 0,
"version": 1,
"archivedAt": null,
"createdAt": 1756108800000,
"updatedAt": 1756108800000
}]
}Create a column
POST/v2/workspaces/:workspaceId/tables/:tableId/columns
Requires Read & write on the workspace
Adds a column. Free — no cells are created and nothing is computed until you run it, however many rows the table already has.
Parameters
name | string · required1–120 characters. |
|---|---|
prompt | string · required1–4,000 characters. The question asked of every row. |
outputType | stringOne of the eight above. Defaults to text_quote. |
creditRate | numberInteger, 4 to 40. Defaults to 4. What a cell of this column costs. |
isCompositional | booleanUnion-retrieve across a bundle instead of map-reduce. Default false. |
config | string | nullA JSON string, up to 4,000 characters — e.g. {"categories":["Low","Medium","High"]}. |
sortOrder | numberInteger, 0 or above. Where the column sits. |
curl -X POST https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/columns \
-H "x-api-key: $RAGEXTRACT_API_KEY" \
-H "content-type: application/json" \
-d '{
"name": "Governing law",
"prompt": "Which law governs this agreement? Answer with the jurisdiction named in the governing law clause.",
"outputType": "text_quote"
}'{
"success": true,
"total": 1,
"data": {
"id": "rcol_D9sW4kF7nJ2xB6mV",
"tableId": "rev_Qm5xC9bV3nK7sAeR",
"name": "Governing law",
"prompt": "Which law governs this agreement? Answer with the jurisdiction named in the governing law clause.",
"outputType": "text_quote",
"config": null,
"isCompositional": false,
"creditRate": 4,
"sortOrder": 0,
"version": 1,
"archivedAt": null,
"createdAt": 1756108800000,
"updatedAt": 1756108800000
}
}Update a column
PATCH/v2/workspaces/:workspaceId/tables/:tableId/columns/:columnId
Requires Read & write on the workspace
Every field optional. Changing prompt or outputType bumps version, marking every existing answer in this column stale. The answers stay readable; running again is a deliberate, charged act. Sending the same value it already had is not a change and does not bump, so a client that PATCHes a whole column object back does not invalidate the table by accident.
Changing name, config, creditRate or sortOrder does not bump the version — none of them changes the question.
Parameters
name | string1–120 characters. |
|---|---|
prompt | string1–4,000 characters. Bumps the version. |
outputType | stringOne of the eight. Bumps the version. |
creditRate | numberInteger, 4 to 40. |
isCompositional | booleanRetrieval strategy. |
config | string | nullJSON string, up to 4,000 characters. |
sortOrder | numberInteger, 0 or above. |
curl -X PATCH https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/columns/rcol_D9sW4kF7nJ2xB6mV \
-H "x-api-key: $RAGEXTRACT_API_KEY" \
-H "content-type: application/json" \
-d '{"prompt": "Name the governing law and the exclusive jurisdiction for disputes."}'{
"success": true,
"total": 1,
"data": {
"id": "rcol_D9sW4kF7nJ2xB6mV",
"tableId": "rev_Qm5xC9bV3nK7sAeR",
"name": "Governing law",
"prompt": "Name the governing law and the exclusive jurisdiction for disputes.",
"outputType": "text_quote",
"config": null,
"isCompositional": false,
"creditRate": 4,
"sortOrder": 0,
"version": 2,
"archivedAt": null,
"createdAt": 1756108800000,
"updatedAt": 1756108800000
}
}Run one column
POST/v2/workspaces/:workspaceId/tables/:tableId/columns/:columnId/run
Requires Read & write on the workspace
A convenience for the common case — fill this one column down every row. Identical to starting a run scoped to a single columnIds entry, and it fails the same way on insufficient credits.
Spends credits — creditRate per cell, plus the bundle surcharge on bundled rows. Price it first with the run preview if you care.
curl -X POST https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/columns/rcol_D9sW4kF7nJ2xB6mV/run \
-H "x-api-key: $RAGEXTRACT_API_KEY"{
"success": true,
"total": 1,
"data": {
"run": {
"id": "rrun_X8dF2sB6nM4kQ9pL",
"tableId": "rev_Qm5xC9bV3nK7sAeR",
"status": "IN_PROGRESS",
"triggeredBy": "ukey_N5tR8mW3xC7bV1jH",
"totalCells": 42,
"pendingCells": 42,
"startedAt": 1756281600000,
"finishedAt": null,
"createdAt": 1756281600000,
"updatedAt": 1756281600000
},
"cells": 42,
"skippedRowIds": []
}
}Archive a column
DELETE/v2/workspaces/:workspaceId/tables/:tableId/columns/:columnId
Requires Read & write on the workspace
Archives rather than deletes. The column stays in GET /columns with an archivedAt stamp, and its cells are still readable — but runs never target it again, so an archived column is never charged for.
curl -X DELETE https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/columns/rcol_D9sW4kF7nJ2xB6mV \
-H "x-api-key: $RAGEXTRACT_API_KEY"{
"success": true,
"total": 1,
"data": {
"id": "rcol_D9sW4kF7nJ2xB6mV",
"tableId": "rev_Qm5xC9bV3nK7sAeR",
"name": "Governing law",
"prompt": "Which law governs this agreement? Answer with the jurisdiction named in the governing law clause.",
"outputType": "text_quote",
"config": null,
"isCompositional": false,
"creditRate": 4,
"sortOrder": 0,
"version": 1,
"archivedAt": 1756281600000,
"createdAt": 1756108800000,
"updatedAt": 1756108800000
}
}