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

# Errors

> Response envelopes and error codes.

## Response envelopes

**Success:**

```json theme={null}
{ "success": true, "data": { "...": "…" } }
```

**Paginated list:**

```json theme={null}
{
  "success": true,
  "data": [ { "...": "…" } ],
  "pagination": { "page": 1, "limit": 50, "total": 0, "totalPages": 0 }
}
```

**Error:**

```json theme={null}
{
  "success": false,
  "error": {
    "code": "INVALID_INPUT",
    "message": "Validation failed",
    "details": [ { "field": "phoneNumber", "message": "must match +254XXXXXXXXX" } ]
  }
}
```

`details` is present for validation errors (an array of `{ field, message }`) and for
rate-limit errors (`{ limit, retryAfter }`).

## Error codes

| HTTP | `code`                       | When                                                                                                                                                                                            |
| ---- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400  | `INVALID_INPUT`              | Validation failed, or a business rule was violated (farmer KYC not approved, no live solvency attestation, over attested capacity, a settlement report that exceeds the amount owed).           |
| 401  | `UNAUTHORIZED`               | Missing, invalid or revoked `x-api-key`.                                                                                                                                                        |
| 403  | `FORBIDDEN`                  | Organization deactivated, KYB verification required, or the caller's role lacks the capability.                                                                                                 |
| 403  | `TIER_NOT_ENTITLED`          | A settlement action against a policy whose frozen `settlementMode` is `DETERMINATION` — premium collection, payout retry, admin payout origination. See [Service tiers](/guides/service-tiers). |
| 403  | `NOT_PARTNER_SETTLED`        | The mirror case: a **partner settlement report** against a policy MicroCrop settles itself.                                                                                                     |
| 403  | `REGULATOR_LICENSE_REQUIRED` | No insurance-regulator operating licence on file for your market (KE: IRA, GH: NIC).                                                                                                            |
| 403  | `REGULATOR_LICENSE_EXPIRED`  | The licence on file has lapsed or has no recorded expiry.                                                                                                                                       |
| 404  | `NOT_FOUND`                  | Resource (or endpoint) not found. A determination belonging to another organization returns exactly this — identical to an unknown id.                                                          |
| 409  | `CONFLICT`                   | Duplicate (e.g. a farmer with that phone/national ID already exists).                                                                                                                           |
| 429  | `RATE_LIMIT_EXCEEDED`        | Too many requests — see [Rate limits](/guides/rate-limits).                                                                                                                                     |
| 502  | `BLOCKCHAIN_ERROR`           | An on-chain operation failed upstream.                                                                                                                                                          |
| 502  | `PAYMENT_ERROR`              | The payment provider failed.                                                                                                                                                                    |
| 500  | `INTERNAL_ERROR`             | Unexpected server error.                                                                                                                                                                        |

## Handling tips

* Branch on `error.code`, not the message (messages may change).
* `400 INVALID_INPUT` with `details` → surface the per-field messages to your
  operators.
* `403 FORBIDDEN` on purchase almost always means your organization isn't `VERIFIED`
  yet — check `GET /api/organizations/me`.
* `403 TIER_NOT_ENTITLED` is **not** a transient failure and must not be retried. It
  means the policy was sold under `DETERMINATION`: MicroCrop will never settle it, and
  the obligation is yours. Route to the [Tier 1 flow](/guides/tier-1-integration).
* `404 NOT_FOUND` on a determination id is deliberately indistinguishable from
  "belongs to another organization" — the endpoint never confirms that someone else's id
  is real.
* `409 CONFLICT` on farmer registration → the farmer already exists; look them up
  instead of re-creating.
* `429` → back off and retry after the `retryAfter` seconds in `details`.

<Note>
  Retrying a `POST /api/determinations/{id}/settlement-report` after a timeout is safe:
  it is idempotent on `(determinationId, partnerReference)` and a replay returns `200`
  with `replayed: true` and the stored report, not a `409`.
</Note>

## Removed endpoints

The org-facing wallet and reserve endpoints were removed with the non-custodial model and
now return `404 NOT_FOUND`: `GET /me/wallet`, `POST /me/wallet/fund`, `GET /me/reserve`,
`POST /me/reserve/deposit`, `POST /me/reserve/withdraw`. See
[Requirements](/requirements#the-capacity-model).
