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

# Dubu Pay API error codes and responses

> Understand the Dubu Pay error response format, every HTTP status code the API returns, common error codes, and how to resolve the most frequent problems.

When a request cannot be completed, the Dubu Pay API always returns a structured JSON body alongside an appropriate HTTP status code. This consistent format means you can write a single error-handling function in your integration and handle every failure case in the same way.

## Error response format

Every error response follows this envelope:

```json theme={null}
{
  "success": false,
  "message": "Human-readable description of the error",
  "errors": [
    {
      "field": "email",
      "message": "Invalid email address"
    }
  ]
}
```

<ResponseField name="success" type="boolean">
  Always `false` for error responses.
</ResponseField>

<ResponseField name="message" type="string">
  A short, human-readable summary of what went wrong. Safe to display to end users for most error types.
</ResponseField>

<ResponseField name="errors" type="array">
  Present on validation errors (HTTP 400). Each element describes one invalid field.

  <Expandable title="errors[]">
    <ResponseField name="field" type="string">
      The name of the request field that failed validation (e.g. `"email"`, `"password"`).
    </ResponseField>

    <ResponseField name="message" type="string">
      A description of why the field failed (e.g. `"Invalid email address"`).
    </ResponseField>
  </Expandable>
</ResponseField>

## HTTP status codes

| Status                      | Meaning                | When you'll see it                                                                                                                       |
| --------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `400 Bad Request`           | Validation error       | One or more request fields failed schema validation. Check the `errors` array for field-level details.                                   |
| `401 Unauthorized`          | Authentication failure | No credentials were provided, the access token has expired, or the credentials are invalid.                                              |
| `403 Forbidden`             | Authorization failure  | You are authenticated but do not have permission for the requested action (e.g. your IP is not whitelisted).                             |
| `404 Not Found`             | Resource missing       | The requested resource does not exist or has been deleted.                                                                               |
| `409 Conflict`              | Duplicate resource     | You attempted to create a resource that already exists — most commonly registering with an email that is already in use.                 |
| `422 Unprocessable Entity`  | Business logic error   | The request was well-formed but could not be completed due to a business rule (e.g. trying to verify an email that is already verified). |
| `429 Too Many Requests`     | Rate limit exceeded    | You have sent too many requests in a short period. Wait for the number of seconds in the `Retry-After` response header before retrying.  |
| `500 Internal Server Error` | Server error           | Something unexpected went wrong on our side. If this persists, contact support.                                                          |

## Error codes

The `message` field on each error response often corresponds to a machine-readable error code. Use these to branch your error-handling logic:

| Code                    | Status | Description                                                                           | Resolution                                                                        |
| ----------------------- | ------ | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `EMAIL_IN_USE`          | 409    | The email address is already registered.                                              | Use a different email or direct the user to log in.                               |
| `INVALID_CREDENTIALS`   | 401    | Email/password combination is incorrect.                                              | Check credentials and try again. Do not expose which field is wrong to end users. |
| `UNAUTHORIZED`          | 401    | Request is missing a valid authentication token or API key.                           | Include `Authorization: Bearer <token>` or `X-Api-Key: <key>`.                    |
| `INVALID_REFRESH_TOKEN` | 401    | The refresh token is missing, malformed, or expired.                                  | Send the user back through the login flow to obtain a new token pair.             |
| `TOKEN_REVOKED`         | 401    | The refresh token was already used or revoked (e.g. after logout or password change). | Re-authenticate.                                                                  |
| `IP_WHITELIST_REQUIRED` | 403    | Your merchant account requires an IP whitelist but none is configured.                | Add at least one IP address to your whitelist in the dashboard.                   |
| `IP_NOT_WHITELISTED`    | 403    | The requesting IP address is not in your merchant's whitelist.                        | Add the IP to your whitelist or make the request from a whitelisted address.      |
| `NOT_FOUND`             | 404    | The requested record does not exist.                                                  | Verify the ID or identifier you used.                                             |
| `ALREADY_VERIFIED`      | 422    | The email address has already been verified.                                          | No action needed — proceed to login.                                              |
| `INVALID_OTP`           | 400    | The one-time code is incorrect or has expired.                                        | Request a new OTP using `POST /auth/resend-otp` or `POST /auth/forgot-password`.  |
| `WRONG_PASSWORD`        | 400    | The `current_password` supplied to the change-password endpoint is incorrect.         | Provide the correct current password.                                             |

## Validation errors in detail

When you send a request body that fails schema validation, you receive HTTP 400 with an `errors` array containing one entry per invalid field:

```json theme={null}
{
  "success": false,
  "message": "Validation failed",
  "errors": [
    {
      "field": "email",
      "message": "Invalid email address"
    },
    {
      "field": "password",
      "message": "Password must be at least 8 characters"
    }
  ]
}
```

Iterate over `errors` to show inline field-level feedback to your users.

## Handling rate limits

Auth endpoints use a stricter rate limit than the general 100 requests/minute cap. When you receive a `429` response:

1. Read the `Retry-After` header to find out how long to wait.
2. Pause all requests to that endpoint for at least that many seconds.
3. Implement exponential back-off in automated systems to avoid hitting the limit repeatedly.

Do not retry immediately after a `429` — further rapid requests will reset the window.
