ndi-sdk on npm. It covers the same /v1 surface as this site. The Python package is separate (pip install ndi-sdk).
Requires Node 20+ (or any runtime with native fetch, FormData, and Blob: browsers, Deno, Bun, edge). Zero runtime dependencies. Dual ESM + CommonJS.
new NdiClient() reads $NDI_API_KEY and $NDI_BASE_URL. You can also pass { api_key, base_url }.
There is one async client — fetch is async-only. close() is a no-op for the default fetch. If you pass your own fetch, you own its lifetime.
What you can do
One-shot calls on
client.documents do not write to a workspace. Uploads for those calls are single-use: the bytes are dropped when the job that reads them finishes.
Parse a local file
wait_seconds holds the HTTP response open when the work finishes quickly. For everything else, poll:
Extract structured JSON
Pass a JSON Schema. Extract from an upload, or from a prior parse with{ type: "parse_result", job_id } so the parse is not paid for twice. not_found on a field is an answer about the document, not an error.
Split and classify
split cuts a scanned packet into logical documents. classify labels one document against classes you define. Classify reads the original file, so it rejects a parse-result source.
Ground quoted text
Ground pins a quote back to a location in the source.Search a workspace
A workspace is a durable corpus: upload files, ingest them once, then search and ask questions repeatedly. Uploading does not make a file searchable — ingestion does.client.uploadAndIngest(...) collapses the upload and ingest calls. Across several spreadsheets, client.tools.queryTables(...) answers one question over the set.
Next steps
- Authentication — minting and rotating keys
- Python SDK
- MCP — use NDI from Claude Code, Cursor, or opencode
- Document operations
- Workspaces
- Search tools
- File tools
- Jobs and idempotency