Html2Pdf.app API Rate Limits: Requests per Minute and How to Handle Them
Html2Pdf.app does not publish a numeric requests-per-minute limit. Learn what its plan limits mean, how to handle errors, and how to pace conversions safely.
Direct answer: Html2Pdf.app’s reviewed public API documentation does not state a numeric requests-per-minute (RPM) or requests-per-second (RPS) limit. It also does not document rate-limit headers or a 429 policy. That does not prove there is no hidden throttle; it means the public materials reviewed do not specify one. The published limits are monthly credits, simultaneous conversions, and, on the Free plan, a PDF-size cap. Html2Pdf.app API documentation · pricing page.
If you need an account-specific RPM/RPS threshold, or need to know whether the service returns 429 and which headers accompany it, check your account notices and ask Html2Pdf.app support. Do not infer requests per minute from monthly credits or concurrency.
What the published limits mean
The current pricing page lists these monthly allowances and concurrency figures. They are plan limits, not a published request rate.
| Plan | Price per month | Credits per month | Parallel conversions | PDF size |
|---|---|---|---|---|
| Free | $0 | 100 | 1 | Up to 1 MB |
| Startup | $9 | 1,000 | 3 | Unlimited, as listed |
| Standard | $25 | 5,000 | 10 | Unlimited, as listed |
| Scale | $39 | 10,000 | 20 | Unlimited, as listed |
The vendor says each 5 MB chunk of generated PDF consumes one credit; its example is a 15 MB PDF costing 3 credits. Credits reset on the first day of each month. Check the live pricing page before making purchasing decisions, because prices and plan details can change.
Credits, concurrency, and RPM are different
- Monthly credits constrain the amount of usage available over the monthly cycle, with credit consumption tied to generated PDF size.
- Parallel conversions describe how many conversions can be in progress at once under a plan.
- RPM/RPS would describe how many requests can be sent in a time interval. The reviewed public docs do not publish that number.
A concurrency count does not tell you how quickly a conversion finishes, and a monthly credit balance does not specify how requests may be distributed across a month. Neither gives a defensible RPM calculation.
How to pace requests safely
Since there is no documented numeric rate to target, use bounded concurrency and a queue rather than sending an unbounded burst. This controls load on your own worker and keeps the number of simultaneous conversions within the capacity listed for your plan. It does not guarantee compliance with any unpublished provider throttle.
- Put conversion jobs in a durable queue, so a worker restart does not lose pending work.
- Set the worker’s maximum parallel jobs no higher than the concurrency listed for your plan. For Free, that is one; for Startup, three; Standard, ten; and Scale, twenty.
- Track HTTP status codes and remaining account usage if exposed in your account. Do not assume undocumented rate-limit headers exist.
- On a documented transient server error (500), retry with increasing delays. Add jitter in your own scheduler so simultaneous workers do not all retry at the same instant.
- On 400, 401, or 403, stop automatic retries and correct the input, credentials, or account limit first.
- If the workload is sustained or bursty, ask support for any account-specific RPM/RPS threshold and whether 429 responses or headers are used.
Simple bounded worker example (Python)
This example illustrates a local queue with bounded concurrency and status-aware handling. The documentation describes a synchronous PDF response, but the exact request fields and authentication format must follow your configured Html2Pdf.app integration. Keep credentials in environment variables or a secret manager; never place the API key in browser code or a public repository. This example intentionally does not invent an endpoint, request parameter, or response header.
import asyncio
import random
MAX_IN_FLIGHT = 3 # Set to or below your plan's listed concurrency.
MAX_RETRIES_500 = 4
async def convert(job, client):
"""client.send(job) must perform your documented API request and return a response."""
for attempt in range(MAX_RETRIES_500 + 1):
response = await client.send(job)
status = response.status_code
if status == 200:
# A synchronous success body is PDF data. Persist it before acknowledging the job.
await job.save_pdf(response.content)
return
if status in (400, 401, 403):
# Fix the request, credentials, or account limit; retrying unchanged will not help.
raise RuntimeError(f"Non-retryable response {status}: {response.text}")
if status == 500 and attempt < MAX_RETRIES_500:
delay = min(60, 2 ** attempt) + random.uniform(0, 0.5)
await asyncio.sleep(delay)
continue
# No automatic 429 policy is documented in the reviewed materials.
# Surface it for investigation instead of assuming a reset interval.
raise RuntimeError(f"Conversion failed with HTTP {status}: {response.text}")
async def run(jobs, client):
semaphore = asyncio.Semaphore(MAX_IN_FLIGHT)
async def bounded(job):
async with semaphore:
await convert(job, client)
await asyncio.gather(*(bounded(job) for job in jobs))
Before using the sketch, implement client.send and job.save_pdf for your application and the vendor’s current documented request format. In production, catch per-job exceptions so one failed job does not cancel unrelated queued work; persist retry counts and outcomes.
Understanding errors and choosing a retry policy
| HTTP status or situation | Documented meaning or guidance | What to do |
|---|---|---|
| 200 | Synchronous success returns binary PDF data. | Save the response as a PDF; do not parse it as JSON by default. |
| 202 | A callback job was accepted when using callBackUrl. |
Wait for callback delivery and process it idempotently. |
| 400 | Invalid parameter or inaccessible source URL. | Correct the request or make the source accessible; do not retry unchanged. |
| 401 | Missing or invalid API key. | Check secret injection and credentials, then submit a corrected request. |
| 403 | The documentation says the account has reached a limit included in its current plan. | Check plan details and the notification email; do not retry automatically until the limit is corrected. |
| 500 | Server error. | Retry after a short delay, increasing delays between repeated attempts. Contact support if it persists. |
| 429 | No 429 policy is documented in the reviewed materials. | If received, record the status and response details, reduce concurrency, and ask support what threshold and reset behavior apply. Do not assume undocumented headers or timing. |
| Timeout or lost connection | The client may not know whether the provider completed the conversion. | Use a job identifier or callback workflow if available in your integration; avoid duplicating a potentially completed conversion until you can reconcile its status. |
The status guidance above comes from the official API documentation. Its advice to retry 500 responses is server-error guidance, not evidence of a particular rate limit.
Using callbacks for background work
The API documentation describes a callBackUrl mode: the request can return 202 when the job is accepted, and the completed PDF is delivered to the callback. This is useful when a conversion should run in the background or when a client should not hold an HTTP request open for the entire job. It is not documented as a way to increase RPM or bypass an account limit.
Make callback processing idempotent. The documentation says failed delivery may be retried up to three times, so the same completed job may reach your receiver more than once. Store a durable job key or equivalent identifier, verify that the delivery belongs to an expected job using the mechanism supported by your integration, and acknowledge only after the result is safely recorded. Keep callback endpoints restricted to the extent the vendor workflow permits.
Operational, reliability, and cost considerations
- Protect credentials: Keep the API key on a backend or trusted worker. The vendor explicitly warns against exposing it in browser JavaScript or public repositories.
- Respect account capacity: Cap simultaneous work at the plan’s published parallel conversion count. Increasing concurrency does not establish or raise an RPM allowance.
- Budget by output: Estimate credits from expected PDF size using the vendor’s 5 MB chunk rule, then leave headroom for larger-than-expected files.
- Watch monthly resets: Credits reset on the first day of each month. Track usage so a worker does not keep submitting jobs after the account reaches a plan limit.
- Use bounded retries: Retry only transient failures with a maximum attempt count and delay ceiling. Do not retry 400, 401, or 403 unchanged.
- Make jobs observable: Record timestamps, status, attempt number, job identifier, and output size. Avoid logging API keys or sensitive document contents.
- Plan for uncertain delivery: A client timeout does not by itself establish whether a remote conversion finished. Reconcile state before resubmitting expensive work.
- Ask for the missing rate details: If your service needs a firm throughput guarantee, request the account’s RPM/RPS policy, 429 behavior, relevant response headers, and any burst allowance directly from support.
Or skip the browser setup
If your task is capturing a website as an image rather than generating a PDF, ScreenshotNeo is a website screenshot API and MCP server. It takes a URL in one GET request and returns PNG, JPEG, WebP, or PDF. See the API documentation for the available options and current request details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners and consent prompts, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off.
- Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed. Responses identify the page verdict and billing status in headers.
- An MCP server provides
take_screenshot,get_page_info, andcapture_pdftools for Claude, Cursor, and other MCP clients. - The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
FAQ
How many requests per minute does Html2Pdf.app allow?
The reviewed official documentation does not publish a numeric RPM or RPS limit. Ask support for an account-specific threshold.
Does Html2Pdf.app return 429 Too Many Requests?
The reviewed documentation does not state a 429 policy or describe rate-limit headers. If your client receives 429, save the response details and confirm the meaning and retry interval with support.
Does a higher parallel conversion plan mean more requests per minute?
No such relationship is published. Concurrency is a simultaneous-job allowance; it is not an RPM figure.
Will callback mode avoid rate limits?
Callback mode supports background completion, but the documentation does not say it changes request-rate limits or plan allowances.


