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

# Error Handling

> How to handle API errors.

# Error Handling

All Wava API errors return a consistent JSON structure:

```json theme={null}
{
  "code": 4001,
  "api_code": "PAYMENT_GATEWAY_REQUIRED",
  "message": "Payment gateway is required",
  "description": "A payment gateway must be specified",
  "error": true
}
```

## Error fields

| Field               | Description                                           |
| ------------------- | ----------------------------------------------------- |
| `code`              | Numeric error code                                    |
| `api_code`          | Machine-readable error identifier                     |
| `message`           | Short human-readable message                          |
| `description`       | Detailed explanation                                  |
| `error`             | Always `true` for error responses                     |
| `gateway_name`      | Present for gateway-specific errors (6000+)           |
| `validation_errors` | Array of field-level errors (for validation failures) |

## Validation error example

When validation fails (code `2000` or `4005`), the response includes an array of field-specific errors:

```json theme={null}
{
  "code": 2000,
  "api_code": "VALIDATION_FAILED",
  "message": "Validation failed",
  "description": "One or more fields failed validation",
  "error": true,
  "validation_errors": [
    {
      "field": "shopper.email",
      "message": "Invalid email format",
      "value": "not-an-email"
    },
    {
      "field": "amount",
      "message": "Amount is required",
      "value": null
    }
  ]
}
```

## Gateway error example

When a payment gateway returns an error, the response includes the gateway name:

```json theme={null}
{
  "code": 6105,
  "api_code": "DAVIPLATA_OTP_ERROR",
  "message": "Invalid or expired OTP",
  "description": "The OTP code provided is invalid or has expired",
  "error": true,
  "gateway_name": "daviplata"
}
```

## HTTP status codes

| Status | Meaning                                       |
| ------ | --------------------------------------------- |
| `200`  | Success                                       |
| `202`  | Accepted (refund processing)                  |
| `400`  | Bad request / Validation error                |
| `401`  | Unauthorized (invalid or missing credentials) |
| `404`  | Resource not found                            |
| `422`  | Unprocessable (e.g., refund window expired)   |
| `429`  | Rate limit exceeded                           |
| `500`  | Server error                                  |
| `503`  | Service temporarily unavailable               |

## Best practices

* Always check the HTTP status code first.
* Use `api_code` for programmatic error handling (not `message`, which may change or be localized).
* For `400` errors, check the `validation_errors` array for field-specific issues.
* For `500` and `503` errors, retry with exponential backoff.
* For gateway errors (6000+), check `gateway_name` to determine which gateway returned the error and handle accordingly.
