ScreenshotNeo

BlogGuides

CloudConvert API Rate Limits for HTML-to-PDF Jobs

CloudConvert uses dynamic rate limits for job and task creation. Learn how to read 429 headers and submit HTML-to-PDF jobs without unsafe retries.

By the ScreenshotNeo team4 October 20268 min read

Short answer: CloudConvert documents dynamic rate limits for API endpoints that create jobs and tasks. It does not publish a guaranteed universal request quota specifically for HTML-to-PDF jobs in the documentation covered here. When a request reaches a limit, expect HTTP 429 and use that response’s Retry-After header to decide when to send another request. Treat the example values in the docs as examples, not as your account’s quota.

HTML-to-PDF website capture uses CloudConvert’s jobs and tasks API, including the capture-website operation with output_format set to pdf. Rate limiting applies to job and task creation at the API level; the documented material does not establish a separate numeric allowance for this operation. See the API introduction and rate-limiting guidance, the capture-website operation, and the jobs reference.

What CloudConvert’s rate-limit response means

CloudConvert says some endpoints enforce dynamic rate limiting. If you exceed the current limit, the response is HTTP 429 Too Many Requests. The documentation describes these response headers:

Header How to use it
X-RateLimit-Limit The limit value reported for the response. Read the value returned to your client; do not assume a fixed quota across accounts or over time.
X-RateLimit-Remaining The remaining amount reported by the API. Use it as a signal when pacing requests.
Retry-After How many seconds to wait before making another request. Honor the value supplied with the 429 response.

The API introduction includes an example response with X-RateLimit-Limit: 1000 and Retry-After: 60. Those are sample values, not a documented universal 1,000-request allowance or a fixed one-minute retry rule for every account. Build your client around the headers it actually receives.

How HTML-to-PDF job creation fits the limit

A CloudConvert job contains tasks. A website-to-PDF workflow uses the capture-website operation, supplies a URL, and sets output_format to pdf. Creating the job is an API request; processing it and retrieving the resulting file are later stages. Job creation and task creation are the actions CloudConvert names as dynamically rate limited.

The jobs API supports asynchronous creation, which returns after the job is created, and a synchronous route that waits for completion. For long-running work, CloudConvert recommends avoiding a blocked application request. Its quickstart recommends webhooks for completion notifications; polling is another documented workflow option. These choices affect how your application waits for results, but they do not establish different rate-limit quotas.

Runnable request-handling pattern

The following pattern applies to the API request that creates a job. Provide your actual job payload and authentication according to CloudConvert’s API reference. It retries a rate-limited request only after the response’s delay, and does not assume the example value of 60 seconds.

cURL: inspect the 429 response

curl --silent --show-error --include \
  --request POST \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data @job.json \
  "https://api.cloudconvert.com/v2/jobs"

Inspect the status line and the X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After response headers. The request body in job.json should use the job/task structure and operation parameters in CloudConvert’s current jobs reference and capture-website operation.

Python: retry a 429 according to Retry-After

import os
import time
import requests

API_KEY = os.environ["CLOUDCONVERT_API_KEY"]
JOB = {
    "tasks": {
        "capture": {
            "operation": "capture-website",
            "url": "https://example.com",
            "output_format": "pdf"
        }
    }
}

session = requests.Session()
url = "https://api.cloudconvert.com/v2/jobs"
headers = {"Authorization": f"Bearer {API_KEY}"}

while True:
    response = session.post(url, headers=headers, json=JOB, timeout=60)

    if response.status_code == 429:
        retry_after = response.headers.get("Retry-After")
        if retry_after is None:
            raise RuntimeError("CloudConvert returned 429 without Retry-After; inspect the response and account guidance.")
        try:
            wait_seconds = max(0, int(retry_after))
        except ValueError as exc:
            raise RuntimeError(f"Unexpected Retry-After value: {retry_after!r}") from exc
        time.sleep(wait_seconds)
        continue

    response.raise_for_status()
    job = response.json()
    print(job)
    break

This example demonstrates the request-throttling path. In production, bound retries and add application-level scheduling so a sustained stream of requests cannot wait forever. Do not blindly repeat a request after an ambiguous network timeout: the server may have created the job even though the client did not receive the response. Reconcile job state using the API before submitting a duplicate.

Node.js: honor the response delay

const apiKey = process.env.CLOUDCONVERT_API_KEY;
if (!apiKey) throw new Error("Set CLOUDCONVERT_API_KEY");

const jobPayload = {
  tasks: {
    capture: {
      operation: "capture-website",
      url: "https://example.com",
      output_format: "pdf"
    }
  }
};

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

for (;;) {
  const response = await fetch("https://api.cloudconvert.com/v2/jobs", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(jobPayload)
  });

  if (response.status === 429) {
    const retryAfter = response.headers.get("retry-after");
    if (retryAfter === null || !/^\d+$/.test(retryAfter)) {
      throw new Error(`429 response had no usable Retry-After value: ${retryAfter}`);
    }
    await sleep(Number(retryAfter) * 1000);
    continue;
  }

  if (!response.ok) {
    throw new Error(`CloudConvert returned ${response.status}: ${await response.text()}`);
  }

  console.log(await response.json());
  break;
}

Use the payload format from CloudConvert’s operation reference for your actual workflow. The example illustrates the operation and output format relevant to website capture; consult the API docs for any additional task configuration your job requires.

Choose asynchronous completion handling

  1. Create the job asynchronously so your web request or worker does not need to remain open until rendering finishes.
  2. Register a webhook to receive completion notification, following CloudConvert’s webhook guidance. Verify and process incoming events according to the API documentation.
  3. Use polling only when it fits your application. If polling, choose a measured interval and avoid creating a second burst of traffic while jobs are still processing.
  4. Store the job identifier returned at creation so later status checks and result retrieval refer to the original job.

CloudConvert’s quickstart guide recommends webhooks for job completion. Synchronous waiting is available, but its long-running nature can tie up a client or server request.

Retry rules: distinguish 429 from task failure

A 429 means the API request was throttled. Wait for the supplied Retry-After duration before the next request. Do not repeatedly resubmit immediately; that ignores the server’s stated delay and can sustain the burst.

A failed task is a different condition. CloudConvert says it internally retries tasks when failures are retryable and instructs users not to automatically retry tasks. Avoid creating a new job just because a task reports failure. Inspect the job and task status and follow CloudConvert’s failure guidance. The guidance is on the API introduction page.

Rate-limit troubleshooting

Symptom Likely cause What to do
HTTP 429 while creating jobs The current dynamic limit for a job-creation endpoint was reached. Read Retry-After and wait that many seconds. Also record the rate-limit headers so you can tune request pacing.
HTTP 429 while creating tasks Task creation is also among the dynamically limited actions CloudConvert identifies. Honor the response delay and reduce concurrent or bursty task-creation requests.
Your code waits exactly 60 seconds but still gets 429 The client may have hard-coded the documentation’s sample value, or another request used the available capacity meanwhile. Use the Retry-After value from each actual response and pace concurrent workers together.
You assumed the limit is 1,000 The displayed X-RateLimit-Limit: 1000 belongs to an example response; it is not a guaranteed quota for every account. Use your response headers and account-specific information. The reviewed docs give no fixed HTML-to-PDF job allowance.
Jobs appear duplicated after a timeout A network timeout can occur after the API accepted the create request. Check for the original job or reconcile using your stored identifiers before resubmitting. Do not treat every client timeout as proof that creation failed.
A task failure triggers repeated new jobs Task failure handling was confused with API request throttling. CloudConvert internally retries retryable task failures and says not to automatically retry tasks. Inspect task state and follow its documented guidance.
A synchronous request times out in your application The application is waiting for a long-running conversion to finish inline. Prefer asynchronous job creation and a webhook completion flow where practical; the quickstart recommends webhooks.

Performance, reliability, and cost considerations

  • Rate pacing: queue job creation and cap concurrent submitters. Dynamic limits mean a fixed client-side number copied from an example response is not a reliable quota.
  • Backoff: for an explicit 429, the response’s Retry-After is the authoritative delay described in the docs. Avoid synchronized retry storms across workers; coordinate scheduling centrally.
  • Completion: webhooks avoid keeping a request open while rendering proceeds. Polling can add API traffic, so use it deliberately.
  • Duplicate prevention: persist job identifiers and track submission state. A timeout may leave the outcome uncertain, so reconcile before retrying job creation.
  • Task recovery: let CloudConvert’s internal retry behavior handle retryable task failures instead of automatically creating replacement tasks or jobs.
  • Quota planning: the reviewed official docs do not give a fixed account-wide sustained quota or a distinct numerical HTML-to-PDF cap. If your workload needs a committed account-specific limit, consult the headers from your own requests and CloudConvert account-specific materials or support.
  • Cost: this rate-limit documentation does not establish conversion pricing. Check CloudConvert’s current plan and pricing information separately rather than inferring cost from rate-limit headers.

ScreenshotNeo: an alternative for direct website screenshots

If your task is to capture a web page as an image or PDF and you do not need a CloudConvert job workflow, ScreenshotNeo is a website screenshot API and MCP server for developers. A single GET request can return a PNG, JPEG, WebP, or PDF. Its clean-capture steps accept cookie and consent banners like a visitor and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Only clean shots are billed: bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. AI agents can use its MCP tools, including take_screenshot, get_page_info, and capture_pdf.

Or skip the browser setup:

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 documentation. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed; an MCP server lets AI agents take screenshots; and 1,000 screenshots per month are free with no card. Paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card required.

FAQ

What is CloudConvert’s API rate limit?

CloudConvert describes dynamic rate limits for some endpoints that create jobs and tasks. The reviewed documentation does not give a universal fixed quota.

How many CloudConvert HTML-to-PDF jobs can I create?

The documentation reviewed does not publish a separate numeric allowance for HTML-to-PDF job creation. Use the headers in your own API responses and account-specific information.

Why am I getting a 429 Too Many Requests response?

The request reached a dynamic API limit. Wait for the number of seconds in that response’s Retry-After header before sending another request.

Should I retry a failed capture task?

Not automatically. CloudConvert says it internally retries tasks for retryable failures and advises against automatically retrying tasks.

Does using a webhook increase the rate limit?

The documentation presents webhooks as a completion-notification method, not as a different rate-limit tier. They can keep your application from waiting synchronously for long-running work.