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

# Error Handling

> Complete reference of Simiz API error codes, HTTP statuses, and resolution steps.

All Simiz API errors follow a consistent format. This page documents every error code and how to resolve them.

## Error response format

```json
{
  "error": {
    "code": "insufficient_balance",
    "message": "Customer has insufficient balance",
    "type": "payment_error",
    "http_status": 400,
    "request_id": "req_abc123"
  }
}
```

| Field         | Description                     |
| ------------- | ------------------------------- |
| `code`        | Machine-readable error code     |
| `message`     | Human-readable description      |
| `type`        | Error category                  |
| `http_status` | HTTP status code                |
| `request_id`  | Unique request ID for debugging |

## Authentication errors

| Code                       | HTTP | Description                                   | Solution                                          |
| -------------------------- | ---- | --------------------------------------------- | ------------------------------------------------- |
| `invalid_api_key`          | 401  | The API key is invalid or doesn't exist       | Check you're using the correct key (test vs live) |
| `expired_api_key`          | 401  | The API key has expired                       | Regenerate a key from your Dashboard              |
| `insufficient_permissions` | 403  | The key doesn't have the required permissions | Check key permissions or contact support          |

## Payment errors

| Code                    | HTTP | Description                                           | Solution                                   |
| ----------------------- | ---- | ----------------------------------------------------- | ------------------------------------------ |
| `insufficient_balance`  | 400  | Customer's wallet balance is too low                  | Inform customer to top up their wallet     |
| `invalid_phone`         | 400  | Phone number is invalid or doesn't match the provider | Validate the format (e.g., `237XXXXXXXXX`) |
| `transaction_limit`     | 400  | Transaction exceeds daily/monthly limit               | Split the payment or wait for limit reset  |
| `payment_expired`       | 400  | Payment confirmation timeout (15 min)                 | Create a new payment                       |
| `payment_cancelled`     | 400  | Customer cancelled the payment                        | Offer the customer to retry                |
| `duplicate_transaction` | 409  | A transaction with this reference already exists      | Use a unique idempotency key               |

## Validation errors

| Code                     | HTTP | Description                     | Solution                                   |
| ------------------------ | ---- | ------------------------------- | ------------------------------------------ |
| `invalid_amount`         | 400  | Amount is outside allowed range | Ensure amount is between 100 and 5,000,000 |
| `invalid_currency`       | 400  | Currency is not supported       | Use `XAF` or `XOF`                         |
| `missing_required_field` | 400  | A required field is missing     | Check all required fields are included     |
| `invalid_email`          | 400  | Email format is invalid         | Validate email format                      |

## Provider errors

| Code                   | HTTP | Description                                 | Solution                               |
| ---------------------- | ---- | ------------------------------------------- | -------------------------------------- |
| `provider_unavailable` | 503  | Mobile Money provider is down               | Retry after a few minutes              |
| `provider_timeout`     | 504  | Provider didn't respond in time             | Retry the transaction                  |
| `pin_error`            | 400  | Customer entered the wrong PIN              | Customer should retry with correct PIN |
| `account_inactive`     | 400  | Customer's mobile wallet is inactive        | Customer should contact their operator |
| `service_suspended`    | 403  | Provider's service is temporarily suspended | Contact support                        |

## Rate limiting errors

| Code                  | HTTP | Description                         | Solution                                                                         |
| --------------------- | ---- | ----------------------------------- | -------------------------------------------------------------------------------- |
| `rate_limit_exceeded` | 429  | API rate limit exceeded             | Wait and retry with exponential backoff                                          |
| `too_many_requests`   | 429  | Too many requests in a short period | Implement backoff, see [Rate Limiting](/en/core-concepts/security/rate-limiting) |

## Internal errors

| Code                  | HTTP | Description                       | Solution                                         |
| --------------------- | ---- | --------------------------------- | ------------------------------------------------ |
| `internal_error`      | 500  | An internal server error occurred | Retry the request. Contact support if persistent |
| `service_unavailable` | 503  | Simiz is temporarily unavailable  | Retry after a few minutes                        |

## HTTP status codes reference

| Code  | Name                  | Description                   |
| ----- | --------------------- | ----------------------------- |
| `200` | OK                    | Request succeeded             |
| `201` | Created               | Resource created successfully |
| `400` | Bad Request           | Invalid parameters            |
| `401` | Unauthorized          | Authentication required       |
| `403` | Forbidden             | Insufficient permissions      |
| `404` | Not Found             | Resource not found            |
| `409` | Conflict              | Duplicate entry               |
| `429` | Too Many Requests     | Rate limit exceeded           |
| `500` | Internal Server Error | Server error — retry          |
| `503` | Service Unavailable   | Temporarily down              |
| `504` | Gateway Timeout       | Provider timeout              |

## Error handling example

```bash
# Create a payment and handle errors based on HTTP status code
response=$(curl -s -w "\n%{http_code}" -X POST https://api.simiz.io/v1/transactions \
  -H "Authorization: Bearer sk_test_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "currency": "XAF",
    "payment_method": "ORANGE_MONEY",
    "payer": { "phone": "237690000001", "name": "John Doe" },
    "description": "Order #12345"
  }')

http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | head -1)

case $http_code in
  201) echo "Payment created: $body" ;;
  400) echo "Validation error: $body" ;;
  401) echo "Invalid API key" ;;
  429) echo "Rate limited — retry later" ;;
  5*)  echo "Server error — retry" ;;
esac
```

<Tip>
  Include the `request_id` when contacting support — it helps us debug your issue faster.
</Tip>
