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

# Errors and failure codes

> How the API reports errors, what each error code means, and which errors are safe to retry.

Infinity uses conventional HTTP status codes to indicate whether a request succeeded. Codes in the `2xx` range indicate success. Codes in the `4xx` range indicate a problem with the request as sent, such as a missing parameter, an invalid amount or insufficient funds; the body tells you exactly what. Codes in the `5xx` range indicate a problem on Infinity's side and are rare.

Every error returns the same body:

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_payout_request",
    "message": "amount has more than 2 decimals for eur.",
    "param": "items[0].amount",
    "request_id": "req_4f4b2bjc4mamxuxm",
    "timestamp": "2026-10-29T10:00:00Z"
  }
}
```

## The error object

| Attribute | Description |
| - | - |
| `type` | The class of error, derived from the HTTP status: `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `api_error`. |
| `code` | A stable, machine-readable identifier for the specific error. Branch your error handling on this. |
| `message` | A human-readable explanation for developers. Its wording may change, so don't parse it or show it to end users verbatim. |
| `param` | The parameter at fault, as a path: `amount`, `items[3].payee_id`, `beneficiary_address.postal_code`, or `Idempotency-Key` for the header. `null` when the error isn't tied to one parameter. |
| `request_id` | The identifier of this request, also returned in the `Request-Id` header. Include it when you contact support. |
| `timestamp` | When the error was produced, in UTC. |

All attributes are always present.

## HTTP status codes

| Status | `type` | Meaning | Retry |
| - | - | - | - |
| `400` | `invalid_request_error` | The request is invalid or can't be fulfilled. | No. Correct it first. |
| `401` | `authentication_error` | No API key, or an invalid one. | No. |
| `403` | `permission_error` | The key is valid but isn't allowed to perform the request. | No. |
| `404` | `invalid_request_error` | The object or path doesn't exist. | No. |
| `405` | `invalid_request_error` | The path doesn't support the method. | No. |
| `409` | `invalid_request_error` | The request conflicts with the object's current state. | Only after the state changes. |
| `415` | `invalid_request_error` | The body isn't `application/json`. | No. |
| `429` | `rate_limit_error` | Too many requests. | Yes, after `Retry-After`. |
| `500` | `api_error` | An unexpected error on Infinity's side. | Yes, with the same `Idempotency-Key`. |
| `503` | `api_error` | A dependency was temporarily unavailable. | Yes, with the same `Idempotency-Key`. |

To avoid confirming that another account's objects exist, an ID belonging to a different account returns the same `404` as an ID that doesn't exist.

## Error codes

Infinity may add error codes. Handle an unrecognised `code` by its HTTP status and `type`.

### General

| Status | `code` | Cause |
| - | - | - |
| 400 | `invalid_json` | The body isn't valid JSON. |
| 400 | `type_mismatch` | A field has the wrong JSON type, for example `"amount": 500` instead of `"500.00"`. |
| 400 | `missing_parameter` | A required field, query parameter or header is missing. |
| 400 | `unknown_parameter` | A field or query parameter isn't recognised. The API rejects unknown parameters rather than ignoring them, so typos surface immediately. |
| 404 | `path_not_found` | The path doesn't exist. |
| 405 | `method_not_allowed` | The path doesn't support the HTTP method. |
| 415 | `unsupported_media_type` | The body isn't `application/json`. |
| 429 | `rate_limited` | The key exceeded its [rate limit](https://docs.infinityapp.in/guides/rate-limits.md). |
| 500 | `internal_server_error` | An unexpected error. Retry with the same idempotency key. |
| 503 | `service_unavailable` | A dependency didn't respond. Retry with the same idempotency key. |

### Authentication

| Status | `code` | Cause |
| - | - | - |
| 401 | `missing_authorization` | No `Authorization: Bearer` header. |
| 401 | `invalid_api_key` | The key doesn't exist or was revoked. |
| 401 | `wrong_environment` | A test key on the live host, or a live key on the sandbox. |
| 403 | `account_inactive` | The key's account has been deactivated. |

### Payouts and quotes

| Status | `code` | Cause |
| - | - | - |
| 400 | `invalid_payout_request` | A field or item breaks a rule, there are more than 100 items, or a payee appears twice. |
| 400 | `wallet_not_found` | `wallet_id` isn't one of your wallets. |
| 400 | `payee_not_found` | A `payee_id` in the body isn't one of your payees. `param` names the item. |
| 400 | `insufficient_funds` | The wallet's available amount doesn't cover the request. Nothing was created. |
| 404 | `payout_not_found` | No such payout. |
| 404 | `payout_batch_not_found` | No such batch. |
| 409 | `payout_not_editable` | The payout isn't on hold, so it can't be updated or canceled. |
| 409 | `idempotency_key_reused` | The idempotency key was used with a different body. |
| 409 | `idempotency_key_in_use` | A request with this idempotency key is still being processed. |

### Payees and payee addresses

| Status | `code` | Cause |
| - | - | - |
| 400 | `invalid_payee_request` | A payee field breaks a rule, or an address's currency doesn't match the payee's. |
| 400 | `bank_details_invalid` | A bank field breaks a rail rule, or the payout network rejected the account. |
| 400 | `kyc_required` | INR payees must add bank details through hosted onboarding. |
| 404 | `payee_not_found` | No such payee. |
| 404 | `address_not_found` | No such address. |
| 409 | `payee_exists` | A payee with this email already exists. The message includes its ID. |
| 409 | `payee_already_active` | The payee is already active. |
| 409 | `address_exists` | The payee already has an address. |

### Account, wallets, deposits, webhooks and events

| Status | `code` | Cause |
| - | - | - |
| 400 | `invalid_payer_setting_request` | A setting value isn't allowed, or no setting was sent. |
| 404 | `wallet_not_found` | No such wallet. |
| 400 | `invalid_deposit_request` | An invalid list parameter, or an invalid test deposit. |
| 404 | `deposit_not_found` | No such deposit. |
| 400 | `invalid_webhook_endpoint_request` | An invalid URL, an unknown event type, or `*` combined with other types. |
| 400 | `webhook_endpoint_limit_reached` | The account already has 5 webhook endpoints. |
| 404 | `webhook_endpoint_not_found` | No such endpoint, or it was deleted. |
| 409 | `webhook_endpoint_exists` | Another of your endpoints already uses this URL. |
| 400 | `invalid_event_request` | An invalid list parameter or an unknown event type. |
| 404 | `event_not_found` | No such event, or it's older than 30 days. |

### Sandbox

| Status | `code` | Cause |
| - | - | - |
| 409 | `test_transition_not_allowed` | The payee or payout can't move to the requested status from its current one. |

## Errors versus payout failures

Error responses describe requests that Infinity couldn't accept. A payout that was accepted can still fail later, at the network or the payee's bank; that isn't an error response but a status change to `failed` or `returned`, with a `failure_code`. See [Failure codes](https://docs.infinityapp.in/guides/payouts.md#failure-codes).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.