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

# Errors

> Error response envelope, status codes, and common failure modes in Clopos Open API v2

# Errors

Every failed request in Clopos Open API v2 returns a JSON body with a consistent shape. This page documents that envelope, the HTTP status codes you can expect, and the most common errors you will encounter in practice.

## Error envelope

All error responses share the same top-level shape:

```json theme={null}
{
  "success": false,
  "message": "Human-readable summary of what went wrong",
  "error": "machine-readable error identifier"
}
```

| Field     | Type    | Notes                                                                                                                                                                                     |
| --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `success` | boolean | Always `false` on error responses. Check this first rather than relying on status codes alone — the `test/production mismatch` response is returned with `200 OK` for historical reasons. |
| `message` | string  | Free-form description suitable for logging or surfacing to an operator. Not intended to be parsed.                                                                                        |
| `error`   | string  | Present when the gateway or upstream produced a stable error identifier. Prefer matching on this when branching in code.                                                                  |

<Warning>
  Always branch on `success === false`, not on the HTTP status code. One edge case — an integrator in test mode calling a production brand — is returned as `200 OK` with `success: false`.
</Warning>

## Status codes

| Status                      | When you will see it                                                                                                                                            |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200 OK`                    | Success. Also, unusually, the `test/production mismatch` rejection at `/v2/auth`.                                                                               |
| `400 Bad Request`           | Missing required fields, invalid `integrator_id`, or invalid parameters forwarded from the upstream Clopos API.                                                 |
| `401 Unauthorized`          | Missing, invalid, or expired `x-token`; integrator disabled; test/production mismatch on authenticated endpoints; upstream auth rejected.                       |
| `404 Not Found`             | The requested resource (receipt, customer, order, etc.) does not exist in the targeted brand + venue.                                                           |
| `429 Too Many Requests`     | You exceeded the rate limit. See [Rate limits](/rate-limits).                                                                                                   |
| `500 Internal Server Error` | Unhandled gateway error. These are reported to Sentry automatically; if you see them persistently, contact support with the timestamp and your `integrator_id`. |
| `504` / timeout             | The upstream Clopos API did not respond within 8 seconds. Safe to retry idempotent requests.                                                                    |

## Common errors

### Missing `x-token`

```http theme={null}
HTTP/1.1 401 Unauthorized
```

```json theme={null}
{
  "success": false,
  "error": "Headers are missing"
}
```

You forgot to include the `x-token` header. Every v2 endpoint except `/v2/auth` requires it.

### Invalid or malformed token

```http theme={null}
HTTP/1.1 401 Unauthorized
```

```json theme={null}
{
  "success": false,
  "error": "Invalid token"
}
```

The JWT is malformed or its signature does not verify. Do not retry — re-authenticate.

### Expired token

```http theme={null}
HTTP/1.1 401 Unauthorized
```

```json theme={null}
{
  "success": false,
  "expires_at": "2026-01-01T12:00:00.000Z",
  "error": "Token expired"
}
```

The JWT has expired. Call `/v2/auth` again to obtain a fresh token, then retry the original request.

<Note>
  The `expires_at` in this error body is an **ISO 8601 string**, while the `expires_at` returned by `/v2/auth` is a **Unix timestamp in seconds**. Parse each accordingly.
</Note>

### Invalid `integrator_id` at `/v2/auth`

```http theme={null}
HTTP/1.1 400 Bad Request
```

```json theme={null}
{
  "success": false,
  "error": "Invalid integrator_id"
}
```

The `integrator_id` is not registered with Clopos or has been disabled. Request a new one via [this form](https://forms.gle/Y9P1Wnv4QFAruxny8).

### Test integrator hitting a production brand

```http theme={null}
HTTP/1.1 200 OK
```

```json theme={null}
{
  "success": false,
  "error": "Integrator is in test mode. But brand is not in test mode",
  "brand": "your_brand",
  "integrator": "your_integrator_name"
}
```

The integrator is flagged as test-only but you are trying to authenticate against a production brand. Either switch to a production `integrator_id` or target a non-production brand. See [Core concepts → Test vs production integrators](/concepts#test-vs-production-integrators).

<Warning>
  This one is the reason you should branch on `success`, not status code — it is returned as `200 OK` at `/v2/auth` even though the authentication failed.
</Warning>

### Missing required field at `/v2/auth`

```http theme={null}
HTTP/1.1 400 Bad Request
```

```json theme={null}
{
  "success": false,
  "error": "Missing client_id, client_secret, brand, or integrator_id"
}
```

One or more of the four required fields was omitted from the auth request body.

### Resource not found

```http theme={null}
HTTP/1.1 404 Not Found
```

```json theme={null}
{
  "success": false,
  "message": "Not Found"
}
```

The requested resource does not exist in the targeted brand/venue combination. Double-check the ID and that the `x-venue` you are using (explicit header or JWT default) matches the venue where the resource lives.

## Retry guidance

| Status          | Safe to retry?                                                                                                      |
| --------------- | ------------------------------------------------------------------------------------------------------------------- |
| `400`           | No — fix the request first.                                                                                         |
| `401`           | Only after re-authenticating.                                                                                       |
| `404`           | No — the resource does not exist.                                                                                   |
| `429`           | Yes, after the window indicated by `RateLimit-Reset`.                                                               |
| `500`           | Yes, with exponential backoff. If it persists, contact support.                                                     |
| Timeout / `504` | Yes for idempotent requests (`GET`). For non-idempotent requests, check the server state first to avoid duplicates. |

## Reporting a bug

If you encounter an error you cannot explain, contact [dev@clopos.com](mailto:dev@clopos.com) with:

* The full request (method, URL, headers *except* `x-token`, and body).
* The full response (status code, headers, body).
* Your `integrator_id` and `brand`.
* The approximate UTC timestamp.

These details let the Clopos team cross-reference the request in Sentry and upstream logs quickly.
