POST
/v1/parseCostfrom $0.001/page
Latency~1s
HyperLM
Step 1: Upload your document — call
POST /v1/documents/upload to get a document_keyRequest
Headers
| Name | Type | Required | Allowed values | Description |
|---|---|---|---|---|
X-API-Key | string | required | — | Your HyperAPI key (hk_live_* or hk_test_*). |
X-Async | string | optional | truefalse | Set to "true" to process asynchronously and receive a job ID. |
Cache-Control | string | optional | — | Send `no-cache` (or `no-store`) as an alternative to `force_refresh=true`; both have the same effect. Other directives, including `max-age=0` and `public`, do not bypass the cache. |
Body
| Name | Type | Required | Description |
|---|---|---|---|
document_key | string | required | S3 document key obtained from the presigned upload endpoint (/v1/documents/upload). |
Query Parameters
| Name | Type | Default | Allowed values | Description |
|---|---|---|---|---|
mode | string | fast | fastadvanced | OCR mode. `fast` returns per-page text, page geometry (`dimensions`, `page_size`, `background`) and, with `include_boxes=true`, line boxes plus typed `word_boxes`. `advanced` runs the layout-aware structured-output path and additionally populates a per-page `structured` object ({html, markdown, regions}). Defaults to `fast`. `advanced` accepts up to 60 pages and returns 413 above that; callers on the custom tier submitting asynchronously (`X-Async: true`) over the API or an SDK are raised to 500 pages. `fast` has no page cap. |
include_boxes | string | true | truefalse | When `true`, attach a `boxes` array of line boxes ({text, bbox: [left, top, right, bottom], confidence}) and, for PDF, XPS and image inputs in `fast` mode, a `word_boxes` array of per-word boxes with typography (font, size, color, bold, italic) to each page. Coordinates are pixels in the page's `dimensions` space. Office documents (docx, pptx) return `boxes` only with `include_image=true`; `mode=advanced` returns no boxes. Defaults to `true`; send `false` to leave boxes out. |
include_image | string | true | truefalse | When `true`, attach a presigned `image_url` (valid ~15 minutes) to each page. A page whose image cannot be presigned is returned without `image_url` rather than failing the request. Defaults to `true`; send `false` to leave page images out. |
include_layout | string | true | truefalse | `fast` mode only. When `true`, each page gains `layout` (the detected regions in reading order, with `bbox` in the same pixel space as `boxes`) and `layout_text`, and `result.layout_text` carries the text rebuilt around the regions. Defaults to `true` in `fast` mode; send `false` to leave the layout out (figure parsing then resolves to none). `mode=advanced` returns its own `structured` layout, and an explicit `include_layout=true` with `mode=advanced` returns 400. |
parse_figures | string | image,chart,table | — | `fast` mode only; requires `include_layout`. A comma-separated list of region kinds to parse further: any of `image`, `chart`, `table`. Each matching region gains `content` (a chart's data as a markdown table, an image's caption or text, a table as HTML) and a `parse_status`, and `result.figure_parse` summarises the run. Best-effort: OCR and layout are always returned even when a region cannot be parsed. Defaults to `image,chart,table` when the layout is on, and to none when it is off. Send `none` to opt out. An explicit list with `include_layout=false` returns 400. |
groups_profile | string | A | AB | `fast` mode with the layout on. Selects how `result.groups` (the document outline over `result.blocks`) is built. `A` (default): every block is in exactly one group, and walking the tree in order — skipping `page_header` and `page_footer` groups — yields reading order. Content before the first heading is held by a `preamble` group, and a document with no heading is one `preamble`. Each page's running heads, feet and page numbers are held by one `page_header` / `page_footer` group per page at the root, with `repeats` naming the first copy when a page repeats an earlier page's. `B`: an alternative outline that ranks headings by the type sizes read off the page; marks running titles as page furniture (`furniture: true`) and does not treat empty headings or field labels as headings (they stay ordinary content); binds captions to their figure or table by position; joins a table that continues onto the next page; makes no `list` groups; does not pair a display formula with its number; and adds extra outline fields (`size_pt` / `size_source` on sections, `caption`, `table` and `continues` on figure and table groups). Under `B`, page furniture is in no group, and a document with no heading has no `preamble`: its own groups (tables, figures, formulas, notes, asides) and any `message` groups sit at the root. Because a caption is held by its figure or table group, the `B` tree is not in reading order; use `blocks[].order` for that. Case-insensitive; any other value is treated as `A` and is never an error. When `B` is requested, `metadata.groups_profile` states the profile that was applied. |
force_refresh | boolean | false | — | When `true`, re-run OCR instead of returning the cached result. Parse results are cached per document for 24 hours, so re-submitting an unchanged file normally returns the stored output — this is how to force a genuinely fresh run after a bad result. Applies to both `fast` and `advanced`. A forced run is billed at the normal page rate, where a cached one is not charged. Defaults to `false`. |
Code examples
# Get a document_key first: see POST /v1/documents/upload
curl -X POST "https://apis.hyperbots.com/v1/parse" \
-H "X-API-Key: hk_live_your_key_here" \
-F "document_key=550e8400-e29b-41d4-a716-446655440000"# Get a document_key first: see POST /v1/documents/upload
curl -X POST "https://apis.hyperbots.com/v1/parse" \
-H "X-API-Key: hk_live_your_key_here" \
-F "document_key=550e8400-e29b-41d4-a716-446655440000"Response
200 OK
application/jsonJSON
{
"status": "success",
"request_id": "req_01j9x...",
"task": "parse",
"model_used": "HyperLM",
"result": {
"ocr": "Invoice\n\nBill To: Acme Corp\nDate: 2024-01-15\n\n...\n\n...",
"pages": [
{
"page_number": 1,
"text": "Invoice\n\nBill To: Acme Corp\nDate: 2024-01-15\n\n...",
"dimensions": { "width": 1696, "height": 2176 },
"page_size": { "width": 612, "height": 792, "unit": "pt" },
"background": "#ffffff",
"image_url": "https://...presigned-page-image...",
"boxes": [
{ "text": "Invoice", "bbox": [128, 96, 412, 168], "confidence": 0.99 }
],
"word_boxes": [
{ "text": "Invoice", "bbox": [128, 96, 412, 168], "font": "Helvetica", "size": 24, "color": "#1a1a1a", "bold": true }
],
"layout": [
{ "label": "title", "bbox": [128, 96, 412, 168] },
{ "label": "table", "bbox": [128, 820, 1568, 1460], "content": "<table>...</table>", "parse_status": "ok" }
],
"gaps": [
{ "bbox": [128, 604, 1568, 820], "height": 216, "after": "b1-3", "before": "b1-4", "ratio": 5.4 }
]
},
{
"page_number": 2,
"text": "...",
"dimensions": { "width": 1696, "height": 2176 },
"page_size": { "width": 612, "height": 792, "unit": "pt" },
"background": "#ffffff",
"image_url": "https://...presigned-page-image...",
"boxes": [ ... ],
"word_boxes": [ ... ],
"layout": [ ... ]
}
],
"figure_parse": {
"requested": ["image", "chart", "table"],
"available": true,
"blocks_total": 1,
"blocks_parsed": 1,
"blocks_skipped": 0,
"gaps": []
},
"blocks": [
{ "id": "b1-0", "order": 0, "page": 1, "label": "doc_title", "bbox": [128, 96, 412, 168], "html": "<h1>Invoice</h1>", "heading": 1, "group": "g0", "depth": 1 },
{ "id": "b1-4", "order": 4, "page": 1, "label": "table", "bbox": [128, 820, 1568, 1460], "html": "<table>...</table>", "group": "g1", "depth": 1 },
...
],
"groups": [
{ "id": "g0", "kind": "section", "pages": [1, 2], "children": ["b1-0", "b1-1", "g1", ...], "level": 1, "heading": "b1-0", "boxes": [{ "page": 1, "bbox": [128, 96, 1568, 2040] }, { "page": 2, "bbox": [128, 120, 1568, 1180] }] },
{ "id": "g1", "kind": "table", "pages": [1], "children": ["b1-4"], "boxes": [{ "page": 1, "bbox": [128, 820, 1568, 1460] }] },
...
]
},
"duration_ms": 843,
"metadata": {
"pages": 2,
"file_type": "pdf"
}
}Page images and figure crops are returned as short-lived signed storage links; the response's assets_expire_at gives the exact deadline. The text is yours to keep; the links are not. Store the request_id and read the result back with fresh links whenever you need it — Retrieving Results.