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

# Errors & error codes

> The response envelope, the HTTP status and error code each failure returns, and how to handle them.

Every Finance API response uses the same envelope, so you can handle success and failure uniformly.

## Response envelope

A successful response sets `success: true` and carries the payload in `result` (list endpoints also include a `pagination` object):

```json Success theme={null}
{ "success": true, "result": { "id": "..." } }
```

A failure sets `success: false` and returns one or more `errors`, each with a stable `code` and a human-readable `message`:

```json Error theme={null}
{
  "success": false,
  "errors": [
    { "code": "invalid-request", "message": "The request contains invalid parameters." }
  ]
}
```

Branch on the `code`, not the `message` — messages may change, codes are stable.

## Standard errors

These apply across endpoints:

| HTTP  | `code`                              | When it happens                                                                                                                 | What to do                                                                                                      |
| ----- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `400` | `invalid-request`                   | Malformed body or invalid parameters.                                                                                           | Fix the request; don't retry it unchanged.                                                                      |
| `401` | `unauthenticated`                   | Missing or expired token.                                                                                                       | Refresh the token and retry — see [Authentication](/getting-started/authentication).                            |
| `403` | `forbidden`                         | The operation isn't available to your company setup.                                                                            | Contact Venly to enable it.                                                                                     |
| `404` | `<resource>-not-found`              | The resource (or one it references) doesn't exist — e.g. `account-not-found`, `payment-request-not-found`.                      | Check the ID; for transfers, confirm the account is the sender or receiver.                                     |
| `409` | `concurrent-modification`           | Stale `version` on an update.                                                                                                   | Re-fetch, reapply your change, retry — see [Versioning](/guides/finance/versioning).                            |
| `422` | `idempotency-conflict` / *(varies)* | An idempotency key was reused with a different body, or replays a call that originally failed; or a semantically invalid input. | Branch on the `code`; to retry a genuine failure, use a **new** [idempotency key](/guides/finance/idempotency). |
| `500` | `internal-error`                    | Unexpected server error.                                                                                                        | Retry with backoff; if it persists, contact Venly.                                                              |

## Verification & activation gates

A new account can't move money until it's verified, and a self-custody wallet can't until its permit confirms. These gates return **different** codes per operation — treat any of them as "not ready yet" rather than matching a single code:

| Operation                                           | HTTP  | `code`                      |
| --------------------------------------------------- | ----- | --------------------------- |
| Create a virtual bank account                       | `400` | `kyc-not-verified`          |
| Create a pay-in session                             | `422` | `kyc-required`              |
| Create a payment request                            | `400` | `account-not-active`        |
| Transfer/payment on an inactive self-custody wallet | `400` | `account-wallet-not-active` |

See [Account verification](/guides/finance/kyc-verification) and [Approving transfers without gas](/guides/finance/permits-and-allowances).

## Payment request errors

[Settling](/api-reference/Finance-API/payment-requests/settle-a-payment-request), [reversing](/api-reference/Finance-API/payment-requests/reverse-a-payment-request), and [updating](/api-reference/Finance-API/payment-requests/update-a-payment-request) a payment request can return these in addition to the standard errors:

| HTTP  | `code`                      | When it happens                                                                                                                                                                           |
| ----- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400` | `invalid-amount`            | Amount ≤ 0, or (on update) equal to the current amount.                                                                                                                                   |
| `400` | `currency-mismatch`         | `currency` doesn't match the authorized currency.                                                                                                                                         |
| `402` | `insufficient-funds`        | Account wallet balance is below the upward adjustment delta.                                                                                                                              |
| `402` | `insufficient-allowance`    | Self-custody allowance is below the upward adjustment delta.                                                                                                                              |
| `403` | `company-not-active`        | Company isn't `ACTIVE` (settlement and upward adjustments only).                                                                                                                          |
| `404` | `payment-request-not-found` | No payment request with that ID/reference for your company.                                                                                                                               |
| `404` | `account-not-found`         | No account matches the supplied card-provider reference (by-reference endpoints).                                                                                                         |
| `409` | `invalid-payment-status`    | The request isn't `RESERVED`, so it can't be settled, reversed, or adjusted.                                                                                                              |
| `409` | `modification-in-progress`  | A previous adjustment or incremental authorization is still pending.                                                                                                                      |
| `409` | `wallet-not-active`         | A wallet involved in the operation isn't ready — for self-custody, confirm the [permit](/guides/finance/permits-and-allowances); otherwise the wallet's `amlStatus` isn't `APPROVED` yet. |
| `422` | `idempotency-conflict`      | The `idempotencyKey` was reused with a different body, or replays a call that originally failed.                                                                                          |

<Note>
  `wallet-not-active` and the transfer/payment-create gate `account-wallet-not-active` describe the **same condition** — the account wallet isn't ready to move funds. The exact `code` and HTTP status vary by endpoint, so treat any `*-not-active` code as "not ready yet" (see [Account verification](/guides/finance/kyc-verification) and, for self-custody, [permits](/guides/finance/permits-and-allowances)) rather than matching a single one.
</Note>

## Rate limits

The Finance API doesn't publish fixed numeric rate limits. Build for resilience regardless:

* Cache your access token and reuse it until it nears expiry — don't fetch one per request.
* Back off and retry on `500` (and on `429`, if returned), using exponential backoff with jitter.
* Make retries safe with an [idempotency key](/guides/finance/idempotency) so a replay never double-charges.

<Note>
  If you expect high call volumes, confirm current limits with your Venly contact — they aren't enumerated in the API contract.
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="API conventions" icon="list-check" href="/getting-started/conventions">
    Idempotency, pagination, and versioning rules.
  </Card>

  <Card title="Account verification" icon="shield-check" href="/guides/finance/kyc-verification">
    The most common reason an otherwise-correct request is rejected.
  </Card>
</CardGroup>
