Skip to main content
A document packet is the unit a workflow runs on: one or more files that anyformat treats as a single document. Almost always it’s a packet of one — you upload a file, you get a packet, and the two ideas line up 1-to-1. The packet only stands out as its own concept when you deliberately bundle several files (say, a contract and its two annexes) that belong together for extraction.

Why a packet, not just a file

Extraction is scoped to the packet, not to the individual files inside it. That means:
  • Cross-file context is preserved — parse and extract see the whole bundle at once, not one file at a time.
  • Results come back at the packet level, as a single set of extracted fields for the whole document.
  • Classify, split, and validate operate on the packet as one input.
For a one-file packet this looks identical to file-level processing. For a multi-file packet, it’s what lets you treat “contract + annexes” or “invoice + supporting scans” as one document.

Packets and files

What it isWhat it’s for
Document packetThe bundle. The runnable unit.The handle you upload, run, and pull results against.
FileOne artifact inside the packet — a PDF, an image, an email.Reading an individual file’s parsed content or per-file breakdown.
The packet has an id; each file inside it has its own id too. You spend almost all your time working with packets — file ids only come up when you need to look at one specific file within a multi-file packet.
Two API names — one object. On v3 the packet is addressed natively: every request and response uses document_packet_id (see the packet endpoints). The frozen v2 surface still calls the same object a file collectionfile_collection_id, sometimes collection_id — used the same way. The ids are interchangeable across versions; mapping details in the migration guide.

How you get one

You create a packet by uploading. Two ways to hand anyformat the bytes:
  • Direct upload (multipart) — send the file bytes in the request. The response comes back with status: "uploaded" once the bytes are in storage; you can run immediately. Best when the bytes are on the user’s machine or in your app’s memory.
  • From a URL — give anyformat an HTTPS URL (a presigned S3 link, a hosted asset) and the server fetches the bytes for you. Best when the file already lives in object storage you can presign, or at a public URL — no need to stream it through your backend.
Both produce a packet id you can run, poll, and pull results against. See Files for supported formats and size limits.
Two API shapes — one concept. On v3, upload with POST .../upload/ (multipart, 1–10 files into one packet) or POST .../upload/from-url/ (1–10 HTTPS URLs, all-or-nothing) — the URL import is atomic, so a 201 means the packet is fully in storage and there is no pending-fetch state to reason about. On v2, use POST .../files/ or POST .../files/from-url/, where the URL fetch completes asynchronously: the response returns status: "pending" while the fetch is in flight, and you should trigger the run on the returned packet id straight away rather than polling the packet listing — the listing’s status reflects extraction state, not upload-fetch state.

One file vs. multiple files

One file (the default). Every upload creates its own single-file packet. In everyday use the packet id and the file id are effectively interchangeable — you address the packet. Multiple files. Bundle them into one packet only when they belong together as a single document. The packet is then processed as a whole; extraction runs over the bundle, not file-by-file. If two files are unrelated, upload them as two packets — that keeps their results independent.

What’s next?

Files

Supported formats, size limits, and per-file mechanics

Runs & results

What happens when you run a workflow on a packet, and the shape of what comes back