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

# Errors

> Error response format and HTTP status codes

## Error format

All errors return a JSON body with an `errors` array:

```json theme={null}
{
  "errors": [
    {
      "message": "Domain not verified",
      "field": "from"
    }
  ]
}
```

The `field` property is only present for validation errors and indicates which request field caused the problem.

***

## HTTP status codes

| Code  | Meaning               | When it happens                                                                         |
| ----- | --------------------- | --------------------------------------------------------------------------------------- |
| `200` | OK                    | Successful read or update                                                               |
| `201` | Created               | Resource created                                                                        |
| `202` | Accepted              | Email queued (async operation)                                                          |
| `400` | Bad Request           | Validation error — check the `errors` array                                             |
| `401` | Unauthorized          | Missing or invalid `X-API-Key`                                                          |
| `402` | Payment Required      | Plan quota exceeded (emails, domains, or webhooks)                                      |
| `404` | Not Found             | Resource doesn't exist or belongs to another workspace                                  |
| `409` | Conflict              | Duplicate resource (e.g. domain already registered)                                     |
| `422` | Unprocessable Entity  | Business logic error — domain not verified, recipient suppressed, domain scope mismatch |
| `429` | Too Many Requests     | Rate limit exceeded — back off and retry                                                |
| `500` | Internal Server Error | Something went wrong on our side                                                        |

***

## Rate limiting

Requests are rate-limited per API key. If you exceed the limit you'll receive a `429` response with a `Retry-After` header indicating when you can retry.

```http theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 30
```

***

## Handling errors

```js Node.js theme={null}
const res = await fetch('https://api.torpedo.co.mz/api/v1/emails', {
  method: 'POST',
  headers: { 'X-API-Key': process.env.TORPEDO_API_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    from: 'hello@myapp.com',
    to: '...',
    subject: '...',
    html: '...',
    text: '...',
  }),
})

if (!res.ok) {
  const { errors } = await res.json()
  console.error(errors[0].message)
}
```
