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.