---
title: Errors
slug: errors
description: What each status code means and which failures are worth retrying.
order: 3
updatedAt: '2026-08-14'
---

Every error uses the same shape:

```json
{ "ok": false, "error": "\"to\" is required" }
```

## Status codes

| Code | Meaning | What to do |
|---|---|---|
| `400` | The body is not valid JSON, `id` or `to` is missing, or an attachment is malformed. | Fix the request. Retrying will not help. |
| `401` | The API key is missing, invalid or revoked. | Check the `x-api-key` header and the state of the key in the dashboard. |
| `404` | No template with that id in the project that owns the key. | Check the id, and that the key belongs to the same project as the template. |
| `429` | The monthly send limit of your plan is spent. | Wait for the period to reset or move to a larger plan. Queue the message on your side instead of dropping it. |
| `500` | Unexpected error in SentFast. | Retry with backoff and get in touch if it does not clear. |
| `502` | The delivery provider rejected the message. | Retry with backoff. If it persists, check the sending configuration of the workspace. |
| `503` | The API is disabled. | Nothing on your side: sending is switched off globally. Retry later. |

## What to retry

Retry `502`, `503` and `500` with exponential backoff — they are transient by
nature. Do not retry `400`, `401` or `404`: the request will fail identically
until you change it.

`429` deserves its own handling. It means the month's volume is spent, not that
something is broken, so a retry loop will only burn requests. Hold the message
in your own queue and send it when the period resets.

## Failures are logged

A send that reaches the platform and then fails still leaves a record: the
recipient, the timestamp, the status and the reason it failed. That is what to
read when a customer says an email never arrived — before assuming it was never
sent.
