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

# Error Handling

> Understand API error responses and how to handle them

# Error Handling

When a request fails, the API returns a JSON object with a consistent structure.

## Error Format

```json theme={null}
{
  "type": "ErrorType",
  "detail": "Human-readable description of what went wrong"
}
```

| Field | Description |
| - | - |
| `type` | Machine-readable error identifier |
| `detail` | Human-readable explanation |

## Error Codes

| Status | Type | When It Occurs |
| - | - | - |
| 400 | `ValueError` | Invalid query parameters (e.g., `limit` > 100) |
| 401 | `UnauthorizedError` | API key is missing, invalid, expired, or revoked |
| 402 | `InsufficientFundsError` | The account cannot pay for the message — `POST /v1/template-messages` only. See [Cart Abandonment](/en/outbound/cart-abandonment) |
| 403 | `ForbiddenError` | The key lacks the scope the endpoint requires — see [Authentication](/en/authentication) |
| 404 | `NotFoundError` | The requested resource does not exist |
| 422 | `ValidationError` | Request body has invalid or missing fields |
| 429 | `RateLimitExceededError` | Rate limit exceeded — see [Rate Limiting](/en/rate-limiting) |
| 500 | `InternalServerError` | Unexpected server error |
| 502 | `UpstreamError` | An internal service failed. Retry later |

## Examples

<AccordionGroup>
  <Accordion title="400 Bad Request">
    ```json theme={null}
    {
      "type": "ValueError",
      "detail": "limit must not exceed 100"
    }
    ```

    **Fix:** Check your query parameters. `limit` must be between 1 and 100, and `page` must be 1 or greater.
  </Accordion>

  <Accordion title="401 Unauthorized">
    ```json theme={null}
    {
      "type": "UnauthorizedError",
      "detail": "Invalid or missing API key"
    }
    ```

    **Fix:** Verify that the `X-API-Key` header is present and contains a valid, active key.
  </Accordion>

  <Accordion title="403 Forbidden">
    ```json theme={null}
    {
      "type": "ForbiddenError",
      "detail": "Missing required scope: orders:read"
    }
    ```

    **Fix:** Your key is valid but lacks the scope that endpoint requires. Keys are created with full access today, so this error should not appear; if you see it, contact support. See [Authentication](/en/authentication).
  </Accordion>

  <Accordion title="404 Not Found">
    ```json theme={null}
    {
      "type": "NotFoundError",
      "detail": "Order 99999 not found"
    }
    ```

    **Fix:** Verify that the resource ID exists and belongs to your merchant account.
  </Accordion>

  <Accordion title="429 Too Many Requests">
    ```json theme={null}
    {
      "type": "RateLimitExceededError",
      "detail": "Rate limit exceeded"
    }
    ```

    **Fix:** Wait for the duration indicated in the `Retry-After` header before retrying. See [Rate Limiting](/en/rate-limiting) for best practices.
  </Accordion>

  <Accordion title="422 Validation Error">
    <Warning>
      422 errors use a different format: `detail` is an **array of objects** (Pydantic/FastAPI format), not a string.
    </Warning>

    ```json theme={null}
    {
      "detail": [
        {
          "loc": ["body", "option_values"],
          "msg": "List should have at least 1 item",
          "type": "too_short"
        }
      ]
    }
    ```

    | Field | Description |
    | - | - |
    | `loc` | Location of the failing field (e.g. `["body", "name"]`) |
    | `msg` | Validation error description |
    | `type` | Pydantic error type (not the same `type` as the standard format) |

    **Fix:** Check your request body. See the [API Reference](/api-reference) for required fields.
  </Accordion>

  <Accordion title="502 Bad Gateway">
    ```json theme={null}
    {
      "type": "UpstreamError",
      "detail": "An internal service error occurred. Please try again later."
    }
    ```

    **Fix:** An internal service failed. Your request is valid — retry after a few seconds. If the issue persists, contact support.
  </Accordion>

  <Accordion title="500 Internal Server Error">
    ```json theme={null}
    {
      "type": "InternalServerError",
      "detail": "Internal server error"
    }
    ```

    **Fix:** This is a server-side issue. Retry after a brief delay. If the problem persists, contact developer support.
  </Accordion>
</AccordionGroup>

## Handling Errors in Code

<CodeGroup>
  ```python Python theme={null}
  import httpx

  response = httpx.get(
      "https://api.ya.onl/v1/orders",
      headers={"X-API-Key": "yv_live_v1_your_api_key"},
  )

  if response.status_code == 200:
      orders = response.json()["data"]
  elif response.status_code == 429:
      retry_after = int(response.headers["Retry-After"])
      print(f"Rate limited. Retry in {retry_after}s")
  else:
      error = response.json()
      print(f"Error [{response.status_code}]: {error['type']} - {error['detail']}")
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.ya.onl/v1/orders", {
    headers: { "X-API-Key": "yv_live_v1_your_api_key" },
  });

  if (response.ok) {
    const { data: orders } = await response.json();
  } else if (response.status === 429) {
    const retryAfter = response.headers.get("Retry-After");
    console.log(`Rate limited. Retry in ${retryAfter}s`);
  } else {
    const error = await response.json();
    console.error(`Error [${response.status}]: ${error.type} - ${error.detail}`);
  }
  ```
</CodeGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.