How to Fix DocRaptor PDF Rendering Timeouts
Diagnose DocRaptor PDF timeouts by checking sync and async limits, asset fetches, JavaScript, and concurrency, with runnable API examples.
Start by checking whether your DocRaptor request is synchronous or asynchronous. Synchronous PDF generation has a 60-second limit; asynchronous generation has a 600-second limit. For a document that cannot fit the synchronous window, submit it as an async job, then poll its status or receive a callback. If it still fails, inspect the job’s failure details and narrow down slow assets, JavaScript, or request concurrency. Async gives the job a longer generation window; it does not guarantee that the renderer will finish faster or fix every failure. DocRaptor API reference · API limits.
1. Classify the timeout first
Record the request mode, elapsed time, HTTP response or async status, and exact error text. Keep three different waits separate:
- Generation limit: up to 60 seconds for synchronous creation or 600 seconds for asynchronous creation.
- External-resource wait:
prince_options[http_timeout]controls how long DocRaptor waits for an external resource. Its documented default is 10 seconds; accepted values are 1–60 seconds. - Your client’s network timeout: the timeout configured in your HTTP client may end the caller’s wait before DocRaptor’s generation window ends. The cited DocRaptor documentation does not establish one universal client-side timeout value.
A client giving up does not, by itself, establish that the renderer reached its own generation limit. For async jobs, use the status endpoint or callback to determine what happened after your initial request returned. See the API reference and its limits guide.
2. Move long-running documents to asynchronous generation
Set async to true when a document is too large or complex for the synchronous window. The initial response acknowledges a job and provides a status_id; it is not the PDF. Keep that identifier, then poll the status endpoint or provide a callback_url. The documented job states are queued, working, completed, and failed. Retrieve the document once it is completed. If it fails, inspect validation_errors rather than treating the acknowledgement as the final result. Follow DocRaptor’s current endpoint and authentication details in its async guide.
Runnable Python example: submit and poll
This example uses the documented asynchronous workflow. Set DOCRAPTOR_API_KEY in your environment. Adjust the polling interval to your application’s needs, and preserve the status response for diagnosis.
import os
import time
import requests
API_KEY = os.environ["DOCRAPTOR_API_KEY"]
BASE = "https://api.docraptor.com"
payload = {
"document_content": "<html><body><h1>Monthly report</h1><p>Generated PDF.</p></body></html>",
"name": "monthly-report.pdf",
"document_type": "pdf",
"async": True,
}
# The exact create/status routes and authentication format are documented by
# DocRaptor; keep them aligned with the current async documentation.
created = requests.post(
f"{BASE}/docs",
auth=(API_KEY, ""),
json=payload,
timeout=30,
)
created.raise_for_status()
job = created.json()
status_id = job["status_id"]
while True:
status_response = requests.get(
f"{BASE}/docs/{status_id}",
auth=(API_KEY, ""),
timeout=30,
)
status_response.raise_for_status()
job = status_response.json()
status = job.get("status")
print("status:", status)
if status == "completed":
# Use the document retrieval method/URL returned or documented for
# your DocRaptor API version.
pdf_response = requests.get(
f"{BASE}/docs/{status_id}.pdf",
auth=(API_KEY, ""),
timeout=60,
)
pdf_response.raise_for_status()
with open("monthly-report.pdf", "wb") as pdf_file:
pdf_file.write(pdf_response.content)
break
if status == "failed":
print("validation_errors:", job.get("validation_errors"))
raise RuntimeError("DocRaptor async job failed")
if status not in ("queued", "working"):
raise RuntimeError(f"Unexpected job status: {status!r}")
time.sleep(2)
Endpoint note: DocRaptor’s async workflow and status fields are documented, but route shapes and response fields can vary by API operation. Verify create, status, and retrieval paths against the current official async documentation before deploying this illustrative polling flow.
cURL: submit an async job
Use the documented API route, JSON body, and authentication scheme for your account. This command shows the essential async request fields; the response should be saved so you can read its status_id.
curl -u "$DOCRAPTOR_API_KEY:" \
-H "Content-Type: application/json" \
-d '{"document_content":"<html><body><h1>Report</h1></body></html>","name":"report.pdf","document_type":"pdf","async":true}' \
"https://api.docraptor.com/docs" \
-o job.json
Node.js: submit an async job
const apiKey = process.env.DOCRAPTOR_API_KEY;
const response = await fetch('https://api.docraptor.com/docs', {
method: 'POST',
headers: {
'Authorization': `Basic ${Buffer.from(`${apiKey}:`).toString('base64')}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
document_content: '<html><body><h1>Report</h1></body></html>',
name: 'report.pdf',
document_type: 'pdf',
async: true
}),
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`Create request failed: ${response.status}`);
const job = await response.json();
console.log('status_id:', job.status_id);
console.log('status:', job.status);
These snippets illustrate the flow and should be checked against the current DocRaptor API operation documentation before use; do not assume a guessed status or PDF retrieval route is universal.
3. Reduce work caused by external assets
Stylesheets, images, fonts, and scripts hosted elsewhere require resource requests in addition to PDF layout. DocRaptor notes that documents with many external resources or scripts can take several minutes. For a slow document:
- Inventory every external stylesheet, image, font, and script referenced by the HTML.
- Remove resources that do not appear in the PDF.
- Reduce oversized images and other large files.
- Where appropriate, inline CSS or JavaScript and embed images as data URIs to reduce separate fetches.
- Check that required resources are reachable from the rendering service and do not depend on an interactive login or short-lived URL.
These changes reduce avoidable fetch and processing work; they cannot guarantee a particular render time. DocRaptor’s recommendations are in asset speed optimization.
4. Tune the external-resource timeout only when relevant
prince_options[http_timeout] sets the wait for an individual external resource, not the overall PDF-generation limit. The documented default is 10 seconds, and the supported range is 1–60 seconds. Increase it only when a required resource is slow and evidence points to that fetch; it may allow the resource more time, while also extending the wait. Lower it only when you prefer the job to move past a slow or unavailable resource sooner and the document can tolerate that resource not loading. Changing this value does not extend the 60-second synchronous or 600-second asynchronous generation window. See the API reference.
5. Check JavaScript readiness and errors
JavaScript is disabled by default. If the PDF does not need it, leave it disabled. If page scripts are required, enable JavaScript deliberately, inspect script errors and console messages, and make sure asynchronous work has a finite completion condition. DocRaptor documents docraptorJavaScriptFinished() as a readiness hook: it should return false while required work remains and true when that work is finished. Other return values are errors. An indefinite wait can prevent conversion from progressing. Pipeline settings can affect behavior, so consult the JavaScript guide and API reference.
6. Check concurrency during load spikes
DocRaptor lists 30 simultaneous requests as the default concurrency limit and says it often increases the limit for larger customers. This is separate from each document’s generation-time limit. If timeouts or queued work coincide with a burst of submissions, check the applicable account limit and control how many jobs you submit at once. Do not infer a concurrency limit from an individual document’s elapsed render time. See DocRaptor API limits.
7. Reproduce the slow path and inspect the failure
When the returned details do not identify the cause, compare the failing request with a minimal document, then add content back in groups: external assets, JavaScript, and complex layout. This is a practical isolation technique based on the documented work sources, not a DocRaptor-guaranteed diagnostic procedure. For an async failure, retain and inspect validation_errors. If the result remains unclear, consult DocRaptor’s PDF generation troubleshooting index and support route.
Sync versus async at a glance
| Mode | Generation window | Response and monitoring | Best fit |
|---|---|---|---|
| Synchronous | 60 seconds | Wait for the PDF response | Documents that reliably finish within the sync window |
| Asynchronous | 600 seconds | Receive a job ID, then poll status or use a callback | Longer jobs that need background processing and explicit status handling |
The longer async window changes the integration workflow; it is not a speed setting. Likewise, the external-resource HTTP wait is separate from both overall windows. Sources: API reference, async creation, and API limits.
Common timeout and failure symptoms
| Symptom | Likely distinction to check | Next action |
|---|---|---|
| Caller gets a timeout but no DocRaptor error | Client network timeout may be shorter than the render window | Check async status; adjust the client wait or use async polling |
| Sync request ends around one minute | Synchronous generation limit | Move long work to async and monitor the job |
| Job remains working or fails with asset-related details | External resource fetching or slow document content | Review assets and the per-resource HTTP timeout |
| Document hangs only with scripts enabled | Script error or readiness condition never completes | Check console output and docraptorJavaScriptFinished() |
| Many jobs slow down together | Concurrency or submission burst | Check account concurrency and pace submissions |
| Async job is failed | Failure may include validation details | Inspect validation_errors and troubleshoot the specific payload |
Or skip the browser setup
If the task is to capture a web page as an image rather than render a multi-page PDF document, ScreenshotNeo offers a one-call website screenshot API. It returns PNG, JPEG, WebP, or PDF; for a screenshot, a call can look like this:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
See the ScreenshotNeo API docs for setup and options. It accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say which page verdict and billing result applied. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots. A web-page screenshot is not a substitute for diagnosing or converting a complex report with DocRaptor.
Create a free ScreenshotNeo account for 1,000 screenshots a month, no card required.
FAQ
Does async make DocRaptor render faster?
No. It provides a longer generation window and a background status workflow; it does not inherently speed up the render.
What should I do if an async job fails?
Read its status response and inspect validation_errors, then correlate the details with the request’s assets, scripts, and configuration.
Does increasing http_timeout fix the overall timeout?
No. It changes the wait for an external resource, not the overall generation limit.
Can ScreenshotNeo replace DocRaptor for every PDF?
No. ScreenshotNeo is for capturing web pages or producing a page capture; DocRaptor’s PDF workflow is the relevant one for generated documents that need document-oriented HTML-to-PDF rendering.


