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

# Error codes

> Stable, machine-readable error codes and their HTTP status.

Every error returns the same envelope with a stable `code` you can branch on and a human-readable `message`.

```json theme={null}
{ "error": { "code": "INSUFFICIENT_CREDIT", "message": "Top up your balance to issue cards" } }
```

## HTTP status mapping

| Status | Meaning                                         |
| ------ | ----------------------------------------------- |
| `400`  | Invalid request — bad or missing input          |
| `401`  | Missing or invalid credentials                  |
| `402`  | Payment required — insufficient platform credit |
| `403`  | Authenticated, but not permitted                |
| `404`  | Resource not found or out of scope              |
| `409`  | Conflict — resource already exists              |
| `410`  | Gone — link expired                             |
| `500`  | Internal error — safe to retry later            |

## Common codes

| Code                       | When                                                                                                                                                                      |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `UNAUTHORIZED`             | No valid bearer token on a protected route                                                                                                                                |
| `INVALID_CLIENT`           | Bad `client_id` / `client_secret` at the token endpoint                                                                                                                   |
| `INVALID_CREDENTIALS`      | Wrong email or password                                                                                                                                                   |
| `FORBIDDEN`                | Role lacks access to the resource or action                                                                                                                               |
| `NOT_FOUND`                | Resource missing or not visible to your org                                                                                                                               |
| `INVALID_REQUEST`          | Validation failed (e.g. applicant not approved, missing `program_id` / `account_id` / `cardholder_id`, or verified address missing state)                                 |
| `APPLICANT_ALREADY_EXISTS` | Duplicate applicant for the organization                                                                                                                                  |
| `INSUFFICIENT_CREDIT`      | Not enough balance to cover the issuance fee                                                                                                                              |
| `KYC_INCOMPLETE`           | Action requires an approved applicant                                                                                                                                     |
| `ISSUER_KYC_INCOMPLETE`    | Tenant KYC passed but issuer identity is not ready — call `POST /v1/applicants/{id}/submit` or `kyc-share`, then poll `GET …/kyc-status` until `issuerKycReady` is `true` |
| `KYC_NOT_APPROVED`         | `kyc-share` called before tenant attestation of approval                                                                                                                  |
| `KYC_SHARE_REJECTED`       | BYOK share token invalid, expired, or not addressed to Apocor's `shareRecipientId`                                                                                        |
| `KYC_SHARE_FAILED`         | Sumsub could not import the tenant share token                                                                                                                            |
| `KYC_NOT_CONFIGURED`       | Sumsub or issuer share recipients are not configured on the platform                                                                                                      |
| `RAIL_NOT_CONFIGURED`      | Live issuer rail credentials are missing — card issuance requires Interlace                                                                                               |
| `RAIL_ACCOUNT_MISSING`     | Issuer sub-account could not be created — applicant `email` is required                                                                                                   |
| `EXTERNAL_SERVICE_ERROR`   | Upstream issuer failure (budget, cardholder, or card creation). Common causes: issuer account not initialized, or verified address missing `state`                        |
| `ISSUER_ERROR`             | Upstream issuer rejected the request (e.g. cardholder at card limit, duplicate spend control). Message contains the issuer detail                                         |
| `NOT_IMPLEMENTED`          | Action requires live issuer configuration that is not enabled                                                                                                             |
| `WEAK_PASSWORD`            | Password below the minimum length                                                                                                                                         |
| `INVITE_EXPIRED`           | Onboarding link is no longer valid                                                                                                                                        |
| `INTERNAL_ERROR`           | Unexpected server error                                                                                                                                                   |

<Tip>
  Branch on `error.code`, not on `error.message`. Codes are stable across releases; messages may be reworded.
</Tip>
