> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.recurrente.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.recurrente.com/_mcp/server.

# Errors

> Error handling in the Recurrente API

The API uses standard HTTP status codes and returns JSON error bodies.

## HTTP Status Codes

| Code  | Meaning                                                   |
| ----- | --------------------------------------------------------- |
| `200` | Success                                                   |
| `201` | Created                                                   |
| `400` | Bad Request — invalid parameters                          |
| `401` | Unauthorized — invalid or missing API keys                |
| `422` | Unprocessable — request understood but can't be completed |
| `500` | Server Error                                              |

## Error Response Format

The API returns errors in the following format:

```json
{
  "message": "Checkout Inválido",
  "errors": {
    "items": ["can't be blank"]
  }
}
```

The `message` field is always present. The `errors` object is optional and contains field-level validation details.

## Common Errors

### Authentication Failed

```json
// 401
{
  "message": "Autenticación Errónea 👀",
  "errors": {
    "authentication": [
      "Las llaves de API son inválidas o no coinciden."
    ]
  }
}
```

Your API keys are invalid, missing, or don't match the same account/environment.

If you send an `sk_test_` key that no longer exists, the message in `errors.authentication` is:
"Esta llave TEST no existe. Las cuentas LIVE ya no tienen llave TEST: las llaves TEST ahora viven en un Sandbox. Ábrelo en Configuración → Llaves API → Sandbox y usa su llave TEST." Live accounts no longer have a TEST key; create one inside a Sandbox.

A key whose environment does not match its account's answers `401` with `"code": "environment_mismatch"`.

### Validation Error

```json
// 400
{
  "message": "Producto Inválido",
  "errors": { "name": ["can't be blank"] }
}
```

The provided parameters don't pass validation. Check the `errors` object for specific details.

### Cannot Modify Paid Checkout

```json
// 422
{ "message": "No se puede modificar un checkout pagado" }
```

You tried to modify a checkout that has already been paid.

### Resource Not Found

```json
// 404
{ "message": "Producto no encontrado" }
```

The requested resource doesn't exist or doesn't belong to your account.

## Error Handling

Always check the HTTP status code before processing the response:

```javascript
if (response.status >= 400) {
  const error = await response.json();
  console.error('API Error:', error.message);
  
  // Handle specific validation errors
  if (error.errors) {
    Object.keys(error.errors).forEach(field => {
      console.error(`${field}: ${error.errors[field].join(', ')}`);
    });
  }
}
```

## Diagnose your Sandbox

Call `GET /test` with the same key and confirm `environment: sandbox`. IDs from another account or environment cannot be reused. `sandbox_unsupported` means the operation is blocked. Masked key previews cannot authenticate: create a new key, or rotate the old key when you intend to revoke it. See [first-payment troubleshooting](/guides-english/getting-started/first-test-payment#troubleshooting).