Reference
Errors & Rate Limits
Standard error envelope, SDK exception mapping, and per tier rate limits.
Errors
All errors return a JSON envelope with code, message, and status. The SDK maps each code to a typed exception inheriting from MarketlensError. The 429 errors additionally carry structured fields inside the error object: limit, reset (Unix seconds), upgrade_url, used (budget walls), and topup_url (the monthly row wall).
Non HTTP exceptions: ConnectionError on network failure, TimeoutError after 30s (configurable). The SDK retries 429 and 5xx errors with exponential backoff (default 2 retries, configurable via max_retries). DAILY_BUDGET_EXCEEDED, ROW_LIMIT_EXCEEDED, and UNIT_LIMIT_EXCEEDED are not retried since those budgets reset at fixed times (midnight UTC, or the first of the month for the monthly row allowance).
{
"error": {
"code": "MARKET_NOT_FOUND",
"message": "Market abc... not found",
"status": 404
}
}{
"error": {
"used": 25000123,
"limit": 25000000,
"reset": 1783728000,
"upgrade_url": "https://marketlens.trade/#pricing",
"code": "DAILY_BUDGET_EXCEEDED",
"message": "Daily data row budget exhausted (25,000,000 rows). Resets at midnight UTC.",
"status": 429
}
}from marketlens import MarketLens, NotFoundError, RateLimitError
try:
book = client.orderbook.get("nonexistent-id")
except NotFoundError as e:
print(e.code, e.message)
except RateLimitError as e:
print(f"Retry after {e.retry_after}s")Rate Limits
Triple gated: a per-minute burst limit (RPM), a daily request-unit budget (1 unit per request, 5 for order book history), and a data row allowance, all tracked per user across all API keys. Query endpoints bill rows returned; exports bill a file's rows once ever, so re-downloads and series polling are free. Paid allowances are monthly and unused rows roll over one month. Catalog endpoints (markets, events, series, and signal surfaces) bill neither rows nor units, so browsing the catalog costs nothing against either allowance and keeps working after both are exhausted. Only RPM applies to them.