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

# Error Reference

> All error codes, messages, and recovery strategies

# Error Reference

All Naturalead API errors follow a consistent JSON format:

```json theme={null}
{
  "error": "Human-readable error message",
  "details": "Additional context (optional)"
}
```

## HTTP Status Codes

### 400 Bad Request

The request body or query parameters are invalid.

| Error Message                                                               | Cause                                      | Recovery                                      |
| --------------------------------------------------------------------------- | ------------------------------------------ | --------------------------------------------- |
| `"phone is required"`                                                       | Missing `phone` field when creating a lead | Include `phone` in the request body           |
| `"Invalid status. Must be one of: new, contacted, qualified, disqualified"` | Status value not in allowed enum           | Use one of the listed values                  |
| `"tags must be an array"`                                                   | `tags` is not an array                     | Pass tags as a JSON array: `["tag1", "tag2"]` |
| `"customFields must be a key-value object"`                                 | `customFields` is not an object            | Pass as key-value object: `{"key": "value"}`  |
| `"Invalid agent ID format"`                                                 | Agent ID is not a valid MongoDB ObjectId   | Use a valid 24-character hex string           |
| `"content (CSV string) is required"`                                        | Empty body for CSV upload                  | Include `content` field with CSV data         |
| `"content and mapping are required"`                                        | Missing mapping in CSV confirm             | Include both `content` and `mapping`          |
| `"filters.conditions array is required"`                                    | Advanced filter has malformed conditions   | Include `filters.conditions` as an array      |

### 401 Unauthorized

Authentication is missing or invalid.

| Error Message                                                                                         | Cause                                        | Recovery                                            |
| ----------------------------------------------------------------------------------------------------- | -------------------------------------------- | --------------------------------------------------- |
| `"Invalid or expired API key"`                                                                        | API key is revoked, expired, or not found    | Create a new key or rotate the existing one         |
| `"Authentication required. Provide an API key via X-API-Key header or Authorization: Bearer header."` | No API key provided                          | Add `X-API-Key` or `Authorization: Bearer` header   |
| `"Invalid webhook token"`                                                                             | Webhook endpoint token doesn't match account | Verify the webhook token from your account settings |

### 403 Forbidden

Authenticated but insufficient permissions.

403 responses use a two-field format: `{"error": "Forbidden", "message": "..."}`.

| Message                                                                         | Cause                                   | Recovery                                       |
| ------------------------------------------------------------------------------- | --------------------------------------- | ---------------------------------------------- |
| `"API key does not have the required scope (requires: {permission})."`          | Key missing the needed permission       | Create a new key with the required scope       |
| `"You do not have permission to perform this action (requires: {permission})."` | Your role lacks the required permission | Contact your account owner to update your role |

### 404 Not Found

The requested resource doesn't exist or belongs to a different account.

| Error Message                | Cause                                      | Recovery                               |
| ---------------------------- | ------------------------------------------ | -------------------------------------- |
| `"Lead not found"`           | No lead with that ID in your account       | Verify the lead ID and account context |
| `"Conversation not found"`   | Conversation doesn't exist in your account | Check the conversation ID              |
| `"Agent not found"`          | Agent config doesn't exist in your account | List agents to find valid IDs          |
| `"Campaign not found"`       | Campaign doesn't exist                     | List campaigns to find valid IDs       |
| `"Knowledge base not found"` | KB doesn't exist in your account           | List knowledge bases for valid IDs     |
| `"Document not found"`       | Document not in the specified KB           | List documents for the knowledge base  |

### 409 Conflict

The request conflicts with current state.

| Error Message                                    | Cause                                  | Recovery                                           |
| ------------------------------------------------ | -------------------------------------- | -------------------------------------------------- |
| `"A lead with this phone number already exists"` | Duplicate phone in the same account    | Search for the existing lead and update it instead |
| `"Cannot delete agent with active campaigns"`    | Agent is used by running campaigns     | Pause or delete the campaigns first                |
| `"Campaign is already running"`                  | Attempted to launch an active campaign | Pause the campaign before relaunching              |

### 429 Too Many Requests

Rate limit exceeded. Check the `RateLimit-*` headers for timing.

| Error Message                                                           | Limit     | Scope                   |
| ----------------------------------------------------------------------- | --------- | ----------------------- |
| `"Too many requests, please try again later"`                           | 1,000/min | Per IP (global)         |
| `"API key rate limit exceeded, please try again later"`                 | 500/min   | Per API key             |
| `"Sync API rate limit exceeded. Maximum 50 batch requests per minute."` | 50/min    | Per API key (sync only) |
| `"Account rate limit exceeded, please try again later"`                 | 2,000/min | Per account             |

**Recovery:** Wait for the `Retry-After` header value (seconds), then retry. See [Rate Limits](/rate-limits) for details.

### 500 Internal Server Error

An unexpected error occurred on the server.

| Error Message          | Cause                        | Recovery                                                        |
| ---------------------- | ---------------------------- | --------------------------------------------------------------- |
| `"Failed to {action}"` | Server-side processing error | Retry with exponential backoff. If persistent, contact support. |

### 503 Service Unavailable

A required integration or service is not configured.

| Error Message                                    | Cause                                 | Recovery                                                 |
| ------------------------------------------------ | ------------------------------------- | -------------------------------------------------------- |
| `"Messaging is not configured for this channel"` | No integration set up for the channel | Configure the integration in **Settings > Integrations** |
| `"Email integration is not configured"`          | Resend email not set up               | Set up email integration with a verified domain          |

## Error handling best practices

1. **Check the status code first** — branch your logic by HTTP status.
2. **Parse the `error` field** — it contains a human-readable message suitable for logging.
3. **Use `details` when available** — some errors include additional context.
4. **Implement retry with backoff** — for `429` and `500` errors, use exponential backoff with jitter.
5. **Never retry `400`, `401`, `403`, `404`** — these require fixing the request, not retrying.
