# 

## HTTP status codes

Every API response includes an HTTP status code that indicates the result of the request.

### Success codes

| Code | Meaning | Description |
|  --- | --- | --- |
| `200` | OK | Request succeeded. The response body contains the requested data. |
| `201` | Created | A new resource was created successfully. |


### Client error codes

| Code | Meaning | Description | Retry? |
|  --- | --- | --- | --- |
| `400` | Bad request | The request body is malformed or contains invalid data. Check field names, types, and required fields. | No — fix the request |
| `401` | Unauthorized | Missing or invalid API key, or invalid credentials on `/v1/auth/keys`. | No — check credentials |
| `403` | Forbidden | Valid API key but insufficient permissions for the requested resource or action. | No — check account role |
| `404` | Not found | The requested resource does not exist. Verify the endpoint URL and resource ID. | No — check resource ID |
| `409` | Conflict | The request conflicts with the current resource state (for example, voiding an already-settled transaction). | No — check resource state |
| `429` | Too many requests | Rate limit exceeded. Wait and retry with exponential backoff. | Yes — back off and retry |


### Server error codes

| Code | Meaning | Description | Retry? |
|  --- | --- | --- | --- |
| `500` | Internal server error | Unexpected server error. | Yes — retry with backoff |
| `502` | Bad gateway | Gateway received an invalid response from an upstream service. | Yes — retry with backoff |
| `503` | Service unavailable | The service is temporarily overloaded or under maintenance. | Yes — retry with backoff |
| `504` | Gateway timeout | The upstream service did not respond in time. | Yes — retry with backoff |


## Error response format

When a request fails, the response body contains a structured JSON object with details about the error.

```json
{
  "error": {
    "status": 400,
    "message": "Invalid request body",
    "details": [
      {
        "field": "amount",
        "message": "Amount must be a positive integer"
      }
    ]
  },
  "correlation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```

| Field | Description |
|  --- | --- |
| `error.status` | HTTP status code (mirrors the response status) |
| `error.message` | Human-readable summary of the error |
| `error.details` | Array of field-level errors (when applicable) |
| `error.details[].field` | The request field that caused the error |
| `error.details[].message` | Description of the validation failure |
| `correlation_id` | UUID for tracing; include this when contacting support |


## Transaction response codes

Transaction responses include processor-level codes in addition to HTTP status codes. A `200 OK` response does not necessarily mean the payment was approved — check the `response_status` and `response_code` fields.

```json
{
  "id": "TRANSACTION-01JMRSPCK7XVNP3KS8F2W4T6Y",
  "transaction_state": "authorized",
  "response_status": "Approved",
  "response_code": "00",
  "response_message": "The API request is approved.",
  "correlation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```

| Field | Description |
|  --- | --- |
| `transaction_state` | Current state of the transaction (for example, `authorized`, `declined`) |
| `response_status` | Human-readable result: `Approved`, `Declined`, `Error` |
| `response_code` | Processor result code (for example, `00` for approved) |
| `response_message` | Detailed explanation of the result |


## Common processor error codes

### TSYS (credit card processor)

| Code | Meaning |
|  --- | --- |
| `00` | Approved |
| `01` | Refer to card issuer |
| `02` | Refer to card issuer, special condition |
| `05` | Do not honor |
| `12` | Invalid transaction |
| `14` | Invalid card number |
| `51` | Insufficient funds |
| `54` | Expired card |


### Vericheck (ACH processor)

ACH transactions may also return **ACH return codes** after settlement, which indicate issues discovered during clearing (for example, insufficient funds, account closed). These returns can arrive up to 60 days after the original transaction.

## Handling errors in your application

### Check the response status code first

![image](https://files.modern-mermaid.live/images/1776268354769-mermaid-diagram-1776268354466.png)

### Best practices

* **Always check `response_status`** on `200 OK` transaction responses. A successful HTTP response does not guarantee payment approval.
* **Log the `correlation_id`** from every response. Include it in support requests so the team can trace the request.
* **Map processor codes to person-friendly messages.** Do not display raw codes like `05` or `51` to persons. Instead, map them to clear messages like "Your card was declined. Please try a different payment method."
* **Implement retry logic** for `429` and `5xx` errors using exponential backoff with jitter. Always include an `Idempotency-Key` header on retries to prevent duplicate transactions.
* **Do not retry `4xx` errors** (except `429`). These indicate a problem with the request that must be fixed before retrying.


For retry implementation details, see [About best practices for integration](/docs/get-started/integration-best-practices).

## Further reading

* [About RESTful design](/docs/concepts/api-fundamentals/restful-design)
* [Request and response structure](/docs/concepts/api-fundamentals/request-response-structure)
* [About best practices for integration](/docs/get-started/integration-best-practices)