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