<!-- ZenPays documentation · https://docs.zenpayz.com/docs/reference/errors -->

# Errors

Every error the SDK throws extends `ZenPaysError`, so a single `catch` can
narrow with `instanceof`.

## SDK error classes

Generated from `errors/index.ts` and the status mapping in `utils/http.ts`.

| Class | `code` | HTTP | Description |
|---|---|---|---|
| `AuthenticationError` | `AUTHENTICATION_ERROR` | 401 | Thrown when API key authentication fails. Check that your API key is valid and not expired. |
| `AuthorizationError` | `AUTHORIZATION_ERROR` | 403 | Thrown when the authenticated user lacks permission for the requested action. |
| `NotFoundError` | `NOT_FOUND` | 404 | Thrown when the requested resource does not exist. |
| `ValidationError` | `VALIDATION_ERROR` | 400 | Thrown when request parameters fail validation. |
| `RateLimitError` | `RATE_LIMIT_EXCEEDED` | 429 | Thrown when API rate limits are exceeded. Wait for the specified duration before retrying. |
| `NetworkError` | `NETWORK_ERROR` | — | Thrown when a network error occurs (timeout, connection refused, etc.). |
| `PaymentError` | `PAYMENT_ERROR` | 402 | Thrown when a payment operation fails. |
| `ChannelLimitError` | `—` | 422 | Thrown when a payment amount violates configured channel limits (min/max per payment method per currency). The `limits` property contains the configured boundaries and the attempted amount. |
| `ConfigurationError` | `CONFIGURATION_ERROR` | — | Thrown when SDK configuration is invalid. |

```ts
import { RateLimitError, ValidationError, ZenPaysError } from '@zenxdigitalholdings/zenpays'

try {
  await zenpays.payments.createPaymentIntent({ amount: 5000, currency: 'USD' })
}
catch (error) {
  if (error instanceof ValidationError)
    console.error('Bad request:', error.fields)
  else if (error instanceof RateLimitError)
    await sleep((error.retryAfter ?? 1) * 1000)
  else if (error instanceof ZenPaysError)
    console.error(error.code, error.status)
  else throw error
}
```

:::note
`PaymentError`, `ChannelLimitError` and `ConfigurationError` are exported for
`instanceof` narrowing but are not currently thrown by the client itself —
`ConfigurationError` only on a missing API key. They exist so API-supplied
codes can be matched without string comparison.
:::

## Wire-level error codes

The classes above are the SDK's view. The API also returns its own `code`
strings in the response envelope, which overlap the list above on only
`VALIDATION_ERROR`. Those are documented separately under
[REST API errors](/docs/rest-api/errors) — the two lists are deliberately not
merged, because they are different vocabularies.
