> For the complete documentation index, see [llms.txt](https://ivorypay.gitbook.io/ivorypay-on-off-ramp-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ivorypay.gitbook.io/ivorypay-on-off-ramp-documentation/getting-started/errors.md).

# Error Handling

How to handle errors from the IvoryPay API.

The IvoryPay API uses standard HTTP status codes combined with structured error responses to help you diagnose and handle failures.

## Error response structure

Every error response includes:

```json
{
  "success": false,
  "message": "Human-readable description of what went wrong",
  "statusCode": 400,
  "errorCode": "ONOFFRAMP0033",
  "errors": [],
  "timestamp": "3/26/2026, 12:00:00 PM",
  "path": "/api/v1/onramp",
  "method": "POST"
}
```

{% hint style="info" %}
`timestamp` is produced by `Date.toLocaleString()` on the server and is therefore a **locale-formatted string**, not an ISO 8601 datetime. Do not parse it as ISO 8601 — treat it as opaque human-readable text and use response headers or your own clock for time-sensitive logic.
{% endhint %}

## Common error codes

| Error Code      | Message                                                                            | HTTP Status | Description                                                    |
| --------------- | ---------------------------------------------------------------------------------- | ----------- | -------------------------------------------------------------- |
| `ONOFFRAMP0033` | Invalid bank code. Please provide a valid bank code                                | 400         | The `bankCode` provided does not match any bank                |
| `ONOFFRAMP0087` | Invalid bank id. Please provide a valid bank id                                    | 400         | The bank ID does not exist                                     |
| `ONOFFRAMP0056` | Unable to validate account details provided                                        | 400         | Account lookup failed for the given details                    |
| `ONOFFRAMP0088` | We can't verify this bank account right now. Please try again later.               | 400         | Bank account resolution failed                                 |
| `ONOFFRAMP0053` | Customer not found                                                                 | 404         | No customer exists with the given identifier                   |
| `MANSA0090`     | Bank details not found                                                             | 404         | No saved bank details for this customer                        |
| `MANSA0091`     | This bank account is already saved in your Duffle                                  | 409         | Duplicate bank details for this customer                       |
| `MANSA0092`     | Bank not found for the given currency                                              | 404         | No bank in our directory for that fiat currency                |
| `MANSA0093`     | We couldn't create a new wallet address right now. Please try again soon.          | 503         | Blockchain address provisioning failed — retry later           |
| `ONOFFRAMP0071` | This business does not have support for this fiat currency. Please contact support | 400         | The merchant is not enabled for the requested fiat currency    |
| `ONOFFRAMP0092` | Transaction source already exists                                                  | 409         | The transaction-source record already exists for this merchant |
| `ONOFFRAMP0000` | Internal server error                                                              | 500         | Unexpected error — contact support                             |

For the full list, see [Error Codes Reference](/ivorypay-on-off-ramp-documentation/resources/error-codes.md).

## Handling errors in your integration

### 1. Check the `success` field

Always check the `success` boolean before processing the response:

```javascript
const response = await fetch('https://ramp-api.ivorypay.io/api/v1/onramp', {
  method: 'POST',
  headers: {
    'Authorization': process.env.IVORYPAY_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(payload),
});

const result = await response.json();

if (!result.success) {
  console.error(`Error ${result.errorCode}: ${result.message}`);
  // Handle specific error codes
  switch (result.errorCode) {
    case 'ONOFFRAMP0033':
      // Invalid bank code — prompt user to re-select bank
      break;
    case 'ONOFFRAMP0053':
      // Customer not found — create the customer first
      break;
    default:
      // Log and surface a generic error to your user
      break;
  }
  return;
}

// Process result.data
```

### 2. Handle validation errors

For 400 errors with validation details, iterate over the `errors` array:

```javascript
if (result.statusCode === 400 && result.errors?.length) {
  for (const err of result.errors) {
    console.error(`Field "${err.field}": ${err.message}`);
  }
}
```

### 3. Retry strategy

| Error type       | Should retry? | Strategy                                       |
| ---------------- | ------------- | ---------------------------------------------- |
| 400 Bad Request  | No            | Fix the request payload                        |
| 401 Unauthorized | No            | Check your API key                             |
| 404 Not Found    | No            | Verify the resource ID/reference               |
| 409 Conflict     | No            | The resource already exists                    |
| 500 Server Error | Yes           | Retry with exponential backoff (max 3 retries) |

### 4. Idempotency

Most IvoryPay endpoints that create resources accept a `reference` field. If you send the same `reference` twice, the API returns the existing resource rather than creating a duplicate. Use UUIDs for references to ensure uniqueness.

***

> **For AI assistants:** Error responses always include `errorCode` (string like "ONOFFRAMP0033") and `message`. Use `errorCode` for programmatic handling and `message` for user-facing display.
