Multiple PDF Async Generation
The POST /file/async/multiple endpoint generates multiple PDF files asynchronously from the specified template and multiple parameters, and saves them as a ZIP file.
Endpoint Information
- URL:
https://api.re-port-flow.com/v1/file/async/multiple - Method:
POST - Authentication:
appkeyheader required - Timeout: None (async processing)
- Request Size Limit: 50MB (Base64-encoded; ~37MB raw equivalent)
Usage Examples
cURL
curl -X POST https://api.re-port-flow.com/v1/file/async/multiple \
-H "appkey: your-application-key" \
-H "Content-Type: application/json" \
-d '{
"designId": "0eUDdgAjNXrrItA2",
"version": 1,
"contents": [
{
"fileName": "invoice_001.pdf",
"shareType": "01",
"passcodeEnabled": false,
"params": { "customerName": "John Doe", "invoiceNumber": "INV-001" }
},
{
"fileName": "invoice_002.pdf",
"shareType": "01",
"passcodeEnabled": false,
"params": { "customerName": "Jane Smith", "invoiceNumber": "INV-002" }
}
]
}'
JavaScript
async function generateMultiplePDFsAsync(designId, contents) {
const response = await axios.post(
`https://api.re-port-flow.com/v1/file/async/multiple`,
{
designId,
version: 1,
contents
},
{
headers: {
'appkey': process.env.APP_KEY
}
}
);
const { requestId, url, files } = response.data;
console.log('ZIP generation started:', { requestId, url, files });
return { requestId, url, files };
}
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
designId | string | ✓ | Template ID (16-character alphanumeric, e.g. 0eUDdgAjNXrrItA2) |
version | integer | ✓ | Version number |
webhookUrl | string | - | Webhook destination for this request (https, up to 2048 characters). Must match the URL of an enabled webhook endpoint registered in the workspace, otherwise 400 WEBHOOK_URL_NOT_ALLOWED. When set, only that endpoint receives this request's events (details) |
contents | array | ✓ | Array of ContentDto (1 to 100 items) |
contents[].fileName | string | ✓ | File name (anything except / \ : * ? " < > | and control characters is allowed; must be unique within the array, case-insensitive) |
contents[].shareType | string | - | Share type (request side uses numeric codes). "01" = workspace share (default) / "02" = invited-only / "03" = public URL share. The response share.shareType returns the human-readable name. |
contents[].passcodeEnabled | boolean | - | Enable passcode protection (default: false). |
contents[].passthrough | object | - | Per-file arbitrary metadata echoed back in files[].passthrough. Top-level strings/numbers are also stored as report-search metadata. |
contents[].params | object | ✓ | Parameters (check structure via Template Parameters API) |
Response
Success (202 Accepted)
{
"requestId": "kZ3mP9qL2xV7nR4t",
"url": "https://re-port-flow.com/{workspaceId}/templates/{designId}/outputs?requestId={requestId}",
"files": [
{
"fileName": "invoice_001.pdf",
"fileId": "a8Fh2LkQ9zT4wE6y",
"share": {
"shareType": "workspace",
"url": "https://re-port-flow.com/file/{requestId}/a8Fh2LkQ9zT4wE6y",
"passcodeEnabled": false
}
},
{
"fileName": "invoice_002.pdf",
"fileId": "b3Gk7MnP1qR5sT9v",
"share": {
"shareType": "workspace",
"url": "https://re-port-flow.com/file/{requestId}/b3Gk7MnP1qR5sT9v",
"passcodeEnabled": false
}
}
]
}
| Field | Type | Description |
|---|---|---|
requestId | string | Request ID (16-character alphanumeric; used with the download endpoint) |
url | string (URI) | URL of the app screen (output history) where the generated result can be reviewed. Not a direct file download URL — use PDF download to fetch files |
files | array | Information for each generated PDF file |
files[].fileName | string | PDF file name |
files[].fileId | string | Individual file ID (used with individual download endpoint) |
files[].passthrough | object | Value of contents[].passthrough from the request (only when specified) |
files[].share.shareType | string | Share type (workspace / invited / public) |
files[].share.url | string | File view URL |
files[].share.passcodeEnabled | boolean | Passcode enabled flag |
files[].share.passcode | string | Server-generated passcode (only when passcodeEnabled=true, immediately after generation) |
passthroughReportFlow does not echo back params (the data used to render the
PDF) on responses or webhooks, both for payload size and to avoid leaking
business data to webhook endpoints.
If you need to know which business record a PDF corresponds to, put your
own DB id (or any opaque token) into passthrough on the request. The
exact value comes back on the response and the webhook unchanged.
{
"fileName": "invoice.pdf",
"passthrough": { "invoiceId": "INV-001", "tenantId": "acme" },
"params": { "customerName": "John Doe", "amount": 10000 }
}
When the webhook arrives, look up your DB by invoiceId to find the
record to update. params (the customer name, amount, etc.) is never
sent off-server.
Top-level string/number values in passthrough are also stored as
report-search metadata (both in the generated PDF's XMP metadata and in the
Re:port Flow app's report-search index). See
passthrough and report-search metadata
for which values are indexed, the limits, and why personal data doesn't belong there.
Error Responses
Same error responses as Sync Single PDF Generation, plus the following:
400 Bad Request (duplicate fileName)
{
"statusCode": 400,
"code": "FILE_NAME_DUPLICATED",
"message": [
"fileName values in contents must be unique (case-insensitive). Give each file a unique name."
],
"error": "Bad Request",
"details": [
{
"field": "contents",
"code": "FILE_NAME_DUPLICATED",
"message": "fileName values in contents must be unique (case-insensitive). Give each file a unique name."
}
],
"docsUrl": "https://doc.re-port-flow.com/en/docs/guides/error-codes#file_name_duplicated"
}
Cause: Multiple entries in contents share the same fileName (including case-insensitive matches).
When only some files fail
If only some files fail after the request was accepted (202), Get Generation Status returns status: "completed" with the failed files in failedFiles. Over webhooks, the successful files arrive as file.completed. The failed ones arrive as file.failed with error.code: "PARTIAL_FAILURE" only when the generation request specified webhookUrl, and only at that URL. If every file fails, the status is failed (error.code: "FILE_GENERATION_FAILED") with the per-file reasons in failedFiles. See Webhook Notifications.
Use Cases
Bulk Invoice Generation
async function generateBulkInvoices(invoices) {
const batchSize = 100;
const batches = chunkArray(invoices, batchSize);
const results = [];
for (const [index, batch] of batches.entries()) {
console.log(`Processing batch ${index + 1}/${batches.length}...`);
const contents = batch.map(invoice => ({
fileName: `invoice_${invoice.number}.pdf`,
shareType: '01',
passcodeEnabled: false,
params: invoice
}));
const result = await generateMultiplePDFsAsync('template-id', contents);
results.push(result);
// Rate limiting
if (index < batches.length - 1) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
return results;
}
FAQ
How many PDFs can one request generate?
Up to 100 items per request (more returns 400 TOO_MANY_CONTENTS). The request must also stay
within the request size cap (50MB after Base64 encoding) and the rate limit (100
requests/min for async endpoints). For large runs, split the work across several requests
and batch them inside the rate limit.
How do I know when generation has finished?
Set up a webhook and you receive completion in real time with no polling — see the
Webhook guide. Without a webhook, take the requestId from the response
and poll Get Generation Status (GET /v1/file/status/{requestId}) until status
becomes completed or failed. While generating, the response carries a Retry-After header —
use it as your polling interval. See Async Workflows.
Next Steps
- Bulk ZIP Download - How to download generated ZIP files
- Async Workflows - Best practices for bulk generation