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

# Error Handling

> Understand error codes and build resilient integrations

## Error structure

All errors return JSON:

```json theme={null}
{
  "message": "Human-readable description of the error."
}
```

Validation errors include a field-level breakdown:

```json theme={null}
{
  "message": "The given data was invalid.",
  "errors": {
    "bank": ["The bank field is required."],
    "transaction_number": ["The transaction number field is required."]
  }
}
```

## Common errors

### 401 Unauthenticated

```json theme={null}
{ "message": "Unauthenticated." }
```

Your API key is missing, malformed, or revoked. Check that you're sending `Authorization: Bearer chk_xxx`.

### 400 Bad Request

```json theme={null}
{ "message": "Unsupported bank: xyz" }
```

An input value is structurally invalid. Check [supported banks](/api-reference/list-banks) for valid `bank` codes.

### 404 Not Found

```json theme={null}
{ "success": false, "exists": false, "message": "Transaction not found." }
```

The transaction couldn't be confirmed. This is a **business-level** result - the payment may be fake, the wrong reference was entered, or the bank hasn't settled yet.

### 422 Validation Error

The request was well-formed but failed field-level validation. Check `errors` for details.

### 402 Payment Required

```json theme={null}
{ "message": "Monthly verification limit reached. Please upgrade your plan." }
```

Your free quota is exhausted. Upgrade at [check.et/dashboard/billing](https://check.et/dashboard/billing).

### 429 Rate Limited

Slow down requests. Retry after the `Retry-After` response header value (seconds).

### 500 Server Error

Unexpected error on our side. Retry with exponential back-off. If it persists, contact support on [Telegram](https://t.me/Mal_tse).

## Retry strategy

```js theme={null}
async function verifyWithRetry(payload, maxAttempts = 3) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const res = await fetch("https://api.check.et/api/v1/verify", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.CHECK_ET_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(payload),
    })

    if (res.status !== 500 && res.status !== 429) {
      return res.json()
    }

    const delay = Math.min(1000 * 2 ** attempt, 30000)
    await new Promise((r) => setTimeout(r, delay))
  }
  throw new Error("Max retry attempts reached")
}
```
