# Handle errors

> Learn how the Bannerify API reports errors and what to do about each error code.

Canonical: https://bannerify.co/docs/api-reference/errors/introduction

When a request fails, the API returns a JSON body with an `error` object in place of the file.

```json
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Invalid api key",
    "docs": "https://bannerify.co/docs/api-reference/errors/code/BAD_REQUEST",
    "requestId": "req:1a2b3c4d5e6f7a8b"
  }
}
```

| Field | Description |
| --- | --- |
| `code` | A stable code for the kind of error. Branch on this field |
| `message` | A sentence that explains what went wrong |
| `docs` | A link to the page for the code |
| `requestId` | The id of the request. The `X-Request-Id` response header carries the same value |

Branch on `error.code`. The HTTP status can surprise you: `USAGE_EXCEEDED` and `RATE_LIMITED` both come with status 500.

## Error codes

| Code | Status | Meaning | Retry |
| --- | --- | --- | --- |
| [`BAD_REQUEST`](https://bannerify.co/docs/api-reference/errors/code/BAD_REQUEST) | 400 | A field is invalid, the API key is unknown, or a signed URL has a wrong signature | No. Fix the request |
| [`FETCH_IMAGE_ERROR`](https://bannerify.co/docs/api-reference/errors/code/FETCH_IMAGE_ERROR) | 400 | Bannerify could not download or read an image | After you fix the image URL |
| [`FORBIDDEN`](https://bannerify.co/docs/api-reference/errors/code/FORBIDDEN) | 403 | The plan of your workspace does not include the feature, such as `s3Config` on the Free or Automate plan | No. Remove the field or change the plan |
| [`NOT_FOUND`](https://bannerify.co/docs/api-reference/errors/code/NOT_FOUND) | 404 | The template does not exist | No. Fix the template id |
| [`USAGE_EXCEEDED`](https://bannerify.co/docs/api-reference/errors/code/USAGE_EXCEEDED) | 500 | Your workspace reached its daily or monthly generation limit | After the limit resets, or after you upgrade |
| [`RATE_LIMITED`](https://bannerify.co/docs/api-reference/errors/code/RATE_LIMITED) | 500 | The API key sent too many `createImage` or signed URL requests | After the reset time in the message |
| [`TOO_MANY_REQUESTS`](https://bannerify.co/docs/api-reference/errors/code/TOO_MANY_REQUESTS) | 400 | The API key sent too many PDF or stored file requests | After the reset time in the message |
| [`INTERNAL_SERVER_ERROR`](https://bannerify.co/docs/api-reference/errors/code/INTERNAL_SERVER_ERROR) | 500 | Something failed during the request | Yes, a few times with a short delay |

A failed render does not count toward your quota.

The API has no `UNAUTHORIZED` code. An unknown API key returns `BAD_REQUEST`.

## Common problems

| Problem | What to do |
| --- | --- |
| The request fails with `INTERNAL_SERVER_ERROR` and no render error | Send the `Content-Type: application/json` header with a valid JSON body. A missing header, malformed JSON, or an empty body fails with this code |
| A value in a `modifications` entry does not change | A layer name that does not exist is ignored without an error. Check the spelling in [Modifications](https://bannerify.co/docs/essentials/modifications#name-your-layers) |
| `format` fails validation | Use `png`, `jpeg`, or `webp` in lowercase. `jpg`, `JPEG`, and `svg` are not valid |
| A large template takes long to render | The API renders while the request waits. Raise the timeout of your HTTP client. The SDKs wait 60 seconds by default |
| An image from a `src` URL fails | Use a smaller file on a fast host, and see [`FETCH_IMAGE_ERROR`](https://bannerify.co/docs/api-reference/errors/code/FETCH_IMAGE_ERROR) |
| JPEG or WebP output looks soft | Raise `quality`. The default is 90, and `png` ignores it |
| Repeat requests hit a limit | Save the result and reuse it, or use a [signed URL](https://bannerify.co/docs/essentials/signed-urls), which the cache can serve for up to 7 days |

## Get help

If you cannot find the cause, write to [an@bannerify.co](mailto:an@bannerify.co) or ask on [Discord](https://bannerify.co/discord). Include the full error response, and the `requestId` in particular.

## Related

- [Previous: Authenticate requests](https://bannerify.co/docs/api-reference/authentication)
- [Next: BAD_REQUEST](https://bannerify.co/docs/api-reference/errors/code/BAD_REQUEST)
- [Documentation index](https://bannerify.co/docs/llms.txt)
