Bulk runs
The simplest way to fill many PDFs is the batch endpoint. Upload a spreadsheet, map the columns once, and Emboss fills a PDF per row for you. See Batch fill for that flow.
You can also fill many PDFs with a client-side loop, calling the single-form endpoints yourself. Reach for the loop when you want full control over concurrency and retries, or when your inputs are separate PDFs rather than rows of one form.
The pattern
Each form follows the usual chain: create, poll until ready, fill, download.
For a batch, run several of those chains concurrently, but cap how many are in
flight so you don't blow past the rate limit: 60 calls per API key per clock
hour that start work (creating, filling, preparing, verifying, reading back,
quoting, suggesting a mapping, starting a batch, or searching the library).
Status checks, downloads and commits don't count. A form you create and then
fill from your own data takes two of those calls.
async function runBatch(pdfPaths, key, concurrency = 5) {
const queue = [...pdfPaths];
const results = [];
async function worker() {
while (queue.length) {
const path = queue.shift();
try {
results.push({ path, status: await fillOne(path, key) });
} catch (err) {
results.push({ path, error: String(err) });
}
}
}
await Promise.all(Array.from({ length: concurrency }, worker));
return results;
}
fillOne is your single-form chain (create → poll → fill → download). Keep
concurrency modest: 5 to 10 in flight is plenty and leaves rate-limit
headroom.
Handling rate limits
If a request returns 429, this API key has used its calls for the current
clock hour. The count starts again at the top of the next hour (UTC), and the
answer carries no Retry-After header, so a short backoff keeps failing. Wait
for the next hour, spread a large run across hours, or ask for a higher limit
at contact@getemboss.ai.
Track what succeeded
There's no automatic idempotency across a batch, so record which inputs finished. If a run is interrupted, re-submit only the ones that didn't complete. Resubmitting a form just creates a new one.
For the single-form flow each worker runs, see Fill from your data and Tracking jobs.