render-bolt
Dashboard

Errors

Every error code the API returns, what it means and whether to retry.

Errors are JSON with the HTTP status and a stable code:

{ "error": { "code": "TIMEOUT", "message": "The page took too long to load" } }

Switch on code, not on message: the code is the stable part. Failed requests don't count toward your quota.

Codes#

Status Code What happened What to do
400 INVALID_PARAMETER A parameter has a wrong value. The message names it. Fix the request
400 BLOCKED_URL Private network, localhost, a non-HTTP address, or a redirect to one Use a public address
401 UNAUTHORIZED Missing or invalid key Check the Authorization header
402 QUOTA_EXCEEDED This month's quota is used up Upgrade in the dashboard or wait for the 1st
422 SELECTOR_NOT_FOUND selector or wait_for_selector never appeared Check the selector, or wait longer
422 DNS_FAILED The domain doesn't exist Check the address
422 CONNECTION_FAILED The site didn't accept the connection Check the site is up
422 TLS_FAILED The site's certificate is invalid Fix the certificate on the site
422 NAVIGATION_FAILED The page could not be loaded for another reason Check the address in a browser
429 RATE_LIMITED Too many requests this minute Wait for Retry-After seconds
503 OVERLOADED The queue is full right now Retry after a few seconds
503 BROWSER_CRASHED, BROWSER_UNAVAILABLE The browser failed during your render Retry once
504 TIMEOUT The page didn't finish within timeout Raise timeout, or drop networkidle
504 QUEUE_TIMEOUT Your request waited too long in the queue Retry after a few seconds
500 RENDER_FAILED Something unexpected went wrong Retry once, then tell us

Retrying#

Retry 429, 503 and 504 QUEUE_TIMEOUT with a growing wait, for example 1, 2 and 4 seconds. Don't retry 4xx errors other than 429 without changing the request. The SDKs do this for you.

async function render(body, attempt = 0) {
  const res = await fetch('https://rendersbolt.com/v1/pdf', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  if (res.ok) return Buffer.from(await res.arrayBuffer());
  const { error } = await res.json();
  const retry = res.status === 429 || res.status === 503 || error.code === 'QUEUE_TIMEOUT';
  if (retry && attempt < 3) {
    const wait = Number(res.headers.get('retry-after')) * 1000 || 1000 * 2 ** attempt;
    await new Promise((r) => setTimeout(r, wait));
    return render(body, attempt + 1);
  }
  throw new Error(`${error.code}: ${error.message}`);
}

Stuck? Write to [email protected] with the request you sent and the error code you got back.

Get your free API key

100 renders a month with every feature. No card needed.