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

# Error Codes

> Understanding Paymnt Cloud error responses

Paymnt Cloud returns meaningful HTTP statuses and a JSON error body with a stable shape. Always log the `request_id` for correlation.

***

## Response format

```json theme={null}
{
  "error": {
    "type": "validation_error | authentication_error | authorization_error | not_found | conflict | unprocessable_entity | rate_limit | internal_error | connector_error",
    "code": "CE_001",
    "message": "Human-readable description",
    "request_id": "req_9f2a1b",
    "status": 400,
    "details": {
      "field": "amount",
      "reason": "must be >= 1"
    }
  }
}
```

* **type** — broad category for programmatic handling
* **code** — short, stable identifier (useful for analytics/alerting)
* **message** — concise text, safe to show to logs/ops dashboards
* **request\_id** — include in support requests
* **status** — HTTP status mirrored in the body
* **details** — optional object with extra context (e.g., invalid fields)

***

## Common categories

* **validation\_error (400)** — malformed or out-of-range parameters
* **authentication\_error (401)** — missing/invalid api-key
* **authorization\_error (403)** — action not permitted for this key/profile
* **not\_found (404)** — resource does not exist (e.g., pay\_…, cus\_…)
* **conflict (409)** — conflicting state (e.g., duplicate operation)
* **unprocessable\_entity (422)** — semantically invalid request
* **rate\_limit (429)** — too many requests, see [Rate Limits](/pages/essentials/rate-limits)
* **internal\_error (500)** — unexpected server error; safe to retry with backoff
* **connector\_error (502/503/504)** — upstream PSP/network issue; retry with backoff

See also: [Retries & Backoff](/pages/operations/retries-backoff) • [Idempotency](/pages/essentials/idempotency)

***

## Examples

### 400 — validation\_error

```json theme={null}
{
  "error": {
    "type": "validation_error",
    "code": "CE_AMOUNT_INVALID",
    "message": "amount must be a positive integer",
    "request_id": "req_01H9K6N9ZQ7D2",
    "status": 400,
    "details": { "field": "amount" }
  }
}
```

### 401 — authentication\_error

```json theme={null}
{
  "error": {
    "type": "authentication_error",
    "code": "CE_AUTH_MISSING",
    "message": "Missing or invalid api-key",
    "request_id": "req_01H9K6QE8Z5D4",
    "status": 401
  }
}
```

### 403 — authorization\_error

```json theme={null}
{
  "error": {
    "type": "authorization_error",
    "code": "CE_FORBIDDEN",
    "message": "Not allowed for this key/profile",
    "request_id": "req_01H9K6XCM3V9S",
    "status": 403
  }
}
```

### 404 — not\_found

```json theme={null}
{
  "error": {
    "type": "not_found",
    "code": "CE_RESOURCE_MISSING",
    "message": "payment not found",
    "request_id": "req_01H9K70Q8E9C0",
    "status": 404
  }
}
```

### 409 — conflict

```json theme={null}
{
  "error": {
    "type": "conflict",
    "code": "CE_STATE_CONFLICT",
    "message": "payment already captured",
    "request_id": "req_01H9K72Z4B1A7",
    "status": 409
  }
}
```

### 422 — unprocessable\_entity

```json theme={null}
{
  "error": {
    "type": "unprocessable_entity",
    "code": "CE_RULE_VIOLATION",
    "message": "profile routing rule blocked this operation",
    "request_id": "req_01H9K75S5E3QF",
    "status": 422
  }
}
```

### 429 — rate\_limit

```json theme={null}
{
  "error": {
    "type": "rate_limit",
    "code": "CE_RL_429",
    "message": "Too many requests",
    "request_id": "req_01H9K78W6P9M2",
    "status": 429
  }
}
```

### 5xx — internal/connector

```json theme={null}
{
  "error": {
    "type": "connector_error",
    "code": "CE_CONNECTOR_TIMEOUT",
    "message": "Upstream connector timed out",
    "request_id": "req_01H9K7B8S4GJ9",
    "status": 504
  }
}
```

***

## Client-side handling (Node example)

```javascript theme={null}
async function call(path, opts = {}) {
  const base = process.env.PAYMNT_BASE_URL || "https://sandbox.paymnt.cloud";
  const res = await fetch(`${base}${path}`, {
    ...opts,
    headers: {
      "Accept": "application/json",
      "api-key": process.env.PAYMNT_API_KEY,
      ...(opts.headers || {})
    }
  });

  const text = await res.text();
  const data = text ? JSON.parse(text) : null;

  if (!res.ok) {
    const err = data?.error || { status: res.status, message: "Unknown error" };
    // Log for observability
    console.error("Paymnt error", {
      status: err.status ?? res.status,
      code: err.code,
      type: err.type,
      request_id: err.request_id
    });
    throw new Error(`${err.type || "error"}: ${err.code || res.status} (${err.request_id || "no-request-id"})`);
  }

  return data;
}
```

***

## Best practices

* **Always log request\_id.** Include it in support requests
* **Don't parse by message text.** Use type/code for logic and metrics
* **Implement retries** with exponential backoff + jitter on 5xx/connector errors and safe 409/422 cases where applicable
* **Use idempotency** on mutating requests to avoid duplicates during retries
* **Handle 429** by respecting Retry-After. See [Rate Limits](/pages/essentials/rate-limits)
* **Surface actionable context** to operators (status, code, type, request\_id); keep PII out of logs

***

## Need help?

If you cannot resolve an error, contact Support and include:

* **request\_id**
* **endpoint and HTTP method**
* **approximate timestamp (UTC)**
* **high-level description** of what you attempted
