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

# Errors

> How Pulsewave reports failures

Pulsewave uses conventional HTTP response codes: `2xx` for success, `4xx` for an error caused by the request, and `5xx` for an error on our end.

## Error shape

Every error response has the same shape:

```json theme={null}
{
  "error": {
    "type": "validation_error",
    "code": "missing_required_field",
    "message": "The 'to' field is required for channel 'email'",
    "param": "to"
  }
}
```

| Field     | Description                                                                     |
| --------- | ------------------------------------------------------------------------------- |
| `type`    | Broad category of error. Useful for `switch` statements in your error handling. |
| `code`    | Specific machine-readable reason. Stable across API versions.                   |
| `message` | Human-readable description. Don't parse this — use `code` instead.              |
| `param`   | The request field that caused the error, if applicable, otherwise `null`.       |

## HTTP status codes

| Status                | Meaning                                                                                               |
| --------------------- | ----------------------------------------------------------------------------------------------------- |
| `200` / `201` / `202` | Success                                                                                               |
| `400`                 | The request was malformed (invalid JSON, wrong types)                                                 |
| `401`                 | Missing or invalid API key                                                                            |
| `404`                 | The resource doesn't exist, or doesn't belong to your account                                         |
| `409`                 | The request conflicts with the resource's current state (e.g. cancelling a message that already sent) |
| `422`                 | The request was well-formed but failed validation                                                     |
| `429`                 | You've exceeded a [rate limit](/rate-limits)                                                          |
| `500` / `503`         | Something went wrong on our end. Safe to retry.                                                       |

## Error types

| Type                   | Typical status | Meaning                                      |
| ---------------------- | -------------- | -------------------------------------------- |
| `invalid_request`      | 400            | The request couldn't be parsed               |
| `authentication_error` | 401            | The API key is missing, invalid, or revoked  |
| `not_found`            | 404            | The resource doesn't exist                   |
| `validation_error`     | 422            | A field failed validation — check `param`    |
| `rate_limit_error`     | 429            | Too many requests — see `Retry-After` header |
| `api_error`            | 500            | An unexpected error on Pulsewave's side      |

## Handling errors

```javascript theme={null}
try {
  await pulsewave.messages.send({ channel: 'email', to, from, subject, html });
} catch (err) {
  if (err.type === 'validation_error' && err.param === 'to') {
    // show a field-level error in your UI
  } else if (err.type === 'rate_limit_error') {
    // back off and retry, see Rate limits
  } else {
    throw err;
  }
}
```

<Tip>
  `5xx` responses and network errors are safe to retry. Pulsewave's official SDKs retry these automatically with exponential backoff.
</Tip>
