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

# Error Handling: Codes, Formats, and Recovery Steps

> Understand the Ecommerce API error envelope, HTTP status codes, and how to handle auth failures, validation errors, and rate limits in your app.

Every error from the Ecommerce API follows a consistent JSON envelope so you can handle failures the same way across every endpoint. Whether the problem is a missing session, a validation failure, or a rate-limit hit, the response body always has `"success": false` alongside a human-readable `message`, a structured `errors` array with field-level detail when applicable, and a `requestId` you can include in support requests.

## Error Response Format

All error responses use the following envelope structure:

```json theme={null}
{
  "success": false,
  "message": "Validation failed",
  "errors": [
    {
      "field": "email",
      "message": "Invalid email address"
    },
    {
      "field": "password",
      "message": "Password must be at least 8 characters"
    }
  ],
  "requestId": "req_01HXYZ"
}
```

<ResponseField name="success" type="boolean" required>
  Always `false` for error responses.
</ResponseField>

<ResponseField name="message" type="string" required>
  A short, human-readable summary of what went wrong. Suitable for logging; not guaranteed to be stable across API versions, so do not use it for programmatic branching — use the HTTP status code instead.
</ResponseField>

<ResponseField name="errors" type="array">
  Present on validation errors. Each element has a `field` (the request property that failed) and a `message` describing the constraint violation.

  <Expandable title="errors[] item shape">
    <ResponseField name="field" type="string">
      The request body or query parameter key that failed validation (e.g. `"email"`, `"phone_number"`).
    </ResponseField>

    <ResponseField name="message" type="string">
      A description of the specific constraint that was violated.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="requestId" type="string">
  An opaque identifier for the specific request. Include this value when contacting support to help correlate server-side logs to your issue.
</ResponseField>

## HTTP Status Codes

The API uses standard HTTP semantics. Match on the status code first, then inspect the response body for detail.

| Status | Name                  | When it occurs                                                                                                                                                                  |
| ------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Bad Request           | The request body, query string, or path parameter failed schema validation. Fix the `errors` array items and retry.                                                             |
| `401`  | Unauthorized          | No session cookie was sent, the session has expired, or the session has been revoked. Log in again to obtain a fresh session.                                                   |
| `403`  | Forbidden             | You are authenticated but not permitted to perform this action — most commonly a missing or invalid `x-csrf-token` header, or attempting an admin-only operation as a customer. |
| `404`  | Not Found             | The requested resource does not exist or does not belong to your account (the API returns 404 instead of 403 for resources that exist but belong to another user).              |
| `409`  | Conflict              | The request conflicts with the current state — for example, registering with an already-used email address, or adding a cart item whose stock has been fully reserved.          |
| `410`  | Gone                  | A time-limited token (email verification link, password reset OTP) has already been used or has passed its expiry window. Request a fresh token.                                |
| `422`  | Unprocessable Entity  | The request is structurally valid but semantically invalid — for example, attempting to transition an order to an incompatible status.                                          |
| `429`  | Too Many Requests     | You have exceeded a rate limit. Back off and retry after the interval indicated in the `Retry-After` response header.                                                           |
| `500`  | Internal Server Error | An unexpected server-side failure occurred. These are logged automatically; include the `requestId` from the response body when reporting the issue.                            |

## Common Error Scenarios

<Accordion title="Authentication errors — 401 Unauthorized">
  A `401` response means the API could not associate your request with a valid session. The most common causes are:

  * **No cookie sent** — your HTTP client is not forwarding the `session` cookie. In `fetch`, ensure you pass `credentials: 'include'`; in `axios`, set `withCredentials: true`.
  * **Session expired** — sessions have a server-controlled lifetime. When a `401` occurs on a request that previously worked, treat it as a signal to redirect the user to log in.
  * **Session revoked** — another device or an admin action revoked the session. The user must log in again.

  **Example response:**

  ```json theme={null}
  {
    "success": false,
    "message": "Session missing or expired",
    "requestId": "req_01HXYZ"
  }
  ```

  **Recovery:** Call `POST /auth/login` or `POST /auth/register` to obtain a fresh session, then replay the original request.
</Accordion>

<Accordion title="CSRF errors — 403 Forbidden">
  A `403` on a write request almost always means the `x-csrf-token` header is absent, stale, or does not match the CSRF cookie the server has on file.

  * **Missing header** — every `POST`, `PATCH`, and `DELETE` request must include `x-csrf-token`. Read-only `GET` requests do not require it.
  * **Stale token** — CSRF tokens are bound to the session. If the session was refreshed or the token cookie expired, the previously fetched token is no longer valid.
  * **Mismatched value** — the server compares the `x-csrf-token` header against the CSRF cookie using the double-submit pattern. Any mismatch results in a `403`.

  **Example response:**

  ```json theme={null}
  {
    "success": false,
    "message": "Invalid or missing CSRF token",
    "requestId": "req_01HXYZ"
  }
  ```

  **Recovery:** Call `GET /auth/csrf-token` to obtain a fresh token, then retry the write request with the new value in `x-csrf-token`.
</Accordion>

<Accordion title="Validation errors — 400 Bad Request">
  A `400` response means your request payload, query parameters, or path parameters did not pass schema validation. The `errors` array pinpoints every failing field so you can correct them all in a single retry.

  **Example — invalid registration payload:**

  ```json theme={null}
  {
    "success": false,
    "message": "Validation failed",
    "errors": [
      {
        "field": "email",
        "message": "Invalid email address"
      },
      {
        "field": "phone_number",
        "message": "Must be a valid E.164 phone number (e.g. +14155552671)"
      },
      {
        "field": "password",
        "message": "Password must include uppercase, lowercase, number, and special character"
      }
    ],
    "requestId": "req_01HXYZ"
  }
  ```

  **Recovery:** Iterate over the `errors` array, surface the messages to the user or fix the values programmatically, and resubmit the request.
</Accordion>

<Accordion title="Rate limiting — 429 Too Many Requests">
  The API enforces rate limits to protect reliability. Login and registration endpoints apply brute-force protection — accounts are locked out after 10 consecutive failed attempts for 15 minutes. General endpoint rate limits apply across all routes.

  When you hit a limit, the response includes a `Retry-After` header specifying the number of seconds to wait before retrying.

  **Example response:**

  ```json theme={null}
  {
    "success": false,
    "message": "Too many requests. Please try again later.",
    "requestId": "req_01HXYZ"
  }
  ```

  **Recovery strategy:**

  1. Read the `Retry-After` header value (in seconds).
  2. Wait for the specified duration before retrying — do not immediately retry or you will continue receiving `429` responses.
  3. For login brute-force lockouts, wait the full 15-minute window before attempting again, or advise the user to reset their password.
  4. In automated clients, implement exponential backoff with jitter to avoid thundering-herd retries.
</Accordion>

<Accordion title="Conflict errors — 409 Conflict">
  A `409` response indicates the request is valid but conflicts with the current state of a resource. The two most common scenarios are:

  **Duplicate email on registration:**

  ```json theme={null}
  {
    "success": false,
    "message": "An account with this email address already exists",
    "requestId": "req_01HXYZ"
  }
  ```

  Direct the user to log in or use the password-reset flow instead of registering again.

  **Insufficient stock on cart or order:**

  ```json theme={null}
  {
    "success": false,
    "message": "Insufficient stock for the requested quantity",
    "requestId": "req_01HXYZ"
  }
  ```

  Reduce the requested quantity or remove the item. Refresh the product variant to show the user the current available stock before they try again.
</Accordion>

<Note>
  The `410 Gone` status code is specifically used for **expired or already-used tokens** — email verification links and password reset OTPs. A `410` is distinct from a `404` (resource never existed) and signals that the token existed but is no longer valid. To recover, request a fresh token: use `POST /auth/email-verification/resend` for verification emails, or restart the password reset flow.
</Note>
