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

# Error codes

> The stable API error codes, their HTTP statuses, and what to do about each one.

Every JSON API error uses the same envelope, so a client can branch on a stable code rather
than parsing prose:

```json theme={null}
{
  "error": {
    "code": "SYNC_WEEKLY_LIMIT_REACHED",
    "message": "Cloud report limit reached. This scan stays local.",
    "requestId": "3f2b…",
    "details": { "daily": { "used": 5, "limit": 5, "resetsAt": "…" } }
  }
}
```

| Field       | Notes                                                        |
| ----------- | ------------------------------------------------------------ |
| `code`      | Stable. Branch on this.                                      |
| `message`   | Human-readable. May change.                                  |
| `requestId` | A fresh UUID per response, for correlating with server logs. |
| `details`   | Optional, code-specific.                                     |

CLI messaging is friendlier, but it branches on the same codes.

## General

| Code                | HTTP | Meaning                                                                                                                                                                                  |
| ------------------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BAD_REQUEST`       | 400  | A required field is missing or malformed. Also used with an explicit **413** when a body exceeds the endpoint's byte limit, because the wire contract has no payload-too-large code yet. |
| `VALIDATION_FAILED` | 422  | The shape was right but a value was not acceptable — a weak password, an invalid email, an invalid projection policy.                                                                    |
| `UNAUTHENTICATED`   | 401  | No credential, a malformed credential, or a credential that did not match.                                                                                                               |
| `FORBIDDEN`         | 403  | Authenticated, but not permitted — not a workspace member, an inactive account, or a plan limit.                                                                                         |
| `NOT_FOUND`         | 404  | The resource does not exist, or exists and you may not know that.                                                                                                                        |
| `CONFLICT`          | 409  | The operation collides with existing state — an email already registered, a binding owned by another workspace, an upload already finalized.                                             |
| `RATE_LIMITED`      | 429  | A throttle was exceeded. Wait and retry.                                                                                                                                                 |
| `INTERNAL`          | 500  | Something failed on the server. The detail is in the server log, not in the response.                                                                                                    |

## Device linking

| Code                           | HTTP | Meaning                                                                             |
| ------------------------------ | ---- | ----------------------------------------------------------------------------------- |
| `DEVICE_LINK_EXPIRED`          | 410  | The link request expired. Link requests live 10 minutes. Start a new one.           |
| `DEVICE_LINK_ALREADY_CONSUMED` | 409  | The link request was already exchanged. A verifier cannot mint a second credential. |
| `DEVICE_LINK_NOT_APPROVED`     | 428  | Nobody has approved the device in a browser yet. Keep polling `…/status`.           |
| `DEVICE_REVOKED`               | 401  | This device credential was revoked. Run `myrqen link` again.                        |

## Sync and reports

| Code                        | HTTP | Meaning                                                                                                                                                               |
| --------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SYNC_DAILY_LIMIT_REACHED`  | 429  | The plan's daily cloud-report limit is reached. `details` carries both windows. The scan still runs locally.                                                          |
| `SYNC_WEEKLY_LIMIT_REACHED` | 429  | The plan's weekly limit is reached.                                                                                                                                   |
| `REPORT_EXPIRED`            | 410  | The report passed its retention window and its contents were deleted. Your local files are unaffected.                                                                |
| `REPORT_SCHEMA_UNSUPPORTED` | 422  | The uploaded body failed schema validation, or the declared `schemaVersion` is not `1.0.0`.                                                                           |
| `UNSAFE_PAYLOAD_REJECTED`   | 422  | A progress or analytics event did not match its closed schema. This is the guard that stops source, prose, evidence, or secrets travelling through the progress path. |

## Sharing

| Code                      | HTTP | Meaning                                                                                                                             |
| ------------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `SHARE_PASSWORD_REQUIRED` | 401  | Supply the password in the `x-myrqen-share-password` header.                                                                        |
| `SHARE_NOT_AVAILABLE`     | 404  | The link is revoked, expired, or not permitted for this viewer — deliberately indistinguishable, so the response discloses nothing. |

Too many wrong passwords on one link returns `RATE_LIMITED`: 10 attempts per 10 minutes.
Correct attempts are not counted, so one attacker cannot lock out the link's legitimate
readers.

## Client versions

| Code                     | HTTP | Meaning                                                               |
| ------------------------ | ---- | --------------------------------------------------------------------- |
| `CLIENT_VERSION_REVOKED` | 403  | This CLI version was revoked by the platform. Update.                 |
| `CLIENT_VERSION_TOO_OLD` | 403  | This CLI version is below the deployment's minimum supported version. |

## Platform support

Operator-only. You will only see this on a deployment you run, acting as its platform
administrator. The endpoints that produce it are
[not documented here](/api-reference/introduction#what-is-not-documented-here).

| Code                     | HTTP | Meaning                                                                                                                                                                                                                     |
| ------------------------ | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SUPPORT_GRANT_REQUIRED` | 403  | A platform administrator asked for customer report content without an active support grant. A grant needs a written reason of at least 12 characters, a bounded expiry, and a password re-entry — and every use is audited. |

## Rate limits

Per-endpoint budgets from `apps/web/lib/rate-limit.ts`:

| Surface                                         | Limit | Window     |
| ----------------------------------------------- | ----- | ---------- |
| Login                                           | 10    | 5 minutes  |
| Login, per account                              | 20    | 15 minutes |
| Signup                                          | 20    | 1 hour     |
| Device-link creation                            | 10    | 10 minutes |
| Device-link exchange                            | 60    | 10 minutes |
| Share password attempts                         | 10    | 10 minutes |
| Progress events                                 | 600   | 1 minute   |
| Analytics, per principal                        | 600   | 1 minute   |
| Analytics, per address                          | 1200  | 1 minute   |
| Support-grant re-authentication (operator-only) | 5     | 10 minutes |

Login and recovery throttles are keyed on **both** the network and the account being signed
in to, because a caller who rotates `X-Forwarded-For` has no trustworthy network identity to
be throttled by.

## Request body limits

| Surface                      | Limit                              |
| ---------------------------- | ---------------------------------- |
| Any JSON route               | 1 MiB                              |
| Report body upload           | `MAX_REPORT_BYTES`, default 12 MiB |
| Progress events per request  | 25                                 |
| Analytics events per request | 50                                 |

A declared `Content-Length` over the limit is refused before a byte is read; a chunked body
that lies about its size is refused mid-stream and the remainder is never buffered.

## CLI exit codes

| Code | Meaning                              |
| ---- | ------------------------------------ |
| `0`  | Success.                             |
| `1`  | Any other failure.                   |
| `2`  | The finding submission was rejected. |
| `3`  | Out of scope, or not authorized.     |
| `4`  | The planned action is prohibited.    |
