Skip to main content
anyformat API v3 is the current stable major. It exposes the same extraction engine as v2 through a smaller, flatter surface built around three resources: workflows, document packets, and runs. Coming from v2? The migration guide maps every v2 path to its v3 successor. v2 keeps serving traffic through its announced deprecation window, unchanged.

Base URL

https://api.anyformat.ai/v3/
All endpoint paths require a trailing slash. Requests without one receive a 307 Temporary Redirect, which preserves the request method and body.

Authentication

All endpoints require an API key, passed as a Bearer token:
curl -H "Authorization: Bearer YOUR_API_KEY" https://api.anyformat.ai/v3/workflows/
See Authentication for how to obtain and manage API keys — keys work identically across v2 and v3.

Resource model

ResourceWhat it isIdentifier
WorkflowThe extraction template — a typed graph of parse / classify / splitter / extract / validate nodes.workflow_id
Document packetThe unit a workflow runs on — one or more files treated as a single document. Created by uploading.document_packet_id
RunOne execution attempt of a workflow against a packet. One packet can have many runs.run_id
All identifiers are hyphenated UUIDs (e.g. 069dcc2c-e14c-7606-8000-2ee4fb17b4e1). Path parameters are always snake_case: workflow_id, document_packet_id, run_id. The typical flow:
  1. Create a workflow (or build it visually in the dashboard).
  2. Upload and run a document in one call — it returns a run_id.
  3. Get the run until status is processed; the results envelope is inline on the same response.

Pagination

Every list endpoint is keyset-paginated and returns the same page shape:
{
  "items": [ ... ],
  "next_cursor": "eyJjcmVhdGVkX2F0Ijoi..."
}
  • ?limit= — page size, default 20, maximum 100. Values above 100 are rejected with 400, not clamped.
  • ?cursor= — the opaque next_cursor token from the previous page.
  • Iterate by following next_cursor until it is null.
  • Sort order is fixed at newest-first (-created_at, -id).
There are no totals, counts, or page numbers — a count over a growing collection is stale the moment it is computed, so v3 doesn’t pretend otherwise. List endpoints also reject unknown query parameters with 400 instead of silently ignoring them, so a typo like ?pagesize= fails loudly.

Idempotency

The three POSTs that create packets or trigger runs accept an optional Idempotency-Key header (Stripe convention — any unique string you choose, e.g. a UUID): Retrying a request with the same key replays the original response — no duplicate packet is created, no second extraction is triggered or billed. Use it to make network-timeout retries safe.
curl -X POST 'https://api.anyformat.ai/v3/document-packets/069dcc2c-e14c-7606-8000-2ee4fb17b4e1/run/' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Idempotency-Key: 5f2b6c3e-8a1d-4f7e-9c0b-1a2b3c4d5e6f'

Rate limits

Same two-tier model as v2 — submission endpoints have a stricter limit, everything else shares a higher general limit:
Tierv3 endpointsLimit
SubmissionPOST .../upload/, POST .../upload/run/, POST .../upload/from-url/, POST /v3/document-packets/{id}/run/60 requests/min
GeneralAll other authenticated endpoints600 requests/min
Exceeding a limit returns 429 Too Many Requests; wait for the number of seconds in the Retry-After header. Every response carries x-ratelimit-limit, x-ratelimit-remaining, and x-ratelimit-reset for the tier that applies.

Response headers

Every /v3/ response is stamped with the API version:
X-API-Version: 3.0.0
v3 responses carry no Deprecation or Sunset headers — those appear only on versions that are on the retirement path (as /v2/ responses do today). See Versioning & deprecation for the full header reference and how to alert on sunset signals.

Errors

Error responses use the same structured envelope as v2:
{
  "error": "Brief, human-readable error description",
  "detail": "Detailed explanation of what went wrong",
  "error_code": "MACHINE_READABLE_ERROR_CODE",
  "retryable": false,
  "request_id": "a1b2c3d4e5f67890abcdef1234567890"
}
retryable: true means the same request may succeed on retry (with backoff); retryable: false means you must change the request first. See Errors for the complete code reference. Two codes worth knowing up front:
  • 402 PAYMENT_REQUIRED — a run trigger was rejected because the organization is out of extraction credit.
  • 400 TOPOLOGY_INVALID — a workflow create/update body failed graph validation; detail.violations lists each broken rule with the offending node ids.
v3 never returns 412 Precondition Failed. Where v2 used 412 to signal “results not ready yet”, v3 returns 200 with the run’s status field — see Get run.

Endpoints at a glance

Workflows

MethodEndpointDescription
POST/v3/workflows/Create a workflow
GET/v3/workflows/List workflows
GET/v3/workflows/{workflow_id}/Get a workflow — full typed graph inline
PATCH/v3/workflows/{workflow_id}/Update a workflow
DELETE/v3/workflows/{workflow_id}/Delete a workflow

Upload

MethodEndpointDescription
POST/v3/workflows/{workflow_id}/upload/Upload a document packet (no processing)
POST/v3/workflows/{workflow_id}/upload/run/Upload and run in one call
POST/v3/workflows/{workflow_id}/upload/from-url/Create a packet from URLs

Document packets

MethodEndpointDescription
GET/v3/workflows/{workflow_id}/document-packets/List a workflow’s packets
GET/v3/document-packets/{document_packet_id}/Get a packet — files + latest_run_id
POST/v3/document-packets/{document_packet_id}/run/Run a packet — returns a new run_id
DELETE/v3/document-packets/{document_packet_id}/Delete a packet

Runs

MethodEndpointDescription
GET/v3/workflows/{workflow_id}/runs/List a workflow’s runs
GET/v3/runs/{run_id}/Get a run — status + results inline

OpenAPI schema

The full OpenAPI specification (v2 + v3) is available at: