---
title: "List the tables printed on a sheet"
method: GET
path: "/v1/blueprints/{blueprint_id}/tables"
tags: ["Blueprints / Drawing text"]
---

# List the tables printed on a sheet

`GET /v1/blueprints/{blueprint_id}/tables`

## Request

- Base URL: `https://api.kamai.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.kamai.io/v1/blueprints/{blueprint_id}/tables`
- Auth: HTTP bearer

The tables printed on the sheet (schedules, legends, revision blocks), as an index
with no cell contents: one entry per table with its `id`, `title`, `source`, `bbox`,
size, `coverage` and flags. Open one with GET `/tables/{table_id}`, passing the id
exactly as listed.

A table id names one table in one extraction of the sheet, not the table for all time.
Each time the sheet is read for tables again (a re-upload, a re-run or a reprocessing),
its `rev` and every id change, even when the tables come out the same; a run that fails
or is cut short leaves the previous extraction in place.

`status` is never an error: `ok`; `empty` (read, and no printed tables: a real answer,
unless `complete` is `false`); `not_extracted` (never read for tables: unknown, not
empty); or `unavailable` (could not be read just now; retry). There is no failed or
in-progress status: a sheet whose only extraction failed answers `empty` with
`complete: false`, and while a sheet is being read you get what was stored before. A new
upload's tables normally land within a couple of minutes: poll for a few minutes after
upload; a sheet still `not_extracted` after that is not being read for tables.

Common mistakes: keeping table ids for days (list again; they change on every
re-extraction); reading `not_extracted` or `unavailable` as "no tables" (only `empty`
means that); assuming a table is complete (check `coverage` and `degraded`); stopping at
the first page (follow `next_cursor` until it is `null`).

404 when the sheet is not in one of your projects; 422 for a malformed or outdated cursor.

## Path parameters

- `blueprint_id` string, required

## Query parameters

- `q` string, nullable: Only tables whose title contains this text, case-insensitive.
- `cursor` string, nullable: `next_cursor` of the previous page. Tied to the sheet's extraction: if the sheet was read again in between, it is a 422; start the listing again.
- `limit` integer, nullable: Tables per page, 1..1000; 1,000 when left out.

## Response `200`

Successful Response

- PrintedTablesResponse
  - `status` 'ok' | 'empty' | 'not_extracted' | 'unavailable', required: `ok`; `empty`: read, and no printed tables (a real answer, unless `complete` is `false`); `not_extracted`: never read for tables, so unknown, not empty; `unavailable`: could not be read just now, retry.
  - `sheets` TableSheetState[]: The sheet's table state (one entry on this route).
    - `blueprint_id` string, required: The sheet.
    - `state` 'ok' | 'empty' | 'not_extracted' | 'unavailable', required: The sheet's table state; see the list's `status`.
    - `rev` integer, nullable: The version of the sheet's stored table extraction, the `rev` in every table id. A new one appears whenever the sheet is read for tables again.
    - `complete` boolean, nullable: `false` when that reading did not finish.
    - `lossy` boolean, nullable: `true` when the sheet's tables are rebuilt from the older markdown form (see the table's `lossy`).
    - `extractor_version` string, nullable: Version of the extractor that read the tables (informational).
    - `chars_total` integer, nullable: All the sheet's tables' markdown, in characters.
    - `note` string, nullable: A plain-English explanation for `not_extracted` and `unavailable`.
  - `tables` PrintedTableEntry[]: This page of the index; no cell contents.
    - `id` string, required: `{blueprint_id}.{rev}.t{n}`: this table in this extraction of the sheet. Use it exactly as returned; never build or edit one (a malformed id is a 422). It changes whenever the sheet is extracted again.
    - `blueprint_id` string, required: The sheet the table is printed on.
    - `title` string, nullable: The table's title as printed, or `null`.
    - `source` string, nullable: How the table was read: `pdf-text-layer` (the PDF's own text) or `ocr` (a scanned or image table); `unknown` otherwise.
    - `bbox` number[], nullable: Where the table sits, [x0, y0, x1, y1] in fractions (0..1) of the page; `null` when unknown.
    - `complete` boolean, nullable: `false` when the sheet's table reading did not finish, so tables (or the emptiness of an `empty` sheet) may be incomplete.
    - `coverage` TableCoverage
      - `cells_present` integer, required: Cells the extraction filled.
      - `cells_total` integer, required: Cells in the table's grid.
    - `degraded` boolean, nullable: `true` when the high-resolution re-read did not land, so the text is the coarser first reading.
    - `lossy` boolean, nullable: `true` when the sheet was extracted before the structured form existed: rows are rebuilt from the markdown, line breaks inside cells are flattened, short rows are padded, and there are no cell boxes.
    - `n_rows` integer, nullable: Data rows, header not counted.
    - `n_cols` integer, nullable: Columns.
    - `chars` integer, nullable: Size of the table's markdown in characters, a guide to its length.
  - `total` integer: Tables matching `q`, across all pages.
  - `next_cursor` string, nullable: Pass it as `cursor` for the next page; `null` on the last page.
  - `excluded` unknown[]: Always empty on this route.
    - unknown

## Other responses

- `404`: The sheet is not in one of your projects.
- `422`: The request is refused. A malformed or outdated cursor. These answer `{"detail": {"error", "details"}}`. A parameter or body field of the wrong type or out of its range is refused before the request is read, with `{"detail": [{"loc", "msg", "type"}, ...]}`.

---

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