curl.
Export your key once so the examples below work as-is:
Step 1 — Upload a document
Stage the file once and get back an opaquefile_id you can reuse across every method:
ndi://file/<file_id>. Handles expire after about 6 days; upload again if you need the file after that.
Step 2 — Parse it
The sync endpoint blocks until the result is ready (default 120 s, tune with?timeout_seconds=, max 300):
result.item.markdown_url — it is a time-limited URL (valid for 1 hour by default; re-fetch GET /jobs/{job_id} for a fresh one).
For large documents, prefer the async variant.
POST /parse_async returns 202 {"job_id": "..."} immediately; poll GET /jobs/{job_id} until status is succeeded or failed. The sync endpoint may itself respond 202 (server at sync capacity) or 408 (timeout) — in both cases the job keeps running and you poll the same way, so handle those two codes even when you use sync. See Jobs.Step 3 — Ground a value
Find where “Total liabilities” appears in the source document, with coordinates:x, y, w, h in 0–1), so you can draw a highlight at any render resolution.
Where to go next
Jobs, polling & idempotency
Sync vs. async, statuses, retries that never double-charge you.
Categorize
Classify segments and sheets against your own taxonomy.
Files & sources
All the ways to get a document into NDI, plus supported formats.
Errors & limits
The error envelope, error codes, and rate limits.