---
title: Errors
description: Every status code the render API returns, what causes it, and what to do next.
sidebar:
  label: Errors
  order: 7
---

A failed request returns JSON with a single `error` string:

```json
{ "error": "Provide either html or url" }
```

A successful one returns bytes, so branch on `response.ok` — never on the body's shape.

## Status codes

| Status | Meaning | What to do |
| --- | --- | --- |
| `400` | The body failed validation — a missing source, an unknown field, a value out of range. | Fix the request. Retrying won't help. |
| `401` | The API key is missing, malformed, disabled, or deleted. | Check the `authorization` header and the key's status in the dashboard. |
| `402` | The monthly render limit is used up. | Upgrade the plan, or wait for the next month. See [Plans and limits](/limits). |
| `404` | `templateId` doesn't exist, or belongs to another account. | Copy the ID again from the dashboard's **Templates** tab. |
| `5xx` | The render itself failed — the page didn't settle, the browser errored, or the renderer was unavailable. | Retry with backoff. If it repeats for the same document, the cause is usually in the page. |

## Common causes

**`Provide either html or url`** — `/v1/render` needs one of them. On `/v1/render/template`, neither is accepted; send `templateId` instead.

**`Unrecognized key` on a field you expected to work** — the body is validated strictly, so a typo (`pageFormat` for `pdfFormat`) fails rather than being ignored. Check the field against [Render options](/render-options).

**`HTML payload is too large`** — the document exceeded 5 MB, almost always because of inlined `data:` images. Host them and reference absolute URLs instead.

**`Template not found`** — the ID is wrong, the template was deleted, or the key belongs to a different account than the template.

## When the file renders but looks wrong

An empty, half-drawn, or unstyled document is a page problem, not an API error — the render succeeded, it just captured the page too early or without its assets.

- **Missing styles, fonts, or images** — relative URLs in `html` have no origin to resolve against. Use absolute URLs, or inline the CSS in a `<style>` block.
- **Blank or partial content** — the page draws after load. Raise `waitUntil` to `networkidle` and add `waitForTimeout` in the 300–1000 ms range.
- **Only the top of a long page** — set `fullPage: true` for images; for PDFs, the page grows automatically, so check for a container with a fixed `height` or `overflow: hidden`.
- **PDF missing backgrounds** — `printBackground` defaults to `true`, so a missing background usually comes from `@media print` rules on the page; render with `media: "screen"` to confirm.
- **Blurry images** — raise `deviceScaleFactor` (up to `4`), or `quality` for `jpg` and `webp`.

The dashboard [sandbox](/dashboard#sandbox) is the quickest way to iterate: same renderer, same options, no deploy between attempts.

## Retrying

`4xx` responses are deterministic — the same request fails the same way, so fix it rather than retry it. `5xx` responses are worth retrying with exponential backoff.

Keep in mind that a render that fails after it starts has already counted against your monthly quota, so cap retries at two or three rather than looping.
