API v3 is available. This SDK targets the v2 API, which keeps working through its deprecation window. A new SDK major targeting v3 is in progress — see the v3 SDKs page and the v3 API reference.
Anyformat, Schema, WorkflowBuilder, Result) is hand-written and mirrors the Python SDK.
Installation
Requires Node 18+.Authentication
Pass the API key to theAnyformat constructor, or read it from the environment.
baseUrl if you’re running against a non-production deploy. See Authentication for how to mint an API key.
Basic usage
Full flow: build a workflow with a fluent builder, submit a document, await the typed result.create() returns a Workflow handle whose run(file) reuses the existing workflow id — so processing N documents through the same workflow costs one POST /v2/workflows/ plus N POST /v2/workflows/{id}/run/, not N create+run pairs.
wait options
wait defaults: 300s overall timeout, 3s poll interval. Override either:
SDKTimeout is thrown if the overall deadline expires before the run completes. The internal poll handles 412 (still processing) automatically.
Builder methods
All node types in the typed graph are exposed as fluent methods.parse is required; the others are optional and can be chained in any topology the API allows.
The
Workflow handle returned by .create() has one method:
Workflow.run returns a Run; Run.wait(opts?) returns a Result once processing finishes.
Filenames are unique within a workflow. By default an upload whose filename already exists in the workflow is rejected with
409 (error code FILENAME_CONFLICT). Pass { onConflict: "rename" } to .run(...) / .upload(...) / .uploadFromUrls(...) to auto-rename instead (invoice.pdf → invoice (1).pdf).Smart lookup
A smart-lookup field is resolved by matching the document against a reference file (a CSV/catalog) instead of being read off the page. Flag the field with{ source: "smart_lookup" }, and pass the reference file to .extract(..., { lookupFiles: [...] }) — the SDK reads each path and uploads it with the workflow. See Smart Lookup for how matching works and the Studio UI equivalent. Here the model reads vendor_name, then resolves the canonical vendor_id from a vendor catalog:
{ source: "smart_lookup" } is accepted on every Schema.* factory. The looked-up field comes back via result.field(...) alongside the others — there’s no separate section for it. An extract with a lookup field but no lookupFiles is rejected with 400. A smart-lookup field is overwritten by the lookup; use { source: "lookup_if_missing" } to extract it from the document too and let the lookup fill it only where extraction found no value.
Managing workflows
The client also lists and deletes workflows:Reading results
Error handling
The SDK exports typed error classes:EXTRACTION_FAILED, RATE_LIMITED) are documented at Errors. The APIError.body field holds the parsed JSON body the server returned.
Webhooks (not on the SDK surface yet)
Anyformat doesn’t expose webhook endpoints directly today. Until it does, register and delete webhooks with fetch or the generated low-level client:
Links
- npm —
npm install @anyformat/sdk - Python SDK — the same fluent shape in Python
- Coding assistant — let Claude drive anyformat from your editor

