# Errors

Increase follows standard HTTP semantics:
a `2xx` status indicates success,
a `4xx` status indicates a problem with the request,
and a `5xx` status indicates a problem on Increase's side.

Every error response is a JSON object that conforms to [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457).
The `type` field is a stable, machine-readable identifier for the kind of error.
The `title` and `detail` fields are meant for humans and may change at any time.

```json
{
  "type": "invalid_operation_error",
  "status": 409,
  "title": "The action you specified can't be performed on the object in its current state.",
  "detail": "There's an insufficient balance in the account."
}
```

Our [SDKs](/documentation/software-development-kits) map it to a distinct error type,
so most consumers match on that type rather than reading `type` directly.

## Common fields

Error objects includes the following fields:

| Field    | Type    | Description                                                          |
| -------- | ------- | -------------------------------------------------------------------- |
| `type`   | string  | A stable, machine-readable identifier for the kind of error.         |
| `status` | integer | The HTTP status code, repeated in the body for convenience.          |
| `title`  | string  | A short, human-readable summary.                                     |
| `detail` | string  | Additional human-readable context for this particular error, if any. |

## Error types

The table below lists each error Increase returns,
sorted by HTTP status.

| Status | Type                                 | When you'll see it                                                                                                                          |
| ------ | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | `invalid_parameters_error`           | A request parameter failed validation. See [Invalid parameters](#invalid-parameters).                                                       |
| `400`  | `malformed_request_error`            | Increase could not parse the request body.                                                                                                  |
| `401`  | `invalid_api_key_error`              | The API key is missing, invalid, or revoked.                                                                                                |
| `403`  | `environment_mismatch_error`         | A production key was used against the sandbox host, or vice versa.                                                                          |
| `403`  | `insufficient_permissions_error`     | The API key is authenticated but is not authorized for this action.                                                                         |
| `403`  | `private_feature_error`              | The endpoint is in private beta. Email [support@increase.com](mailto:support@increase.com) for access.                                      |
| `404`  | `api_method_not_found_error`         | No API method exists at this path.                                                                                                          |
| `404`  | `object_not_found_error`             | No object exists with the specified identifier.                                                                                             |
| `409`  | `idempotency_key_already_used_error` | The `Idempotency-Key` was previously used with a different request body. See [Idempotency key already used](#idempotency-key-already-used). |
| `409`  | `invalid_operation_error`            | The action can't be performed on the object in its current state.                                                                           |
| `429`  | `rate_limited_error`                 | You've exceeded the rate limit. See [Rate limited](#rate-limited).                                                                          |
| `500`  | `internal_server_error`              | An unexpected error occurred on Increase's side; the team has been notified.                                                                |

## Type-specific fields

Some error types carry additional fields.

### Invalid parameters

Errors of type `invalid_parameters_error`
include an `errors` array with one entry per failing parameter.

```json
{
  "type": "invalid_parameters_error",
  "status": 400,
  "title": "Your request contains invalid parameters.",
  "detail": "The following errors were present:\n  amount: must be greater than 0",
  "errors": [{ "field": "amount", "message": "must be greater than 0" }]
}
```

### Idempotency key already used

Errors of type `idempotency_key_already_used_error`
includes a `resource_id` pointing to the object created by the original request.

```json
{
  "type": "idempotency_key_already_used_error",
  "status": 409,
  "title": "The idempotency key submitted has already been used. Fetch the created object or use a different idempotency key.",
  "detail": null,
  "resource_id": "account_transfer_abc123"
}
```

### Rate limited

Errors of type `rate_limited_error`
may include a `retry_after` field with the number of seconds to wait before retrying.

```json
{
  "type": "rate_limited_error",
  "status": 429,
  "title": "You've tried to take this action too many times in too short a window. Please wait a while and try again.",
  "detail": null,
  "retry_after": 30
}
```

The same number of seconds is also returned in the standard `Retry-After` response header.

## Retrying safely

`5xx` responses and network errors are generally safe to retry.
To retry a `POST` without risking duplicate side effects,
send an [`Idempotency-Key`](/documentation/idempotency-keys) header
and reuse the same value across attempts.

See the [Idempotency keys](/documentation/idempotency-keys) guide for more information.
