Download URL
Last updated March 23, 2026
When a document reaches the success status, the API response includes a download_url field. This is a temporary signed URL pointing to the generated PDF or image stored on S3. It triggers a file download (not inline display) and expires after 1 hour.
{
"document": {
"id": "a5e86d72-f5b7-43d4-a04e-8b7e08e6741c",
"status": "success",
"download_url": "https://pdfmonkey-production.s3.eu-west-1.amazonaws.com/...",
"preview_url": "https://preview.pdfmonkey.io/...",
"public_share_link": null
}
}
When the download URL appears
The download_url is only populated when the document status is success. For all other statuses (draft, pending, generating, failure), the field returns null.
If you just created a document and the URL is null, the most likely reason is that generation has not finished yet. See The Download URL is Empty for a full diagnosis.
URL expiration (1 hour)
Download URLs expire after 1 hour
Every time you fetch the document details (via the API or an integration), you receive a fresh URL with a new 1-hour window. You never need to regenerate the document itself to get a working link.
If you need a permanent URL that never expires, consider using Share Links instead.
Refreshing an expired download URL
If a download URL has expired, fetch the document again to get a new one:
- Via the API:
GET /api/v1/document_cards/:id– see API Documents reference - Via an integration: Use a “Get Document” or “Find Document” action in Zapier, Make, or another platform
- Via the Dashboard: Open the document detail page – the download link is always current
You do not need to regenerate the document. The file remains on S3 until it is deleted – only the signed URL expires.
Download URL vs. other URL fields
| Field | Purpose | Expiration |
|---|---|---|
download_url | Temporary signed URL that downloads the generated file. Only populated on success status. | 1 hour |
preview_url | Renders a preview of the document in the browser. Works even for drafts. Not a download link – do not use it to retrieve the final file. See Embedding a Preview. | Does not expire |
public_share_link | Permanent public URL to view and download the file. Available on Pro+ and Premium plans only. See Share Links. | Does not expire |
Best practices
- Download promptly. When you receive a webhook notification or poll for completion, download the file right away.
- Store the file, not the URL. If you need the file later, save it to your own storage (S3, Google Drive, etc.) rather than relying on the temporary download URL.
- Re-fetch when needed. If you do need the URL later, call the API again to get a fresh one – it takes a single GET request.
- Use share links for distribution. If you need a stable URL to embed in emails or web pages, use
public_share_linkinstead (requires Pro+ or Premium plan). See Share Links.
Troubleshooting
- The Download URL is Empty – common reasons why the URL is
null - The Download URL Gives a 403 Error – how to handle expired URLs
Related pages
- Document Statuses and Lifecycle – understand when
download_urlbecomes available - Generate PDFs with the API – end-to-end generation workflow
- Webhooks – get notified when a document is ready to download
- Automatic Deletion (TTL) – how long files are stored before cleanup
- API Documents reference – full field documentation
Frequently asked questions
- How long is a PDFMonkey download URL valid?
- Each download URL is a temporary signed link valid for 1 hour. After that, it returns a 403 Forbidden error. Fetch the document again via the API to get a fresh URL — no need to regenerate the document.
- Why is the download_url field null?
- The download_url is only populated when the document status is "success". If the document is in draft, pending, generating, or failure status, the field returns null. Make sure you set status to "pending" when creating the document and wait for generation to complete.
- How do I get a new download URL after it expires?
- Fetch the document again via the API (GET /api/v1/documents/:id) or through an integration. Each fetch returns a fresh URL with a new 1-hour window. You never need to regenerate the document itself.