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" }). Top-level strings/numbers are also stored as report-search metadata.
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://re-port-flow.com/{workspaceId}/design/{designId}/outputs?requestId={requestId}",
"files": [
{
"fileName": "invoice.pdf",
"fileId": "7f3d1a2b-4c5e-6f7a-8b9c-0d1e2f3a4b5c",
"passthrough": { "pageId": "abc123" },
"share": {
"shareType": "workspace",
"url": "https://re-port-flow.com/file/{requestId}/{fileId}",
"passcodeEnabled": false
}
}
]
}
FieldTypeDescription
requestIdstring (UUID)Request ID, used by the download endpoint
urlstring (URI)URL of the app screen (output history) where the generated result can be reviewed. Not a direct file download URL — use file download to fetch files
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.

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.

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 /v1/file/download/{requestId}/{fileId}
(the `url` in the response is an app-screen link and cannot be used
to download the file)

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,
fileId: files[0].fileId,
// Link to the app screen (output history) where the result can be
// reviewed. Requires a login; it is not a direct file download URL.
outputsUrl: url,
});
});

Fetch the generated file with requestId / fileId via file download. Authenticate with either the appkey header or an OAuth 2.0 access token (Authorization: Bearer) — see Authentication for which to pick.

Generate and fetch with credentials for the same workspace

An appkey is issued per workspace, and an OAuth 2.0 access token is bound to the workspace chosen at consent. Credentials for a different workspace than the one that generated the file cannot retrieve its requestId / fileId.

Keeping the appkey on your server, as above, fits "automating a single workspace": both generation and retrieval stay inside that appkey's workspace.

To let external or third-party users work with their own workspace data, use OAuth 2.0 Authorization Code + PKCE, have the user authorize, and issue both the generation request and the download with that same access token (required scope: pdf:generate). A file generated with the server appkey above cannot be fetched with a token for another workspace.

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.

FAQ

Should I use sync or async generation?

Use Single PDF Sync Generation when you need the PDF back immediately. Use this async endpoint when generation takes a long time, or when you want to avoid the 120-second sync timeout.

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 the download endpoint.

Next steps