Skip to content

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

outputTypeAnswers with
text_quoteA short piece of text, quoted or paraphrased from the document.
numberA number. Stays a number whatever the table's locale.
dateAn ISO YYYY-MM-DD date. Always ISO — see below.
booleanYes or no.
categoricalOne of a fixed set you declare in config.categories.
list_scalarA list of values. Costs more — more retrieval, longer generation.
imageA picture: the page, or a region of it, that shows what was asked for.
image_listSeveral 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 creditRate plus the usual bundle surcharge. There is no image rate.
  • A failed locate falls back to the whole page — box is null. 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 (and categoryColors) — a categorical column's closed set. Extraction reads categories and 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 stays YYYY-MM-DD either 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.

Request
curl https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/columns \
  -H "x-api-key: $RAGEXTRACT_API_KEY"
Response
{
  "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

namestring · required1–120 characters.
promptstring · required1–4,000 characters. The question asked of every row.
outputTypestringOne of the eight above. Defaults to text_quote.
creditRatenumberInteger, 4 to 40. Defaults to 4. What a cell of this column costs.
isCompositionalbooleanUnion-retrieve across a bundle instead of map-reduce. Default false.
configstring | nullA JSON string, up to 4,000 characters — e.g. {"categories":["Low","Medium","High"]}.
sortOrdernumberInteger, 0 or above. Where the column sits.
Request
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"
  }'
Response
{
  "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

namestring1–120 characters.
promptstring1–4,000 characters. Bumps the version.
outputTypestringOne of the eight. Bumps the version.
creditRatenumberInteger, 4 to 40.
isCompositionalbooleanRetrieval strategy.
configstring | nullJSON string, up to 4,000 characters.
sortOrdernumberInteger, 0 or above.
Request
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."}'
Response
{
  "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.

Request
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"
Response
{
  "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.

Request
curl -X DELETE https://api.ragextract.com/v2/workspaces/wks_7Kq2mB4nR8vXpL3d/tables/rev_Qm5xC9bV3nK7sAeR/columns/rcol_D9sW4kF7nJ2xB6mV \
  -H "x-api-key: $RAGEXTRACT_API_KEY"
Response
{
  "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
}
}