ScreenshotNeo

BlogHow-to

HTMLCSStoImage Rate Limit Exceeded: How to Handle API Errors

Diagnose HTMLCSStoImage 429 responses, distinguish request throttling from exhausted image credits, and recover safely with cURL, Python, or Node.js.

By the ScreenshotNeo team4 October 20269 min read

A 429 response from HTML/CSS to Image can mean either that a management-operation group has reached its request quota or that image credits for the plan are exhausted. Read the response body before retrying: a management throttle calls for waiting and pacing requests; an image-credit error calls for checking usage, billing-period settings, or plan allowance. A one-minute wait does not restore exhausted image credits.

HTML/CSS to Image documents no per-second or per-minute rate limit for image generation itself. Image creation consumes plan image credits. Its REST management operations have separate per-minute read and write quotas. See the provider’s rate limits and usage limits guide.

1. Identify which limit you reached

What the request did Likely limit What to look for Recovery
Listed, fetched, created, updated, or deleted a management resource Management request throttle A rate-limit message or operation-group details; REST headers may include RateLimit-Policy, RateLimit, and Retry-After Honor Retry-After. If it is absent, wait 60 seconds, then pace requests.
Created an image Image-credit exhaustion A plan-limit message with used and allowed image-credit totals Check billing-period usage and overage settings, or review a plan with a larger allowance.
Called a management tool through MCP Management request throttle Explanatory tool error text; it may not arrive as an HTTP 429 or include REST rate-limit headers Wait 60 seconds before retrying, then reduce bursts.

Management quotas are documented as 100 reads per minute and 20 writes per minute for each listed resource family and organization. Read and write groups are separate, and each resource family has its own groups. Listing and getting operations count as reads; creating, updating, and deleting count as writes. These are sliding 60-second windows. API keys and MCP connections for the same organization share the relevant allowance across REST and MCP. The documented figures apply to management operations, not image-generation request rate. Check the current provider documentation for the applicable group and quota.

2. Inspect a REST response before retrying

Capture the status, response headers, and body. Do not assume every 429 has the same cause. This cURL example makes one request and prints the headers and body for inspection; replace the endpoint and authentication values with the exact management endpoint and credentials used by your integration.

curl -sS -D response-headers.txt -o response-body.txt \
  -w 'HTTP status: %{http_code}\n' \
  -u 'YOUR_API_ID:YOUR_API_KEY' \
  'YOUR_HTMLCSSTOIMAGE_MANAGEMENT_ENDPOINT'

cat response-headers.txt
cat response-body.txt

For an image-creation request, inspect the same response body for a plan-limit message and credit totals. The provider documents an image endpoint 429 example that reports “Plan limit exceeded” and includes used and allowed image-credit totals. That points to account allowance rather than a short request cooldown. The official rate-limit guide shows the documented response cases.

3. Handle management throttles in code

For a REST management throttle, wait for the number of seconds in Retry-After when the header is present. If it is absent, the provider advises waiting 60 seconds. Do not immediately replay the rejected request. Once the window has passed, spread requests out; if several workers share an organization, add a small random delay so they do not all retry together.

cURL: inspect a rejected request

cURL is useful for a single diagnostic request. This example writes the response headers and body to files so you can see the provider’s error details and any retry hint.

curl -sS -D headers.txt -o body.txt \
  -w 'HTTP status: %{http_code}\n' \
  -u 'YOUR_API_ID:YOUR_API_KEY' \
  'YOUR_HTMLCSSTOIMAGE_MANAGEMENT_ENDPOINT'

cat headers.txt
cat body.txt

Python: retry a management read once after the advised wait

Set the endpoint to the specific HTML/CSS to Image management resource you need. This example retries only a 429, uses Retry-After when available, and otherwise waits 60 seconds. It deliberately does not automatically retry image-credit exhaustion.

import time
import requests

API_ID = "YOUR_API_ID"
API_KEY = "YOUR_API_KEY"
ENDPOINT = "YOUR_HTMLCSSTOIMAGE_MANAGEMENT_ENDPOINT"


def get_management_resource():
    response = requests.get(ENDPOINT, auth=(API_ID, API_KEY), timeout=30)

    if response.status_code != 429:
        response.raise_for_status()
        return response

    print("First 429 response:", response.text)
    retry_after = response.headers.get("Retry-After")
    try:
        wait_seconds = max(0, int(retry_after)) if retry_after else 60
    except ValueError:
        wait_seconds = 60

    time.sleep(wait_seconds)
    retry = requests.get(ENDPOINT, auth=(API_ID, API_KEY), timeout=30)
    retry.raise_for_status()
    return retry


result = get_management_resource()
print(result.status_code)
print(result.text)

Node.js: wait on a management 429

Use a supported Node.js runtime with the built-in fetch. The endpoint and credentials should be supplied through your deployment’s secret configuration, not committed to source control.

const endpoint = process.env.HTMLCSSTOIMAGE_MANAGEMENT_URL;
const apiId = process.env.HTMLCSSTOIMAGE_API_ID;
const apiKey = process.env.HTMLCSSTOIMAGE_API_KEY;

if (!endpoint || !apiId || !apiKey) {
  throw new Error('Set the management URL, API ID, and API key');
}

const auth = Buffer.from(`${apiId}:${apiKey}`).toString('base64');

async function getManagementResource() {
  let response = await fetch(endpoint, {
    headers: { Authorization: `Basic ${auth}` },
    signal: AbortSignal.timeout(30_000),
  });

  if (response.status !== 429) {
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${await response.text()}`);
    }
    return response;
  }

  const errorBody = await response.text();
  console.error('First 429 response:', errorBody);
  const retryHeader = response.headers.get('retry-after');
  const seconds = retryHeader && Number.isFinite(Number(retryHeader))
    ? Math.max(0, Number(retryHeader))
    : 60;
  await new Promise(resolve => setTimeout(resolve, seconds * 1000));

  response = await fetch(endpoint, {
    headers: { Authorization: `Basic ${auth}` },
    signal: AbortSignal.timeout(30_000),
  });
  if (!response.ok) {
    throw new Error(`Retry failed with HTTP ${response.status}: ${await response.text()}`);
  }
  return response;
}

const result = await getManagementResource();
console.log(await result.text());

4. Handle exhausted image credits

When the response identifies exhausted image credits, stop retrying the same image request. Repeated attempts do not replenish the billing-period allowance. Instead:

  1. Read the error body and note the reported used and allowed credit totals.
  2. Check image usage for the current billing period in the account dashboard.
  3. Review billing and overage settings to understand whether additional usage is allowed.
  4. If your usage needs exceed the plan allowance, compare plans with a larger image allowance.
  5. Where it fits the workflow, use the API’s batch creation support within its documented batch limit. Batching can reduce request overhead, but it does not remove image-credit limits.

See the HTML/CSS to Image API guide for API usage and batch creation details.

5. Coordinate workers and avoid retry storms

Because an organization’s API keys and MCP connections share management allowances, independent services can collectively exhaust the same operation group. A retry loop in each worker can make the burst worse. Use these practices:

  • Track the operation group and organization associated with each management call.
  • Honor the server’s Retry-After value rather than retrying immediately.
  • If no retry header is supplied, wait 60 seconds as the provider advises.
  • After the rejected call, spread work across time instead of releasing a queued burst all at once.
  • Add a small randomized delay to retries when multiple workers share credentials.
  • Keep image generation and management operations distinct in monitoring: one consumes image credits, while the other is subject to management read/write groups.

Batching may help reduce call overhead for supported image creation workflows, but it does not increase the plan’s image-credit allowance. Avoid adding automatic retries for every error status: a 401 or 403, for example, points to credentials, permissions, or plan requirements rather than a rate limit.

6. Check nearby authentication and permission failures

Not every failed API call is a rate limit. HTML/CSS to Image documents HTTP Basic authentication, with the API ID as the username and API key as the password. Its API-key troubleshooting guide identifies 401 responses for credential or enabled-key problems, and 403 for missing permission or plan requirements. Confirm that the key is enabled, the organization owns the resource, and the key has the needed permissions. Keep keys secret and do not include them in support requests. See the API keys and troubleshooting guide.

7. Troubleshooting checklist

Symptom Likely cause Fix
429 on a listing or retrieval call with rate-limit details The organization’s read group reached its sliding 60-second quota. Honor Retry-After; if absent, wait 60 seconds. Then space out reads.
429 on a create, update, or delete call The organization’s write group reached its quota. Wait as instructed, then pace writes. Check whether other workers or MCP clients share the organization allowance.
429 body says “Plan limit exceeded” and includes credit totals Image credits are exhausted for the plan period. Check usage and billing/overage settings or review plan allowance. Do not use a one-minute retry loop.
MCP tool reports a rate-limit error without HTTP headers A shared management group may be exhausted. Use the tool’s error text, wait 60 seconds, then retry with reduced concurrency.
401 response Wrong, disabled, or incorrectly supplied API credentials. Verify the API ID and key, Basic authentication format, and key status.
403 response The key lacks permission or the plan does not allow the requested operation. Check the resource-owning organization, key permissions, and plan requirements.
429 recurs immediately after a retry Retry was too early, another worker is consuming the shared group, or the request is an image-credit failure. Re-read the response body and headers; coordinate workers and apply the recovery path for the identified limit.

If the limit type remains unclear, send support the relevant image or template IDs and request references. Never send API keys, passwords, or other secrets. The provider’s official FAQ also answers whether limits apply and what happens when plan limits are reached.

8. Or skip the browser setup

If you need screenshots of web pages rather than HTML/CSS template rendering, ScreenshotNeo provides a website screenshot API. It is a one-call alternative for capturing a URL as an image or PDF. The request below returns an image response; see the ScreenshotNeo API documentation for options and response details.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

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)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for 1,000 free screenshots a month, with no card required.

9. Performance, reliability, and cost notes

  • Management performance: A 429 is a signal to reduce request bursts, not to retry faster. Respect the retry hint and keep workers from synchronizing their retries.
  • Image-generation cost: Image creation draws on plan image credits. A plan-limit 429 requires reviewing usage or allowance, not waiting for a short throttle window.
  • Batching: Use documented batch creation when it suits the workload and stays within its batch limit. It can reduce request overhead but does not bypass credit accounting.
  • Operational safety: Log status, response body, relevant rate-limit headers, operation type, and request reference. Redact credentials and sensitive page data.
  • Retry boundaries: Retry only errors with a defined recovery action. A management throttle can recover after the specified wait; exhausted image credits need an account or billing change.

10. FAQ

Does HTML/CSS to Image rate-limit image creation per minute?

The current provider documentation says image generation has no per-second or per-minute rate limit. It consumes plan image credits instead.

Does an image-credit 429 clear after 60 seconds?

No. The 60-second advice applies to management throttling when Retry-After is absent and to MCP management errors. An exhausted image-credit allowance requires checking usage, billing settings, or plan capacity.

Can REST and MCP calls use separate management quotas?

No. The provider says API keys and MCP connections for an organization share the relevant management operation-group allowance.

Should I contact support if I cannot tell which limit was reached?

Yes. Include relevant image or template IDs and request references, and remove credentials and secrets from the report.