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

# Errors overview

> The canonical Agnes error envelope, the full list of stable error codes, and retry guidance.

The Agnes API returns errors with a consistent JSON envelope so client
applications and SDKs can parse them programmatically. This page is the
overview; every canonical code has a dedicated page under
[errors](/errors/overview) that you can link to from your own
operational runbooks.

If you are using one of the official SDKs
([`agnes-security`](https://pypi.org/project/agnes-security/) or
[`@lasscyber/agnes-security`](https://www.npmjs.com/package/@lasscyber/agnes-security)),
all of this is parsed for you and surfaced as typed exceptions; this
page is the underlying wire contract.

## The envelope

```json theme={null}
{
  "detail": "You have exceeded your limit of 100 requests per minute.",
  "code": "rate_limit_exceeded",
  "request_id": "5b3f6c7e-7d24-4d40-9b12-3a59c01c6e91",
  "doc_url": "https://docs.lasscyber.com/errors/rate_limit_exceeded"
}
```

| Field        | Type                     | Description                                                                                                                                                                                                                          |
| ------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `detail`     | string, object, or array | Human-readable message. For HTTP 422 this is an array of `{loc, msg, type}` validation items. Some routes return a structured object with extra context (e.g. `analyzer_unavailable` 503 includes `analyzer` and `upstream_status`). |
| `code`       | string                   | Canonical, snake\_case error code. Stable across releases.                                                                                                                                                                           |
| `request_id` | string                   | Echo of the `X-Request-ID` response header. Quote this when filing support tickets.                                                                                                                                                  |
| `doc_url`    | string (URL)             | Documentation page for this error code (one of the pages in this section).                                                                                                                                                           |

## Standard headers on error responses

| Header                                                                                     | When               | What it means                                                    |
| ------------------------------------------------------------------------------------------ | ------------------ | ---------------------------------------------------------------- |
| `X-Request-ID`                                                                             | Always             | Unique ID for the request. Use it when filing a support ticket.  |
| `Retry-After`                                                                              | 429, 503           | Seconds to wait before retrying. SDKs honour this automatically. |
| `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`                          | 200, 429           | Current rate-limit window state.                                 |
| `X-Billing-Status`, `X-Billing-Message`, `X-Subscription-Status`, `X-Grace-Days-Remaining` | 402, sometimes 200 | Subscription health for the calling tenant.                      |

## Validation errors (422)

When a request body fails Pydantic validation, the API returns HTTP
422 with `detail` as an **array** of items, matching FastAPI's
standard:

```json theme={null}
{
  "detail": [
    {
      "loc": ["body", "max_tokens"],
      "msg": "Field required",
      "type": "missing"
    }
  ],
  "code": "validation_error",
  "request_id": "...",
  "doc_url": "https://docs.lasscyber.com/errors/validation_error"
}
```

Both SDKs expose these as `ValidationError` with a `field_errors` map
(Python) or `fieldErrors` (TypeScript) that walks the array for you.

## Canonical error codes

All codes are stable across minor releases. Adding a new code is a
non-breaking change; renaming or removing a code is a breaking change
and ships with a coordinated SDK release.

| Code                                                         | HTTP      | When                                                                    | Retry?                                              |
| ------------------------------------------------------------ | --------- | ----------------------------------------------------------------------- | --------------------------------------------------- |
| [`bad_request`](/errors/bad_request)                         | 400       | Malformed payload, unparseable JSON, schema violation outside Pydantic. | No, fix the request.                                |
| [`validation_error`](/errors/validation_error)               | 422       | Pydantic / FastAPI request validation failure.                          | No, fix the request.                                |
| [`unauthorized`](/errors/unauthorized)                       | 401       | Missing, expired, or invalid credentials.                               | No, refresh credentials and retry.                  |
| [`forbidden`](/errors/forbidden)                             | 403       | Authenticated but not authorised for this resource.                     | No, request access.                                 |
| [`email_not_verified`](/errors/email_not_verified)           | 403       | JWT user has not verified their email.                                  | No, verify your email.                              |
| [`not_found`](/errors/not_found)                             | 404       | Resource does not exist or is not visible to this tenant.               | No.                                                 |
| [`method_not_allowed`](/errors/method_not_allowed)           | 405       | HTTP method not supported on this path.                                 | No.                                                 |
| [`idempotency_conflict`](/errors/idempotency_conflict)       | 409       | Duplicate `Idempotency-Key` with a conflicting request body.            | No, change the key.                                 |
| [`payload_too_large`](/errors/payload_too_large)             | 413       | Request body or token count exceeds the configured cap.                 | No, send a smaller payload.                         |
| [`unsupported_api_version`](/errors/unsupported_api_version) | 400 / 410 | The `Agnes-Version` header is older than the minimum supported version. | No, upgrade your SDK or pin a newer version.        |
| [`rate_limit_exceeded`](/errors/rate_limit_exceeded)         | 429       | Tenant has exceeded its per-minute or per-month request budget.         | Yes, after `Retry-After` seconds.                   |
| [`billing_required`](/errors/billing_required)               | 402       | Subscription is past due or in a state that blocks API access.          | After resolving billing.                            |
| [`billing_grace_period`](/errors/billing_grace_period)       | 402 / 403 | Subscription has lapsed but is still inside the grace period.           | Yes, but renew before grace expires.                |
| [`analyzer_unavailable`](/errors/analyzer_unavailable)       | 503       | A specific analyzer's upstream is degraded.                             | Yes, after `Retry-After`. SDKs retry automatically. |
| [`service_unavailable`](/errors/service_unavailable)         | 503       | Generic temporary unavailability.                                       | Yes, with backoff.                                  |
| [`internal_error`](/errors/internal_error)                   | 500       | Unexpected server-side failure. Operators are paged automatically.      | Optional retry. Quote `request_id`.                 |

## Retry guidance

<Snippet file="retry-guidance.mdx" />

## Service status

For real-time API health and incident history, see
[status.lasscyber.com](https://status.lasscyber.com). Subscribe via
email or Slack to receive notifications when an incident opens or
resolves.

If you are experiencing widespread issues that are not yet reflected
on the status page, file a support ticket from
[agnes.lasscyber.com/support](https://agnes.lasscyber.com/support) and
include a recent `request_id`.
