---
title: "Parse a table and propose a column mapping"
method: POST
path: "/batch-tasks/preview"
---

# Parse a table and propose a column mapping

`POST /batch-tasks/preview`

## Request

- Base URL: `https://rendry.io/api/v1`
- URL: `https://rendry.io/api/v1/batch-tasks/preview`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer
  - HTTP bearer

Dry run before /batch-tasks: shows how the columns map to template variables. Creates nothing and costs nothing. variables are the columns the table is expected to carry — what a caller supplies; for a template that computes some of its values, inputs (InputDescriptor) names what it computes from them. A computed value is never an expected column and is never reported unmatched, but a column named after one maps onto it as an explicit override.

## Headers

- `X-Rendry-Account` string

## Request body

- object
  - `preset_id` string, required
  - `table` string, required
  - `format` string: Output format override, the same field /batch-tasks takes. Pass the one you will create the batch with, or max_cost_credits quotes a different price than the batch charges (a pdf page is priced per page, an image by canvas area).
  - `quality` integer: As on /batch-tasks: resolved with format and max_width exactly as the batch resolves them, so a value the batch refuses is refused here too (batch_output_invalid).
  - `max_width` integer: As on /batch-tasks; see quality.
  - `mapping` object: When sent, checked and every row judged under it exactly as /batch-tasks judges them, so a body the batch would refuse is refused here with the batch's answer (batch_mapping_mismatch, batch_row_invalid). Without it the preview proposes one and judges no rows. The reply proposes its own either way (suggested_mapping).
  - `rows` object: Fed to that row judgement as /batch-tasks feeds it; the quote itself is priced by the template's page, as the batch's balance check is.

## Response `200`

Proposed mapping and the price of the run

- BatchTaskPreview: How the table maps onto the template, and what the batch will cost — nothing is created.
  - `columns` string[]: Header row of the table
  - `rows_total` integer
  - `max_cost_credits` number: What the batch charges up front if every row renders: rows × the page price of this template in the format passed
  - `sample_rows` array[]: The first data rows, as cells
    - string[]
  - `variables` string[]: Every {variable} the template accepts
  - `suggested_mapping` object: column -> variable, by name
  - `unmatched_variables` string[]: Variables no column feeds; they render with the template's sample value
  - `variables_without_sample` string[]: Variables that have neither a column nor a sample: a row that leaves them unfed FAILS
  - `inputs` InputDescriptor[]: Present for a template that computes some of its values (a template or formula definition): the class, mode and dependencies of every name. Absent otherwise.
    - `name` string, required
    - `class` 'required' | 'defaulted' | 'computed' | 'fact', required: required: referenced and never authored — send it, or the render refuses. defaulted: an authored text a caller may replace. computed: a template or formula the template evaluates; a literal a caller sends replaces it for that call and cuts its dependencies. fact: page or pages, the engine's — cannot be supplied.
    - `mode` 'text' | 'template' | 'formula': The authored mode of a definition; absent for a name that has none.
    - `dependencies` string[]: The names a computed definition references, sorted.
    - `used` boolean, required: Content reaches this name, directly or through computed definitions. An unused authored definition is still listed: removing one is an explicit act. Not what a render needs: every template and formula is evaluated on every render, drawn or not, so a required name that only an undrawn definition reads is still required and is listed in `variables`.
    - `format` DisplayFormat: One deterministic display vocabulary. Numbers use exact arithmetic and half away from zero rounding. Currency needs symbol (a symbol or ISO code), with explicit spacing in that text. Percent multiplies a raw ratio by 100. Dates accept strict YYYY-MM-DD only and patterns D, DD, M, MM, MMM, MMMM, YY, YYYY with English month names. upper/lower use Unicode simple case mapping; no locale or multi-character expansions. No format leaves existing text untouched. Fields unrelated to the selected type are refused.
      - `type` 'number' | 'currency' | 'percent' | 'date' | 'upper' | 'lower', required
      - `decimals` integer
      - `grouping` boolean
      - `decimal_mark` string
      - `group_mark` string
      - `symbol` string
      - `symbol_position` 'prefix' | 'suffix'
      - `prefix` string
      - `suffix` string
      - `pattern` string

## Other responses

- `400`: The refusals /batch-tasks gives before its price, with the same body: the table (batch_table_*), an output option (batch_output_invalid), a sent mapping (batch_mapping_mismatch) or a row under it (batch_row_invalid). A quote is never given for a batch /batch-tasks would refuse.
- `422`: `batch_render_too_big`: the render needs more memory than a worker has — the same refusal /batch-tasks gives, before any quote.
- `503`: `service_unavailable`: the template could not be read (our side); retry. Never `preset_not_found` for an outage.

---

[API](https://skmtc.dev/rendry/apis/rendry-api.md) · [All operations](https://skmtc.dev/rendry/apis/rendry-api/llms.txt) · [OpenAPI document](https://skmtc.dev/rendry/apis/rendry-api/revisions/c4fb572c26c9?raw)
