Skip to main content

Single PDF Async Generation

The POST /file/async/single endpoint generates a single PDF asynchronously from the specified design and parameters. It returns a requestId and file information immediately, so the client never has to wait for rendering.

Endpoint

  • URL: https://api.re-port-flow.com/v1/file/async/single
  • Method: POST
  • Auth: appkey header required
  • Timeout: none (async processing)
  • Request body limit: 50MB (after Base64 encoding, roughly 37MB of binary data)

Example

cURL

curl -X POST https://api.re-port-flow.com/v1/file/async/single \
-H "appkey: your-application-key" \
-H "Content-Type: application/json" \
-d '{
"designId": "550e8400-e29b-41d4-a716-446655440000",
"version": 1,
"content": {
"fileName": "invoice.pdf",
"shareType": "01",
"passcodeEnabled": false,
"params": {
"customerName": "John Doe",
"invoiceNumber": "INV-2024-001",
"amount": 10000
}
}
}'

Request parameters

FieldTypeRequiredDescription
designIdstring (UUID)Design ID
versionintegerDesign version
content.fileNamestringFile name (any character is allowed except `/ \ : * ? " < >
content.shareTypestring-Share type on the request side is a numeric code: "01" = workspace (default), "02" = invitee, "03" = public URL. In the response, share.shareType is returned as the human-readable name (workspace / invited / public)
content.passcodeEnabledboolean-Whether to enable passcode protection (default false)
content.passthroughobject-Arbitrary metadata that will be echoed back in files[].passthrough (e.g. { "pageId": "abc123" })
content.paramsobjectTemplate parameters. The expected structure is available from the design parameter API

Response

Success (202 Accepted)

{
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://api.re-port-flow.com/v1/file/download/{requestId}",
"files": [
{
"fileName": "invoice.pdf",
"fileId": "7f3d1a2b-4c5e-6f7a-8b9c-0d1e2f3a4b5c",
"passthrough": { "pageId": "abc123" },
"share": {
"shareType": "workspace",
"url": "https://app.re-port-flow.com/file/{requestId}/{fileId}",
"passcodeEnabled": false
}
}
]
}
FieldTypeDescription
requestIdstring (UUID)Request ID, used by the download endpoint
urlstring (URI)ZIP download URL
filesarrayGenerated files
files[].fileNamestringFile name
files[].fileIdstringFile ID, used by the per-file download endpoint
files[].passthroughobjectThe content.passthrough value supplied on the request (only when set)
files[].share.shareTypestringShare type (workspace / invited / public)
files[].share.urlstringSharable URL
files[].share.passcodeEnabledbooleanWhether passcode protection is enabled
files[].share.passcodestringServer-generated passcode (only when passcodeEnabled=true AND immediately after generation)
When to use passthrough

ReportFlow 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.

Errors

Errors are the same shape as the synchronous endpoint. See Single PDF Sync Generation — Errors.

Async flow

1. Client → API: send generation request

2. API → Client: returns requestId / url / files immediately (202 Accepted)

3. API: starts background PDF generation

4. API: uploads the result to S3 when done

5. Client: download the PDF via the returned `url` or
/v1/file/download/{requestId}/{fileId}

Use cases

Case 1: background generation

Accept the user request immediately and let the rendering happen in the background.

app.post('/api/generate-report', async (req, res) => {
const response = await axios.post(
'https://api.re-port-flow.com/v1/file/async/single',
{
designId: '...',
version: 1,
content: { fileName: 'report.pdf', params: req.body },
},
{ headers: { appkey: process.env.APP_KEY } },
);

const { requestId, url, files } = response.data;

res.status(202).json({
message: 'Report generation started',
requestId,
downloadUrl: url,
fileId: files[0].fileId,
});
});

Use ReportFlow's built-in webhook to be notified when generation finishes — no polling required.

See the Webhook guide for details, including HMAC-SHA256 signature verification.

Next steps