# Error Handling

Fincore endpoints return gRPC-transcoded error payloads. This page documents the
shared error format and cross-cutting handling rules.

Endpoint-specific error catalogs live below each API contract in the product
guides. Use this page only for the shared error shape and cross-cutting handling
rules.

## Error structure

```json
{
  "code": 9,
  "message": "API Error",
  "details": [
    {
      "reason": "FAILED_PRECONDITION",
      "domain": "CORE",
      "metadata": {
        "error_detail": "The account does not have sufficient funds.",
        "http_code": "400",
        "error_code": "10-E4120"
      }
    }
  ]
}
```

The most useful troubleshooting value is usually
`details[].metadata.error_detail`.

## Reason to HTTP status

The HTTP status is derived from `details[].reason`. Branch your handling on
`reason`, not on the numeric suffix of `error_code`: a code ending in `4120`
still returns `400`.

| `reason` | HTTP | Meaning |
|  --- | --- | --- |
| `FAILED_PRECONDITION` | `400` | A business rule blocked the operation, for example insufficient funds or a state that does not allow the transition. |
| `DATA_ERROR` | `400` | A field value is invalid for its type or format. |
| `MISSING_REQUIRED_FIELDS` | `400` | A required field is absent. |
| `VALUE_TOO_LONG` | `400` | A field exceeds its maximum length. |
| `UNIQUE_VIOLATION` | `409` | The resource already exists. In public flows this is the idempotency conflict. |
| `UNAUTHORIZED` | `401` | Missing, invalid, expired, or environment-mismatched credentials. |
| `FORBIDDEN` | `403` | The client is not allowed to perform the operation. |
| `RESOURCE_NOT_FOUND` | `404` | The referenced resource does not exist for this client. |
| `INTERNAL` | `500` | Unexpected server or downstream error. |


Fincore does not return `412` or `422` on any request. A rule failure that reads
like a precondition is returned as `400` with `FAILED_PRECONDITION`. The `422`
status appears only in the opposite direction, as a response **your** endpoint
returns to a webhook; see
[Webhooks](/products/fincore/guides/webhooks#delivery-response-expectations).

## Cross-cutting handling

| HTTP | Typical action |
|  --- | --- |
| `401` | Verify `Authorization: Bearer <token>` or `x-api-key`, generate a new token, and confirm environment/client alignment. |
| `500` | Retry only if the operation is idempotent or after support confirmation. |


## Endpoint-specific errors

Use the contract section in each guide for endpoint-level errors:

| Area | Contract section |
|  --- | --- |
| Authentication | [Authentication](/products/fincore/guides/authentication#api-contracts) |
| Accounts and private account lifecycle | [Accounts](/products/fincore/guides/accounts#api-contracts) |
| Business Units | [Business Units](/products/fincore/guides/business-units#api-contracts) |
| Instruments | [Instruments](/products/fincore/guides/instruments#api-contracts) |
| Money Out | [Money Out](/products/fincore/guides/money-out#api-contracts) |
| Transaction reads and refunds | [Transactions](/products/fincore/guides/transactions#api-contracts) |
| Penny Validation | [Penny Validation](/products/fincore/guides/penny-validation#api-contracts) |
| Webhooks | [Webhooks](/products/fincore/guides/webhooks#api-contracts) |
| Money In | [Money In](/products/fincore/guides/money-in#api-contracts) |
| Reports | [Reports](/products/fincore/guides/reports#api-contracts) |


## Support checklist

When escalating an issue to Monato, include:

- Endpoint and HTTP method.
- `trackingId` or transaction `id` when available.
- `client_id`.
- HTTP status.
- `details[].metadata.error_detail`.
- Timestamp and environment.


Do not send full payloads, API keys, secrets, full CLABEs, card numbers, or
personal data.