Skip to main content
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.
The hand-written TypeScript SDK for anyformat. The wire types and the low-level HTTP client are generated from the API’s OpenAPI spec with Hey API; the ergonomic layer (Anyformat, Schema, WorkflowBuilder, Result) is hand-written and mirrors the Python SDK.

Installation

Requires Node 18+.
The package ships ESM + CJS bundles and TypeScript types.

Authentication

Pass the API key to the Anyformat constructor, or read it from the environment.
Override the base URL with 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.
The TS SDK splits “create workflow” from “submit document”, mirroring the Python SDK. 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.pdfinvoice (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

See Response formats for the full shape of every section.

Error handling

The SDK exports typed error classes:
Wire-format error codes (e.g. 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:
See Webhooks for the payload shape and signature verification.
  • npmnpm install @anyformat/sdk
  • Python SDK — the same fluent shape in Python
  • Coding assistant — let Claude drive anyformat from your editor