Skip to main content

PDF Download

These endpoints retrieve PDFs that have already been generated. Pass a requestId to download an entire request as a ZIP, or a requestId plus a fileId to fetch one PDF on its own. Both require authentication — either the appkey header or an OAuth 2.0 access token — and both are how you collect output after an async job finishes or a webhook arrives.

ZIP Bulk Download​

Endpoint Information​

  • URL: https://api.re-port-flow.com/v1/file/download/{requestId}
  • Method: GET
  • Authentication: appkey header required

Response (200 OK)​

Response body: ZIP file (binary)

HeaderDescriptionExample
Content-TypeContent typeapplication/zip
Content-LengthFile size (bytes)307200
Content-DispositionFile name: <template name>_<requestId>.zip, URL-encodedattachment; filename="Invoice_kZ3mP9qL2xV7nR4t.zip" (for a template named "Invoice")

Usage Example​

curl -X GET https://api.re-port-flow.com/v1/file/download/kZ3mP9qL2xV7nR4t \
-H "appkey: your-application-key" \
--output output.zip

JavaScript Example​

async function downloadZip(requestId) {
const response = await axios.get(
`https://api.re-port-flow.com/v1/file/download/${requestId}`,
{
headers: {
'appkey': process.env.APP_KEY
},
responseType: 'arraybuffer'
}
);

fs.writeFileSync('output.zip', response.data);
return response.data;
}

Individual PDF Download​

Endpoint Information​

  • URL: https://api.re-port-flow.com/v1/file/download/{requestId}/{fileId}
  • Method: GET
  • Authentication: appkey header required

Usage Example​

curl -X GET https://api.re-port-flow.com/v1/file/download/kZ3mP9qL2xV7nR4t/Hn4sT8wQ1cV6bX2e \
-H "appkey: your-application-key" \
--output invoice.pdf

JavaScript Example​

async function downloadSingleFile(requestId, fileId) {
const response = await axios.get(
`https://api.re-port-flow.com/v1/file/download/${requestId}/${fileId}`,
{
headers: {
'appkey': process.env.APP_KEY
},
responseType: 'arraybuffer'
}
);

const returnedFileId = response.headers['file-id'];
console.log('Downloaded file ID:', returnedFileId);

return response.data;
}

Error Handling​

See Error Codes for the error body shape and the full list of codes.

StatuscodeMeaningWhat to do
404FILE_NOT_FOUNDWrong requestId / fileId, a requestId of another workspace (a 404 rather than a 403, so that its existence is not revealed), a single generation that failed more than 24 hours ago (its job record is gone, so the failure can no longer be detected), or the output was deleted (no files left after a successful generation)Make sure you use the values from the generation response and the credentials of the workspace that generated them
409FILE_NOT_READYStill generatingWait Retry-After seconds and resend, or wait for completion with Get Generation Status
422FILE_GENERATION_FAILEDGeneration of the request (or of the specified file) failedCheck error / failedFiles in Get Generation Status and generate again
Change from the previous behavior

Previously, downloading a file that was still being generated returned 404. Now a file that is still generating returns 409 FILE_NOT_READY and a failed generation returns 422 FILE_GENERATION_FAILED. A 404 means the ID is wrong, belongs to another workspace, is a single generation that failed more than 24 hours ago, or the output was deleted (a request that is still generating also returns 404 when its job record is missing). If your code treated 404 as "still generating" and polled the download endpoint, switch to Get Generation Status.

404 Not Found​

{
"statusCode": 404,
"code": "FILE_NOT_FOUND",
"message": "File not found: kZ3mP9qL2xV7nR4t",
"error": "Not Found",
"details": [],
"docsUrl": "https://doc.re-port-flow.com/en/docs/guides/error-codes#file_not_found"
}

409 Conflict​

HTTP/1.1 409 Conflict
Retry-After: 2
Content-Type: application/json

{
"statusCode": 409,
"code": "FILE_NOT_READY",
"message": "The file is still being generated. Retry after 2 seconds or poll GET /v1/file/status/kZ3mP9qL2xV7nR4t.",
"error": "Conflict",
"details": [],
"docsUrl": "https://doc.re-port-flow.com/en/docs/guides/error-codes#file_not_ready",
"retryAfter": 2
}

422 Unprocessable Entity​

{
"statusCode": 422,
"code": "FILE_GENERATION_FAILED",
"message": "PDF generation failed for this request (PARAMS_TYPE_MISMATCH). See GET /v1/file/status/kZ3mP9qL2xV7nR4t for the reason.",
"error": "Unprocessable Entity",
"details": [],
"docsUrl": "https://doc.re-port-flow.com/en/docs/guides/error-codes#file_generation_failed"
}

Best Practices​

1. Wait for completion before downloading​

Use Get Generation Status or the file.completed webhook to know when a file is ready, instead of calling the download endpoint repeatedly.

2. Verify File ID​

Check the File-ID header to verify you downloaded the correct file.

const fileId = response.headers['file-id'];
if (fileId !== expectedFileId) {
throw new Error('Downloaded wrong file');
}

FAQ​

Should I download by requestId or by fileId?​

To take everything from one request at once, pass only requestId and use ZIP Bulk Download. When you need just one file out of the batch, pass both requestId and fileId and use Individual PDF Download.

What should I do when I get a 404?​

A 404 (FILE_NOT_FOUND) means the requestId / fileId is wrong, belongs to another workspace, is a single generation that failed more than 24 hours ago, or the output was deleted. Make sure you use the values from the generation response unchanged and the credentials of the workspace that generated them. A file that is still being generated normally returns 409 FILE_NOT_READY (only a request whose job record could not be saved returns 404 while still generating).

How do I know when generation has finished?​

Wait for status to become completed with Get Generation Status (GET /v1/file/status/{requestId}), or receive the file.completed webhook. The failure notification (file.failed) is sent only when the generation request specified webhookUrl, and only to that URL. You don't need to call the download endpoint repeatedly.

Next Steps​