Guides
Batch Processing
The batch endpoint lets you submit multiple PDF URLs in a single API call. All conversions are processed asynchronously, and you can poll a single URL to monitor progress.
How it works
- Send a
POSTto/v1/convert/batchwith an array of PDF URLs. - The API returns a
batchIdand apollUrl(status 202). - Poll
GET /v1/batch/:batchIdto check progress. - When all requests are complete, download each
resultUrl.
Each URL in the batch consumes one request from your monthly quota.
Submit a batch
curl - batch request
curl -X POST https://api.pdfpipe.dev/v1/convert/batch \
-H "Authorization: Bearer pk_..." \
-H "Content-Type: application/json" \
-d '{
"urls": [
{ "url": "https://example.com/invoice-1.pdf" },
{ "url": "https://example.com/invoice-2.pdf", "format": "text" },
{
"url": "https://example.com/report.pdf",
"type": "attachment",
"pages": "1-3",
"metadata": { "department": "finance" }
}
],
"defaults": { "format": "json" },
"returnMethod": "inline",
"webhook": { "url": "https://example.com/hooks/batch-complete" }
}'Per-URL options: Each URL object can set
format, type, pages, and metadata (string key/value pairs stored with that request). The defaults object (format, type) applies to any URL that doesn't specify its own value. returnMethod and webhook are set once at the top level and apply to the whole batch.Batch response (202)
202 - Response
{
"batchId": "batch_a1b2c3d4e5f6...",
"requests": [
{ "requestId": "req_aaa...", "url": "https://example.com/invoice-1.pdf", "status": "queued" },
{ "requestId": "req_bbb...", "url": "https://example.com/invoice-2.pdf", "status": "queued" },
{ "requestId": "req_ccc...", "url": "https://example.com/report.pdf", "status": "queued" }
],
"pollUrl": "/v1/batch/batch_a1b2c3d4e5f6..."
}Poll for progress
curl - poll batch status
curl https://api.pdfpipe.dev/v1/batch/batch_a1b2c3d4e5f6... \
-H "Authorization: Bearer pk_..."200 - Batch status
{
"batchId": "batch_a1b2c3d4e5f6...",
"total": 3,
"completed": 2,
"failed": 0,
"pending": 1,
"requests": [
{ "requestId": "req_aaa...", "status": "complete", "resultUrl": "https://..." },
{ "requestId": "req_bbb...", "status": "complete", "resultUrl": "https://..." },
{ "requestId": "req_ccc...", "status": "processing" }
]
}200 - Batch status (returnMethod: inline, with a failure)
{
"batchId": "batch_a1b2c3d4e5f6...",
"total": 2,
"completed": 1,
"failed": 1,
"pending": 0,
"requests": [
{
"requestId": "req_aaa...",
"status": "complete",
"contentType": "application/json",
"content": "{\"pages\":[{\"pageNumber\":1,\"text\":\"...\"}],...}"
},
{ "requestId": "req_bbb...", "status": "failed", "errorCode": "NOT_A_PDF" }
]
}Poll every 5-10 seconds. When pending reaches 0, all jobs are done. Each completed request includes a presigned resultUrl, or content when the batch used returnMethod: "inline" (you can also append ?returnMethod=inline to the poll URL). Failed requests carry an errorCode; poll GET /v1/status/:requestId for the full message and suggestion.
Full Node.js example
Node.js
const response = await fetch("https://api.pdfpipe.dev/v1/convert/batch", {
method: "POST",
headers: {
"Authorization": "Bearer pk_...",
"Content-Type": "application/json",
},
body: JSON.stringify({
urls: pdfUrls.map(url => ({ url })),
defaults: { format: "json" },
webhook: { url: "https://example.com/hooks/batch" },
}),
});
const { batchId, pollUrl } = await response.json();
// Poll until all complete
let batch;
do {
await new Promise(r => setTimeout(r, 5000));
// pollUrl is "/v1/batch/..." so prepend only the host
const poll = await fetch(`https://api.pdfpipe.dev${pollUrl}`, {
headers: { "Authorization": "Bearer pk_..." },
});
batch = await poll.json();
console.log(`Progress: ${batch.completed}/${batch.total}`);
} while (batch.pending > 0);
// Download all results
for (const req of batch.requests) {
if (req.status === "complete" && req.resultUrl) {
const doc = await fetch(req.resultUrl).then(r => r.json());
console.log(`${req.requestId}: ${doc.totalPages} pages`, doc.pages[0].text);
} else if (req.status === "failed") {
console.warn(`${req.requestId} failed: ${req.errorCode}`);
}
}Batch size limits
The maximum number of URLs per batch depends on your tier:
| Tier | Max batch size |
|---|---|
| Free | 5 URLs |
| Starter | 25 URLs |
| Pro | 50 URLs |
| Business | 100 URLs |