---
title: "locate"
method: POST
path: "/v1/workspaces/{workspace_id}/tools/locate"
tags: ["tools"]
---

# locate

`POST /v1/workspaces/{workspace_id}/tools/locate`

## Request

- Base URL: `https://ndi-api.nace.ai`
- URL: `https://ndi-api.nace.ai/v1/workspaces/{workspace_id}/tools/locate`
- Auth: API key in header `X-API-Key`
- TypeScript: <https://skmtc.dev/nace/apis/ndi-platform-api/docs/v1/workspaces/:workspace_id/tools/locate/post.ts> (a function with typed inputs; its response is checked against the schema)

Find the pages and tables that hold a piece of information.

**Cost class: medium** — a few seconds on a workspace the navigator has seen; the first call after an
ingestion change reads the workspace's ingestion outputs first.

A decision model walks the workspace's files, sections and pages (built at ingestion) and names the pieces to
read, best first, with the tables to query — the locate NDI's own navigate-mode agent runs. ``text`` is that
agent's reply, word for word. Only files the key may see are considered, cut to ``path_prefix`` / ``paths``.

Stateless: send back the pieces a previous call offered (``exclude``) and what you have read (``already_read``)
to be shown something new.

## Path parameters

- `workspace_id` string, uuid, required: Workspace identifier.

## Headers

- `Idempotency-Key` string, nullable: Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.

## Request body

- LocateRequest: Request for ``locate``: where in the workspace a piece of information is. The navigator NDI's own agent calls as ``ndi-locate``, over the files the caller may see. It is stateless: what a caller was already offered (``exclude``) and has read (``already_read``) is left out of the answer only when sent back, as a run's memory does it for NDI's agent. A call that leaves out nothing is the caller's opening and rates more files. ``text`` gives the best pages in full unless ``pointer`` asks for previews only.
  - `already_read` LocateRead[]: Reads already done: their pieces are left out, and the navigator is told they did not settle the need.
    - `component` string, nullable: The tab or section read; null for the file's own text, or every tab of a whole read.
    - `line_end` integer, nullable: Last line read; null to the end.
    - `line_start` integer, nullable: First line read; null from line 1.
    - `pages` integer[], nullable: The page numbers that were read.
    - `path` string, required: The file's uploaded source path.
  - `every` boolean: The need names a kind of file and every one is wanted (each invoice, every statement): the navigator rates each file of that kind and lists the members in `population`.
  - `exclude` LocatePiece[]: Pieces earlier locates offered, left out of this answer.
    - `component` string, nullable: The piece's `component` (a tab or section); null when it had none.
    - `number` integer, required: The piece's `number`: a page, or a text file's window.
    - `path` string, required: The file's uploaded source path.
  - `k` integer: How many pieces to name.
  - `need` string, required: What is still needed, in a few words: a year, an entity, a line item, a definition.
  - `path_prefix` string, nullable: Only files under this folder, workspace-relative; `paths` adds files. Omit both for the whole workspace.
  - `paths` string[], nullable: Only these uploaded files (with `path_prefix`, its folder's files too). Unknown or inaccessible paths are refused.
  - `pointer` boolean: Name every page in `text` by its opening lines only. Without it, the best pages come in full, as a task's first locate wants them; later locates pass it, so page text does not pile up in an agent's context.
  - `question` string, nullable: The whole question the need is part of; every decision weighs the need within it. Omit it and the need is the whole question.

## Response `200`

Successful Response

- LocateResponse: Response of ``locate``: the reply NDI's agent reads, and the same findings as fields.
  - `credits` integer, nullable: Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.
  - `job_id` string, uuid, nullable: The external operation job.
  - `pages` LocatedPiece[], required: The pieces named, best first.
    - `component` string, nullable: The tab or section a read of the piece names; null when the file's text is one.
    - `head` string, required: The piece's opening text, cut where the reply text cuts it.
    - `line_end` integer, nullable: A window's last line, inclusive.
    - `line_start` integer, nullable: A window's first line, as read-file numbers lines.
    - `number` integer, required: The page number, or the window's number in a text file.
    - `paged` boolean, required: True for a page (read it by `number`); false for a window of lines.
    - `path` string, required: Uploaded source path of the file.
    - `score` number, required: How likely the piece holds what is needed, 0 to 1.
  - `population` LocatedMember[], required: Set when answering needs every file of a kind (each invoice, every contract): the members, best first.
    - `path` string, required: The file's uploaded source path.
    - `score` number, required: How likely the file is a member, 0 to 1.
  - `population_unrated` integer: Files in folders rated likely to hold members that the budget ran out before rating: when above 0, `population` is incomplete; narrow the need to a folder, kind or period and locate again with `every`.
  - `tables` LocatedTableRef[], required: The tables rated for the need, best first.
    - `columns` string[], required: Every column of the table, in order.
    - `path` string, required: Uploaded source path of the file holding it.
    - `relevant_columns` string[], required: The columns a query for the need reads, when rated.
    - `score` number, required: How likely its rows answer the need, 0 to 1.
    - `sql_table` string, required: The table's name in SQL queries.
    - `tab` string, nullable: The workbook tab, when it is one.
  - `text` string, required: The reply as NDI's own agent reads it: each piece with the command that reads it and its text (the best pages in full, the rest by their opening lines; every page by its opening lines with `pointer`), then a population's members and the tables to query.
  - `waiver` 'repeat_of_job' | 'no_job', nullable: Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.

## Other responses

- `504`: Gateway Timeout
- `default`: Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code.

## Changes

- **2026-11-07** `d002a3589a67`: 2 info
  - added the optional property `credits` to the response with the `200` status
  - added the optional property `waiver` to the response with the `200` status

[Operation history](https://skmtc.dev/nace/apis/ndi-platform-api/changes/v1/workspaces/:workspace_id/tools/locate/post.md)

---

[API](https://skmtc.dev/nace/apis/ndi-platform-api.md) - [All operations](https://skmtc.dev/nace/apis/ndi-platform-api/llms.txt) - [OpenAPI document](https://skmtc.dev/nace/apis/ndi-platform-api/revisions/d002a3589a67?raw)
