Batch fill
Fill one form from every row of a spreadsheet. Upload a CSV or XLSX, map its columns to the form's fields once, and Emboss fills a separate PDF for each row. Each row is a deterministic fill with no inference, so it is fast and cheap. For the single-form version of this, see Fill from your data.
There are two steps. First get a column mapping that you review and edit, then run the batch. The mapping is computed once because your spreadsheet columns are the same for every row.
1. Create the form and wait for detection
Upload the flat PDF and poll until it is ready (see
Tracking jobs):
curl -X POST https://api.getemboss.ai/forms \
-H "Authorization: Bearer sk_..." \
-F "file=@./invoice.pdf"
2. Suggest a column mapping
Send your spreadsheet to suggest-mapping. Emboss reads the column headers and
the form's fields and proposes a mapping. This is one context fill.
curl -X POST https://api.getemboss.ai/forms/{form_id}/suggest-mapping \
-H "Authorization: Bearer sk_..." \
-F "file=@./customers.csv"
{
"mapping": {
"Company": { "field_id": 0, "confidence": "high" },
"Phone": { "field_id": 1, "confidence": "high" }
},
"unmapped_columns": ["Internal Notes"]
}
Each field_id is the integer id from the form's contract (see
The contract shape). Review the mapping. Change any
field_id, drop a column, or add one Emboss missed. If you already know the
mapping you want, you can skip this step and supply your own in the next one.
3. Run the batch
Send the same spreadsheet plus the resolved mapping as a JSON string. Emboss
returns a batch_id right away and fills the rows in the background.
curl -X POST https://api.getemboss.ai/forms/{form_id}/fill-batch \
-H "Authorization: Bearer sk_..." \
-F "file=@./customers.csv" \
-F 'mapping={"Company":{"field_id":0},"Phone":{"field_id":1}}'
{ "batch_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d" }
The response status is 202 Accepted. The batch runs in the background. Poll it with the call below.
Each row is one standard fill. A row that cannot be filled is recorded as failed and does not stop the rest of the batch.
4. Poll the batch
curl https://api.getemboss.ai/forms/fill-batch/{batch_id} \
-H "Authorization: Bearer sk_..."
{
"status": "complete",
"total": 500,
"filled": 498,
"failed": 2,
"results": [
{ "row": 1, "status": "filled", "pdf_url": "/forms/fill-batch/{batch_id}/rows/1/pdf" },
{ "row": 7, "status": "failed", "error": "row 7: one or more values are not valid for their field; checkboxes take yes or no (field ids: 12)" }
]
}
The results array has one entry per row. Filled rows carry a pdf_url. Failed
rows carry an error, so you can fix that row and run it again.
Row numbers count the spreadsheet's data rows from 1, after rows that are entirely blank are dropped, so they can differ from your sheet's own line numbers.
5. Download the filled PDFs
Fetch one row's PDF:
curl https://api.getemboss.ai/forms/fill-batch/{batch_id}/rows/1/pdf \
-H "Authorization: Bearer sk_..." -o row-1.pdf
Or get all of them in one zip:
curl https://api.getemboss.ai/forms/fill-batch/{batch_id}/zip \
-H "Authorization: Bearer sk_..." -o batch.zip
Limits and pricing
A batch is capped at 1000 rows. The mapping call is one context fill and each
filled row is one standard fill, both drawing from your monthly free allowance;
a row that fails is not charged. Without a payment method on file, a batch with
more rows than the free fills you have left this month is refused with 402
before anything is filled: the answer's code is over_free_tier, and it
carries rows, remaining and billing_url. See Pricing for the
rates.
Validation errors
fill-batch checks everything before it starts the job, so a bad request creates
no batch and bills nothing.
400if the spreadsheet is empty or unreadable, the mapping is not valid JSON, the mapping names a column not in the spreadsheet or a field not in the form, or there are more than 1000 rows.409if the form is notready.404if the form or the batch is not yours.413if the spreadsheet is over 10 MB.
fill-batch takes no Idempotency-Key: a retried request starts, and bills,
a second batch. Check GET /forms/fill-batch/{batch_id} before you send it again.