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

# Errors & rate limits

> The error envelope, common status codes and rate-limit behaviour.

## Error envelope

Failed requests return `success: false` with a message and HTTP status:

```json theme={null}
{
  "success": false,
  "message": "Invalid API key"
}
```

Validation errors (from a malformed body) include the field-level detail Nest's validation pipe produces.

## Common status codes

| Status                | Meaning                                                                                                    |
| --------------------- | ---------------------------------------------------------------------------------------------------------- |
| `200` / `202` / `204` | Success. `202` = accepted for async processing (transactional sends); `204` = no content (webhook delete). |
| `400`                 | Bad request — validation failed, or a required identity (email/phone) was missing.                         |
| `401`                 | Missing or invalid `X-Sender-Tenant` / `X-API-Key`.                                                        |
| `402`                 | Insufficient SMS credits (transactional SMS / OTP).                                                        |
| `403`                 | Forbidden — feature disabled, or origin not allowed (embedded forms).                                      |
| `404`                 | Not found — e.g. profile lookup by an email that doesn't exist.                                            |
| `409`                 | Conflict — e.g. duplicate on a unique field.                                                               |
| `429`                 | Rate limited.                                                                                              |

## Validation rules

The API whitelists request bodies and **rejects unknown properties**. Send only the documented fields — an unexpected field returns `400`.

## Rate limits

Public endpoints inherit a default of **60 requests per minute** per caller. Tighter limits where noted:

| Surface                         | Limit                                      |
| ------------------------------- | ------------------------------------------ |
| Public API (`/public/*`)        | 60 / min                                   |
| Event ingest (`/events/ingest`) | 60 / min                                   |
| OTP send & verify               | 60 / min (plus 5 sends per phone / 10 min) |
| Embedded form subscribe         | 10 / min                                   |

A rate-limited request returns `429`. Back off and retry with exponential delay.

<Note>
  Transactional sends return **202 Accepted** — the message is queued and
  passes the same pipeline (suppression, consent for marketing, wallet for
  SMS) at the worker. A 202 means accepted for processing, not delivered.
</Note>
