Skip to main content
Ground answers “where does this value appear in the source document?” You submit one or more items — literal strings or semantic descriptions — and get back, per item, the locations where it was found: normalized bounding boxes on pages, cell ranges in spreadsheets, character ranges in text files, or line indices in JSONL. Typical uses: drawing citation highlights over a PDF viewer, verifying that an extracted figure really exists in the source, and linking derived data back to its provenance.
EndpointBehavior
POST /groundStarts the job and waits for the result (bounded by timeout_seconds).
POST /ground_asyncStarts the job and returns 202 {"job_id": …} immediately.

Request

timeout_seconds
number
default:"120"
Sync endpoint only. Max seconds to wait, between 1 and 300.
file
object
required
The document to search. Same shape as everywhere else — source_url (+ file_name for s3:///https://). See Files & sources.
items
array
required
Values to locate — between 1 and 30 per request. Each item is matched independently; split larger batches across requests.
options
object
derived
object
Artifacts from prior NDI runs on the same file that speed up and improve grounding. All URLs must be s3:// URLs previously returned by NDI.
idempotency_key
string
Up to 128 characters. See Idempotency.
Supported extensions: everything parse supports except .eml .msg .vsd .vsdx, plus .bmp .jsonl .md .mdx.

Result

result_type
"ground"
Discriminator — always "ground".
results
array
One entry per requested item, in no guaranteed order — correlate by item_id.
total_items_found
integer
Items with at least one match.
total_items_requested
integer
Items submitted.
duration_ms
integer
Processing time.

Match types

Every match carries confidence (0–1) and usually matched_text (the text found at the location). The location fields depend on match_type:
match_typeLocation fieldsProduced for
visual_regionpage (1-indexed), x, y, w, h — a bounding box normalized to the page (0–1), origin top-left; optional cropped_image_urlPDFs, images, rendered documents
spreadsheet_rangesheet_name, cell_range (e.g. "B12:D14")Spreadsheets
text_rangestart_char, end_char — offsets into the textPlain-text sources
jsonl_recordline_index, keysJSONL sources
audio_rangestart_ms, end_msMedia transcripts
To draw a highlight from a visual_region at render size W×H pixels: left = x*W, top = y*H, width = w*W, height = h*H.

Examples

curl -s "$NDI_BASE/ground" \
  -H "X-API-Key: $NDI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": { "source_url": "ndi://file/7f4d2a10-3b7e-4c25-9f61-8f0f4f0a1b2c" },
    "items": [
      {
        "item_id": "liab-total",
        "query": "total liabilities",
        "semantic": true,
        "hints": { "visual": { "anchor_text": "Balance Sheet", "page_hints": [41, 42, 43] } }
      },
      {
        "item_id": "auditor",
        "query": "Independent Auditor'\''s Report",
        "semantic": false
      }
    ],
    "options": { "confidence_threshold": 0.8, "return_cropped_images": true },
    "idempotency_key": "ground-annual-report-v1"
  }'
curl -s "$NDI_BASE/ground" \
  -H "X-API-Key: $NDI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": {
      "source_url": "https://example.com/trial-balance.xlsx",
      "file_name": "trial-balance.xlsx"
    },
    "items": [
      {
        "item_id": "cash-eoy",
        "query": "1,204,331.00",
        "hints": { "spreadsheet": { "sheet_name": "TB Dec 2025" } }
      }
    ]
  }'
Result
{
  "job_id": "b1e6d5c4-2a3f-4e89-a0b1-c2d3e4f5a6b7",
  "action": "ground",
  "status": "succeeded",
  "result": {
    "result_type": "ground",
    "results": [
      {
        "item_id": "liab-total",
        "found": true,
        "matches": [
          {
            "match_type": "visual_region",
            "page": 42,
            "x": 0.118, "y": 0.552, "w": 0.312, "h": 0.021,
            "confidence": 0.93,
            "matched_text": "Total liabilities  $1,204,331",
            "cropped_image_url": "https://…(time-limited)…/crop-0.png"
          }
        ],
        "error": null
      },
      {
        "item_id": "auditor",
        "found": false,
        "matches": [],
        "error": null
      }
    ],
    "total_items_found": 1,
    "total_items_requested": 2,
    "duration_ms": 8412
  },
  "error": null,
  "created_at": "2026-07-12T21:15:40Z",
  "started_at": "2026-07-12T21:15:41Z",
  "completed_at": "2026-07-12T21:15:49Z"
}