API and developers

Error Handling

Understand API error responses and how to handle them

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

Error Format

{
  "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
403 ForbiddenError The key lacks the scope the endpoint requires — see 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
500 InternalServerError Unexpected server error
502 UpstreamError An internal service failed. Retry later

Examples

400 Bad Request
{
  "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.

401 Unauthorized
{
  "type": "UnauthorizedError",
  "detail": "Invalid or missing API key"
}

Fix: Verify that the X-API-Key header is present and contains a valid, active key.

403 Forbidden
{
  "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.

404 Not Found
{
  "type": "NotFoundError",
  "detail": "Order 99999 not found"
}

Fix: Verify that the resource ID exists and belongs to your merchant account.

429 Too Many Requests
{
  "type": "RateLimitExceededError",
  "detail": "Rate limit exceeded"
}

Fix: Wait for the duration indicated in the Retry-After header before retrying. See Rate Limiting for best practices.

422 Validation Error

422 errors use a different format: detail is an array of objects (Pydantic/FastAPI format), not a string.

{
  "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 for required fields.

502 Bad Gateway
{
  "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.

500 Internal Server Error
{
  "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.

Handling Errors in Code

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']}")
Need help?