Read a filled form back

Send Emboss a filled PDF and get back every value it holds, labelled, with a completeness verdict when the form is one Emboss already knows. Nothing is stored: Read-back never stores your file. The bytes go to a temporary file for the read, which is deleted when the response is sent.

The call

POST /forms/read takes a multipart file (the filled PDF, under the usual size limit) and an optional form_id. It runs synchronously: no job to poll, no document left behind afterward.

curl -X POST https://api.getemboss.ai/forms/read \
  -H "Authorization: Bearer sk_..." \
  -F "file=@./w9-filled.pdf"
{
  "recognised": "own_layout",
  "match": "exact",
  "form_id": "6c47f7f5-f921-4698-910f-95dd7d81310b",
  "fingerprint": "fillable:3a9f2c8e1d47b6a0",
  "file_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85",
  "page_count": 1,
  "fields": [
    {
      "name": "business_name",
      "page": 1,
      "type": "text",
      "value": "Copperline Hospitality Group, LLC",
      "filled": true,
      "id": 1,
      "label": "Business name",
      "required": true
    }
  ],
  "unmatched": [],
  "counts": { "fields": 24, "filled": 24, "required": 15, "required_filled": 15, "signatures_missing": 0 },
  "complete": true
}

Recognition order

Emboss tries to recognise the form the file came from, in this order:

  1. form_id, if you send one: the call reads that form's own contract to label the values. Not your form, or not found: 404. recognised is "form_id".
  2. own_layout: without a form_id, if the file's fingerprint matches the layout_fingerprint of a form already in your account, that form's contract labels the values. form_id in the response is that form's id.
  3. shared_layout: the fingerprint matches a blank-form layout Emboss has seen before, shared across accounts. That layout's fields label the values. form_id is null: a shared layout names the form, not who uploaded it first.
  4. none: no match. recognised is "none" and the values come back raw, keyed by the PDF's own widget names, with no label and no completeness verdict.

When recognition succeeds through own_layout or shared_layout, match says how: "exact" when the file's bytes fingerprint identically to the stored layout, "loose" when the file was saved by a different program but its printed text and field geometry still line up with a stored layout closely enough to trust it. match is null for form_id recognition and for none. A form from the library of forms Emboss already knows is recognised "exact" on the copy Emboss seeded and "loose" on a copy someone re-saved or re-scanned through another program.

fields always has one entry per widget in the file you sent, whichever branch matched. id, label and required appear only when the form is known (recognition was form_id, own_layout or shared_layout); unmatched lists any widget name the matching contract does not know. complete is true when every required field carries a value, false when one does not, and null for an unknown form, where counts.required and counts.required_filled are both 0. counts.signatures_missing counts empty signature boxes separately and never changes complete, since a signature is a person's act, not a value.

A checkbox or radio counts as filled when its value equals the widget's own on-state; a text or signature field counts as filled when it holds a non-empty string. This is the same rule the verify endpoint uses, since both read the same values off the same PDF. A radio group appears once in fields, under the group's own name, carrying whichever option is selected.

If the file has no form boxes

A scanned or flattened PDF has no widgets to read, so POST /forms/read returns 400 with the detail "no form boxes found; scanned or flattened forms are not read yet". Reading values out of a scan is a different problem (optical recognition of handwriting and marks, not widget values) that read-back does not attempt.

Read before you lock

A form locked with the free Lock a filled form tool (flatten_pdf) has no form boxes left, so it cannot be read back or checked. Read it or verify it first, then lock it.

Pricing

Read-back is billed as one read at 1¢, which is flat, any length. The first 5 each month are free, subject to the same free page cap every free operation carries. The retention window other operations carry does not apply here: read-back has nothing to delete, since nothing was ever stored. See Ephemeral processing for what that window covers.

The pay-per-call read (POST /pay/read) works differently: the file is held until the read is paid for, and deleted with the price if no payment arrives within the hour; the values it read stay with the job for 24 hours so a lost answer can be fetched again. See x402 and MPP.

Also available as a tool

The same call is exposed as read_form on MCP and as the read_form skill on A2A, both taking a file and an optional form_id. On the pay-per-call API, the same operation is /pay/read: an anonymous caller pays per read, with no account and no own_layout recognition, since there is no account to hold a prior form against.

Where to read more

  • The submission package is the next step once a filled form is complete: hand over the form, its attachments, and a receipt in one file.
  • Prepare, commit and verify covers the deterministic verification engine that read-back's filled rule shares.
  • Security lists what Emboss stores and for how long, and where read-back's "nothing at all" fits into that.