PDFShift API Rate Limits and Request Quotas Explained
Understand PDFShift’s per-minute limits, 429 headers, monthly credits, and parallel conversions, with code to inspect limits and pace requests.
PDFShift publishes three request-rate limits: 2 requests per minute for unauthenticated requests, 250 documents per minute for authenticated requests, and 10 requests per minute in sandbox mode. A rate-limited request returns HTTP 429. The response includes X-RateLimit-Remaining, X-RateLimit-Limit, and X-RateLimit-Reset; reset is a Unix timestamp in seconds. These short-window limits are separate from monthly credits and parallel conversions. PDFShift’s API documentation does not state whether account-specific exceptions apply, so treat the response headers and your current account terms as authoritative.
PDFShift’s published rate limits
| Request context | Published ceiling | What to check |
|---|---|---|
| Unauthenticated | 2 requests per minute | Confirm the API key is actually reaching PDFShift and is valid. |
| Authenticated | 250 documents per minute | The documentation says “documents”; this is not a promise of sustained conversion throughput. |
| Sandbox mode | 10 requests per minute | Sandbox has its own lower rate ceiling. Do not use it to infer production capacity. |
The limits are described by request context, not as a list of separate plan-specific rates. If you are seeing throttling below the documented authenticated ceiling, check authentication, sandbox configuration, and the actual headers returned for your request.
Rate limits, credits, and concurrency are different
These three controls answer different questions. A request can fit within one limit and still be constrained by another.
| Control | What it measures | What happens when reached |
|---|---|---|
| Rate limit | Requests or documents within a short time window | HTTP 429 when rate limited; inspect rate-limit response headers. |
| Monthly credits | Generated output size over the billing month | Account quota behavior depends on the plan and overage configuration. |
| Parallel conversions | Conversions running at the same time | PDFShift says up to 50 can run in parallel by default across plans; parallel work is queued and uses asynchronous responses. |
PDFShift’s credit explanation says one credit covers a generated file up to 5 MB, with larger files consuming additional credits rounded up by 5 MB. Its examples include 4 MB using one credit, 9 MB using two, 14 MB using three, and 23 MB using five. That means one successful conversion may use several monthly credits even though it was one API request. See the credit calculation explanation and the FAQ on credits and parallel conversions.
The FAQ says the default parallel-conversion ceiling is 50 across plans. Parallel requests are queued and return 202 Accepted; a webhook is sent for each converted source. Contact PDFShift about a custom higher concurrency limit. A 202 from this asynchronous flow is acceptance for processing, not proof that the final conversion has completed.
Read the rate-limit headers
On a 429 response, record these headers:
X-RateLimit-Remaining: requests remaining in the current rate window.X-RateLimit-Limit: the limit for the current window.X-RateLimit-Reset: when the window resets, expressed as a Unix timestamp in seconds.
Use the reset timestamp to delay retries. Convert it to a UTC time for logs or operator dashboards, but avoid assuming a fixed window schedule beyond the timestamp in the response. If the remaining count or limit is missing, retain the status, response body, and all headers for diagnosis; do not invent a retry interval.
Runnable examples: inspect a 429 and wait until reset
The following examples make a PDF conversion request and save a successful PDF. Replace the placeholder API key with a secret supplied through your environment in production. The request endpoint and X-API-Key authentication follow PDFShift’s current Help Center guidance. Each example handles 429 by reading the documented headers and waiting until the reported reset time before exiting for an operator or job runner to retry. It does not blindly replay a conversion, which could duplicate work.
cURL
curl -sS -D response-headers.txt \
-o result.pdf \
-w 'HTTP %{http_code}\n' \
-X POST 'https://api.pdfshift.io/v3/convert/pdf' \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{"source":"https://example.com"}'
# If the status is 429, inspect the returned headers:
cat response-headers.txt | grep -i 'X-RateLimit-'
When automating cURL, capture the HTTP status and parse the reset header in the calling script. Do not treat the downloaded body as a PDF unless the response status indicates success.
Python
import os
import time
import requests
from datetime import datetime, timezone
api_key = os.environ["PDFSHIFT_API_KEY"]
response = requests.post(
"https://api.pdfshift.io/v3/convert/pdf",
headers={"X-API-Key": api_key},
json={"source": "https://example.com"},
timeout=120,
)
if response.status_code == 429:
headers = response.headers
remaining = headers.get("X-RateLimit-Remaining")
limit = headers.get("X-RateLimit-Limit")
reset = headers.get("X-RateLimit-Reset")
print(f"Rate limited: remaining={remaining}, limit={limit}, reset={reset}")
if reset and reset.isdigit():
reset_at = int(reset)
wait_seconds = max(0, reset_at - int(time.time()))
print("Reset UTC:", datetime.fromtimestamp(reset_at, timezone.utc).isoformat())
time.sleep(wait_seconds)
raise SystemExit("Retry the job after the reset; request was not replayed.")
response.raise_for_status()
with open("result.pdf", "wb") as output:
output.write(response.content)
print("Saved result.pdf")
Node.js
import { writeFile } from "node:fs/promises";
const apiKey = process.env.PDFSHIFT_API_KEY;
if (!apiKey) throw new Error("Set PDFSHIFT_API_KEY first");
const response = await fetch("https://api.pdfshift.io/v3/convert/pdf", {
method: "POST",
headers: {
"X-API-Key": apiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({ source: "https://example.com" }),
signal: AbortSignal.timeout(120_000),
});
if (response.status === 429) {
const remaining = response.headers.get("X-RateLimit-Remaining");
const limit = response.headers.get("X-RateLimit-Limit");
const reset = response.headers.get("X-RateLimit-Reset");
console.error({ remaining, limit, reset });
if (reset && /^\\d+$/.test(reset)) {
const resetAt = Number(reset);
console.error("Reset UTC:", new Date(resetAt * 1000).toISOString());
await new Promise((resolve) =>
setTimeout(resolve, Math.max(0, resetAt * 1000 - Date.now())),
);
}
throw new Error("Rate limited; retry the job after reset, without replaying it here");
}
if (!response.ok) {
throw new Error(`PDFShift returned HTTP ${response.status}: ${await response.text()}`);
}
await writeFile("result.pdf", Buffer.from(await response.arrayBuffer()));
console.log("Saved result.pdf");
Run the Python example with PDFSHIFT_API_KEY set in the process environment. In Node.js, use a runtime with built-in fetch and AbortSignal.timeout, or substitute equivalents supported by your runtime.
Build a reliable request queue
- Authenticate every production call. PDFShift says unauthenticated requests have a much lower documented rate ceiling. Keep the key server-side, send it in
X-API-Key, and check that deployments do not drop the header. - Set a conservative local rate below the published ceiling. Leave room for bursts, multiple application workers, and any uncertainty about account behavior. The dossier does not establish a guaranteed burst size or window algorithm.
- Coordinate workers centrally. A per-process limiter is insufficient if several processes share one account: their combined traffic may exceed the service limit. Use a shared queue or distributed limiter.
- On 429, pause until the reported reset. Add a small randomized delay after reset when many workers may retry together. Respect the timestamp instead of immediately repeating requests.
- Bound concurrency separately. Keep active conversions within the documented default of 50; use a lower application-specific ceiling when jobs are resource-heavy. For parallel conversion mode, provide a webhook and treat 202 as queued work.
- Track credits separately. Log each conversion’s output size and reconcile monthly credit usage. A large document can consume multiple credits.
- Make retries safe. Store a job identifier and completion state in your own system. Retry only after classifying the failure and checking whether the original job may already have completed.
Monthly quotas, overage, and cost planning
The pricing page currently displays 50 free monthly credits, a 15 MB maximum file size, and a 30-second timeout for the free plan. PDFShift’s FAQ says paid plans default to a 100-second conversion timeout. These are plan details that can change; consult the live pricing page and your account before sizing a production workflow.
The FAQ describes usage notifications at 50%, 80%, and 100% of monthly credit usage. It says overage can be enabled so work can continue past the included quota; the Help Center says overage is disabled by default and can be bounded with a configured cap. Its example of 25,000 included credits, a 27,500-credit cap, and $0.02 per extra credit is an illustration, not a universal rate. Check current account settings and plan terms before enabling overage or forecasting spend. See PDFShift’s overage setup guide.
For cost estimates, calculate generated output size rather than counting only requests: estimate credits as the generated file size divided by 5 MB, rounded up, then sum across conversions. Include larger-than-usual documents and failed or retried jobs in your own monitoring, and confirm how the service counts each outcome with current terms.
Performance and reliability considerations
- Rate capacity is not conversion speed. The authenticated figure is a request ceiling stated in documents per minute. It does not guarantee each conversion completes within a minute or that 250 conversions will complete in that interval.
- Concurrency helps throughput but creates asynchronous work. The published default is 50 simultaneous conversions. Parallel mode queues requests and uses 202 plus webhooks, so your system needs durable job state and webhook handling.
- Use client timeouts that exceed expected work. PDFShift’s listed conversion timeout differs by plan; the client also needs a network timeout. A client timeout does not necessarily prove that the remote conversion stopped.
- Limit output size where possible. Large output files can consume multiple credits and may take longer to transfer and process.
- Measure your own workload. Track status code, elapsed time, output bytes, credit usage, rate headers, retry count, and webhook completion. The dossier provides no independent benchmark or guaranteed throughput figure.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| HTTP 429 | Request rate exceeded for the request context. | Read all three rate-limit headers, wait until X-RateLimit-Reset, then retry through a paced queue. |
| Unexpectedly low allowance | API key is missing, invalid, or not sent as expected; request may be treated as unauthenticated. | Send X-API-Key and verify authentication with current PDFShift guidance. The Help Center explains that missing authentication can fall back to unauthenticated behavior: authentication troubleshooting. |
| 429 while testing | Sandbox mode has a separate ceiling of 10 requests per minute. | Reduce test request frequency and account for sandbox mode when interpreting the limit. |
| HTTP 403 or quota exhaustion | Monthly credits may be exhausted; this is distinct from rate throttling. | Check account usage, generated file sizes, plan quota, and whether overage is enabled and capped. |
| 202 but no PDF in the response | Parallel conversion was accepted asynchronously. | Provide and monitor the configured webhook; process each completion callback rather than expecting the PDF in the immediate response. |
| Conversion times out | Document generation exceeded the configured or plan timeout, or the client deadline elapsed. | Check both client and service timeout settings. The FAQ lists 30 seconds for free and 100 seconds for paid by default; ask PDFShift about eligible adjustments. |
| PDF arrives but credit use is higher than document count | One generated file exceeded a 5 MB credit band. | Compare output size with the rounded-up 5 MB credit calculation and size forecasts accordingly. |
| Repeated 429 after retry | Retry happened before reset or multiple workers retried together. | Use the reset timestamp, coordinate workers with a shared limiter, and add jitter after reset. |
Or skip the browser setup
If your goal is to capture a webpage as an image or PDF rather than tune a PDF conversion queue, ScreenshotNeo is a website screenshot API with a single GET request. Its API and options are documented at ScreenshotNeo docs.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
FAQ
Does a 429 mean I have used all monthly credits?
No. A 429 indicates rate throttling. Check the rate headers. Monthly credits are a separate usage allowance based on generated output size.
Does 250 documents per minute mean 250 conversions will finish each minute?
No. It is the published authenticated request ceiling, not a completion-time or sustained-throughput guarantee.
Can I increase the parallel conversion limit?
PDFShift says the default is 50 concurrent conversions across plans and directs customers who need more to contact support for a custom arrangement.
How should I treat the reset header?
Interpret X-RateLimit-Reset as a Unix timestamp in seconds, wait until that time, and then let a controlled queue retry the job.
Are the free credit amount and overage prices permanent?
No. Plan details and overage terms can change. Confirm them on PDFShift’s current pricing page and in account settings.


