> ## Documentation Index
> Fetch the complete documentation index at: https://pdfbase.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error types, codes, and how to handle them.

## Error format

PDFBase uses conventional HTTP status codes and returns errors as JSON with a consistent structure.

```json theme={null}
{
  "error": {
    "type": "invalid_request",
    "code": "html_too_large",
    "message": "HTML body exceeds the 5MB limit. Current size: 7.2MB.",
    "param": "html",
    "doc_url": "https://docs.pdfbase.dev/errors#html_too_large"
  }
}
```

| Field     | Type           | Description                                         |
| --------- | -------------- | --------------------------------------------------- |
| `type`    | string         | Error category. Always present.                     |
| `code`    | string         | Machine-readable error code. Always present.        |
| `message` | string         | Human-readable explanation. Always present.         |
| `param`   | string \| null | The parameter that caused the error, if applicable. |
| `doc_url` | string         | Link to documentation for this specific error.      |

## HTTP status codes

| Status | Meaning                                                                            |
| ------ | ---------------------------------------------------------------------------------- |
| `200`  | Success                                                                            |
| `201`  | Created                                                                            |
| `400`  | Bad request — invalid parameters                                                   |
| `401`  | Unauthorized — missing or invalid API key                                          |
| `403`  | Forbidden — key lacks required scope or IP not allowed                             |
| `404`  | Not found — resource doesn't exist or has expired                                  |
| `402`  | Payment required — credit balance is 0                                             |
| `409`  | Conflict — idempotency key reuse with different parameters                         |
| `413`  | Payload too large — HTML or file exceeds size limit                                |
| `422`  | Unprocessable — valid JSON but semantically wrong (e.g., template schema mismatch) |
| `429`  | Rate limited — too many requests                                                   |
| `500`  | Internal error — our fault, not yours                                              |
| `503`  | Service unavailable — temporary capacity issue                                     |

## Error types

### `invalid_request`

The request was malformed or missing required fields.

```json theme={null}
{
  "error": {
    "type": "invalid_request",
    "code": "missing_required_field",
    "message": "The 'html' or 'url' field is required when creating a PDF.",
    "param": "html"
  }
}
```

### `authentication_error`

API key is missing, invalid, revoked, or expired.

```json theme={null}
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The API key provided is not valid. Check that you're using the correct key for this environment.",
    "param": null
  }
}
```

### `permission_error`

The API key is valid but doesn't have the required scope, or the request IP isn't allowed.

```json theme={null}
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This key requires the 'templates:write' scope to create templates.",
    "param": null
  }
}
```

### `not_found`

The requested resource doesn't exist or has expired (files expire after 24h by default).

```json theme={null}
{
  "error": {
    "type": "not_found",
    "code": "resource_expired",
    "message": "PDF 'pdf_x7Kf9m' has expired. Files are deleted 24 hours after creation.",
    "param": null
  }
}
```

### `rate_limit_error`

You've exceeded your plan's rate limit. See [Rate Limits](/docs/rate-limits) for details.

```json theme={null}
{
  "error": {
    "type": "rate_limit_error",
    "code": "too_many_requests",
    "message": "Rate limit exceeded. Retry after 2 seconds.",
    "param": null
  }
}
```

### `rendering_error`

The PDF was generated but something went wrong during rendering. The response still includes the PDF, but the `warnings` field flags issues.

```json theme={null}
{
  "id": "pdf_abc123",
  "object": "pdf",
  "status": "completed_with_warnings",
  "url": "https://files.pdfbase.dev/pdf_abc123.pdf?token=sig_xyz",
  "warnings": [
    {
      "code": "resource_load_failed",
      "message": "Failed to load https://cdn.example.com/logo.png — used fallback.",
      "resource": "https://cdn.example.com/logo.png"
    }
  ]
}
```

<Tip>
  Enable `debug: true` on the request to get a full screenshot, console log, and failed resource list alongside the PDF. See the [Debug Mode guide](/docs/guides/debug-mode).
</Tip>

### `payment_required`

Your credit balance is 0. Purchase more credits to continue making API calls that consume credits. Read-only operations (GET endpoints) still work.

```json theme={null}
{
  "error": {
    "type": "payment_required",
    "code": "insufficient_credits",
    "message": "Your credit balance is 0. Purchase more credits at https://app.pdfbase.dev/billing",
    "param": null,
    "credits_remaining": 0
  }
}
```

<Tip>
  Set up [auto-refill](/docs/pricing#auto-refill) to prevent service interruptions. PDFBase will automatically purchase credits when your balance drops below your configured threshold.
</Tip>

### `idempotency_error`

You reused an idempotency key with different parameters than the original request.

```json theme={null}
{
  "error": {
    "type": "idempotency_error",
    "code": "idempotency_key_conflict",
    "message": "Idempotency key 'order-123-pdf' was already used with different parameters.",
    "param": null
  }
}
```

### `internal_error`

Something went wrong on our end. These are automatically reported and investigated. Retry with exponential backoff.

```json theme={null}
{
  "error": {
    "type": "internal_error",
    "code": "rendering_crashed",
    "message": "The rendering engine encountered an unexpected error. This has been logged. Please retry.",
    "param": null
  }
}
```

## Retry strategy

For `429` and `5xx` errors, retry with exponential backoff:

```typescript theme={null}
// The SDK handles this automatically
const pdfbase = new PDFBase({
  apiKey: 'pk_live_xxx',
  maxRetries: 3,        // default: 3
  timeout: 30_000,      // default: 30s
})
```

| Attempt   | Delay          |
| --------- | -------------- |
| 1st retry | 500ms + jitter |
| 2nd retry | 1s + jitter    |
| 3rd retry | 2s + jitter    |

The `Retry-After` header on `429` responses tells you exactly how long to wait. Always respect it.

## Billing for errors

**You are never charged for failed requests.** Only successful PDF generations (status `completed` or `completed_with_warnings`) count as credits.
