> For the complete documentation index, see [llms.txt](https://docs.omni.integratedcommerce.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.omni.integratedcommerce.io/get-started/errors-and-rate-limits.md).

# Errors and rate limits

The error envelope, what each code range means, and how to handle rate limits.

## The error envelope

API request errors return a consistent object. An error can occur before or after submission to the payment gateway:

```json
{
  "code": 2000,
  "status": "Rejected",
  "message": "One or more validation errors occurred.",
  "traceId": "1-6838bcce-5c0074e82ac7170d4f990d87",
  "timestamp": "2025-05-29T20:00:15.5752808Z",
  "errorDetails": [
    {
      "code": 2000,
      "field": "Amount",
      "message": "Request validation failed",
      "details": "The Amount field must be a positive number between 1 and 999,999,999."
    }
  ]
}
```

Always log `traceId`. It is the single fastest way for support to find your request.

## status is what tells you whether to retry

`status` is the execution status of the request against the payment gateway, and it is the field that decides your retry behaviour.

| Status        | Meaning                                                                                      | Safe to retry?                    |
| ------------- | -------------------------------------------------------------------------------------------- | --------------------------------- |
| `Completed`   | The request completed successfully.                                                          | n/a                               |
| `Rejected`    | The request was rejected before execution or by the gateway.                                 | Correct the cause before retrying |
| `Interrupted` | The request was interrupted and the final status is unknown. Side effects may have occurred. | **No** - check first              |
| `Unknown`     | Status could not be determined.                                                              | **No** - check first              |

{% hint style="danger" %}
`Interrupted` does not mean the payment failed. A Sale (Token) that returns `Interrupted` might still have charged the customer. Before retrying, resolve the real outcome with [`GET /transactions`](/payments/transaction-retrieval.md) - otherwise you risk double-charging.
{% endhint %}

## Error code ranges

`code` is a numeric error code, grouped into ranges so you can branch on the range rather than on every individual value.

| Range         | Category                         | Typical handling                                                                                             |
| ------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `1000`-`1999` | Authentication and authorization | Fix the API key or the resource ownership. Not retryable.                                                    |
| `2000`-`2999` | Request validation               | Fix the request. `errorDetails` names the offending field. Not retryable.                                    |
| `3000`-`3499` | Server and session errors        | Reconcile any earlier submission before replacing an expired or used session. Other errors may be transient. |
| `3500`-`3599` | Billing subscription errors      | Inspect the subscription state before retrying.                                                              |
| `4000`-`4999` | Resource not found               | The ID does not exist, or belongs to another merchant. Not retryable.                                        |
| `6000`-`6999` | SDK and client-side errors       | See [SDK error codes](/payment-sdk/error-codes.md).                                                          |
| `9000`-`9999` | Unhandled errors                 | Contact support with the `traceId`.                                                                          |

The complete enumeration, with a description for every individual code, is on the `Error` schema in the API reference.

## Transaction result codes are different

Transaction responses use `resultCode` and, when available, `resultText`. These are distinct from `code` and `message` in an error envelope:

* `0` - the transaction request was successful. Check each `transactionResponse`'s `responseCode` to determine whether the transaction was approved or declined.
* `1010` - the transaction request is pending customer interaction.
* `4100` - a token payment requires a cardholder challenge. Follow `threeDsChallenge.redirectUrl` and reconcile the outcome before retrying.
* `4001` - the transaction is being processed. Returned for asynchronous bank transfer payment methods such as [ACH](/payments/ach.md) while awaiting a final outcome.
* `1003`, `1005`, `3002`, `3005`, `3006`, `3009` - terminal-specific conditions on [card present](/payments/card-present.md) transactions, such as a busy, low-battery, or disconnected terminal.
* `6800`-`6802` - [3D Secure](/hosted-payment-form/3d-secure.md) outcomes on declined card-not-present transactions.
* `6900`-`6902` - hosted payment form and Payment SDK card outcomes: an issuer decline, a gateway failure, or a missing payment token. See [SDK error codes](/payment-sdk/error-codes.md#hosted-form-gateway-outcomes-6900-6999).

{% hint style="info" %}
`resultCode: 0` means the *request* succeeded, not that the money moved. A declined sale is a successful request with a declining `responseCode` inside `transactionResponses`. Branch on both.
{% endhint %}

The full `resultCode` enumeration is on the `ResultCode` schema in the API reference.

## HTTP status codes

| Code  | Meaning                                                                                       |
| ----- | --------------------------------------------------------------------------------------------- |
| `200` | The request was processed. Inspect the body for the transaction or error result.              |
| `400` | Request validation failed. See `errorDetails`.                                                |
| `401` | The API key is missing or invalid.                                                            |
| `404` | The resource does not exist, or is not owned by your merchant.                                |
| `409` | A resource or transaction is not ready yet (`3400`, `3401`, or `4001` in the error envelope). |
| `500` | Server or processing error. Check execution `status` before deciding whether to retry.        |
| `429` | You have exceeded the rate limit.                                                             |

## Rate limiting

If you receive `429 Too Many Requests`, pause before retrying. Honor `Retry-After` when supplied; otherwise use exponential backoff. The public API does not guarantee `X-RateLimit-Limit`, `X-RateLimit-Remaining`, or `X-RateLimit-Reset` headers.
