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

# Error Handling

> Error codes and handling in the Journeybee API

# Error Handling

The API uses standard HTTP status codes and returns errors in a consistent JSON format.

## Error response format

```json theme={null}
{
  "error": {
    "code": "not_found",
    "message": "Partner not found"
  }
}
```

## Error codes

| HTTP Status | Code                  | Description                                                             |
| ----------- | --------------------- | ----------------------------------------------------------------------- |
| `401`       | `unauthorized`        | Missing or invalid API key                                              |
| `403`       | `forbidden`           | API key lacks required permission (read or write)                       |
| `403`       | `module_disabled`     | The requested module is not enabled for your account                    |
| `404`       | `not_found`           | The requested resource does not exist                                   |
| `409`       | `conflict`            | The action conflicts with existing data (e.g., deleting a stage in use) |
| `422`       | `validation_error`    | Request body or query parameters failed validation                      |
| `429`       | `rate_limit_exceeded` | Too many requests — wait and retry                                      |
| `500`       | `internal_error`      | Unexpected server error                                                 |

## Handling errors

Check the HTTP status code first, then use `error.code` for programmatic handling:

```javascript theme={null}
const response = await fetch("https://api.journeybee.io/v1/partners", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "Acme Corp" }),
});

if (!response.ok) {
  const { error } = await response.json();

  switch (error.code) {
    case "unauthorized":
      // Re-authenticate or check API key
      break;
    case "validation_error":
      // Fix request body based on error.message
      break;
    case "rate_limit_exceeded":
      // Wait for Retry-After header duration
      break;
    default:
      // Log and retry or alert
      break;
  }
}
```

## Validation errors

When request validation fails, the `message` field describes which fields are invalid:

```json theme={null}
{
  "error": {
    "code": "validation_error",
    "message": "body/name: Required"
  }
}
```

## Conflict errors

Delete operations on configuration resources (stages, tiers, categories, tags, custom fields) return `409 Conflict` if the resource is currently in use:

```json theme={null}
{
  "error": {
    "code": "conflict",
    "message": "Stage \"Active\" is in use by 12 record(s) and cannot be deleted"
  }
}
```

Reassign the records to a different stage/tier/category before retrying the delete.
