ApiError Class
All HTTP errors from the SDK are thrown asApiError instances. Inspect the status, message, and data properties to determine what went wrong.
ApiError Properties
| Property | Type | Description |
|---|---|---|
status | number | HTTP status code (400, 401, 429, 500, etc.) |
message | string | Error description from the server |
data | unknown | Raw response body, useful for debugging |
Common Status Codes
| Code | Meaning | Action |
|---|---|---|
400 | Bad request (invalid parameters) | Fix request parameters |
401 | Unauthorized (invalid or missing API key) | Check your LIMITLESS_API_KEY |
403 | Forbidden (insufficient permissions) | Verify account permissions |
404 | Not found (invalid slug or resource) | Check market slug or resource ID |
429 | Rate limited | Back off and retry with delay |
500 | Internal server error | Retry with exponential backoff |
502 | Bad gateway | Retry with exponential backoff |
503 | Service unavailable | Retry with exponential backoff |
504 | Gateway timeout | Retry with exponential backoff |
withRetry Wrapper
The SDK provides awithRetry utility function that wraps any async operation with configurable retry logic.
withRetry Options
| Option | Type | Default | Description |
|---|---|---|---|
statusCodes | number[] | [429, 500, 502, 503, 504] | HTTP status codes that trigger a retry |
maxRetries | number | 3 | Maximum number of retry attempts |
delays | number[] | [1000, 2000, 4000] | Delay in ms before each retry. If fewer delays than retries, the last delay is reused. |
onRetry | (error: ApiError, attempt: number) => void | — | Callback invoked before each retry |
Only
ApiError instances with a matching status code trigger retries. Other errors (network failures, timeouts) are thrown immediately.@retryOnErrors Decorator
For class-based architectures, use the@retryOnErrors decorator to add retry logic to individual methods.
Decorator Options
| Option | Type | Default | Description |
|---|---|---|---|
statusCodes | number[] | [429, 500, 502, 503, 504] | HTTP status codes that trigger a retry |
maxRetries | number | 3 | Maximum number of retry attempts |
exponentialBase | number | 2 | Base for exponential backoff calculation (base^attempt * 1000 ms) |
maxDelay | number | 30000 | Maximum delay in milliseconds between retries |
exponentialBase: 2 and maxDelay: 30000:
| Attempt | Delay |
|---|---|
| 1 | 2,000 ms |
| 2 | 4,000 ms |
| 3 | 8,000 ms |
| 4 | 16,000 ms |
| 5 | 30,000 ms (capped) |
Rate Limiting with OrderQueue
For high-frequency trading scenarios, implement anOrderQueue to throttle outgoing requests and avoid 429 errors:
Best Practices
Always handle ApiError specifically
Always handle ApiError specifically
Catch
ApiError separately from other errors. Network failures, JSON parse errors, and timeouts are not ApiError instances and should be handled differently.Do not retry 400 or 401 errors
Do not retry 400 or 401 errors
Client errors (400, 401, 403) indicate a problem with your request or credentials. Retrying them wastes time and API quota. Only retry transient server errors (429, 5xx).
Use exponential backoff for 429 responses
Use exponential backoff for 429 responses
When rate limited, the server may include a
Retry-After header. If available, respect it. Otherwise, use exponential backoff starting at 1 second.Combine retry with OrderQueue
Combine retry with OrderQueue
For the most robust setup, use
OrderQueue to throttle request rate and withRetry or @retryOnErrors to handle transient failures:Logging
The SDK provides optional logging through a simpleILogger interface. Logging is completely opt-in with zero overhead by default.
Quick Start
Log Levels
| Level | What’s Logged |
|---|---|
debug | Request headers (API key redacted), request/response bodies, WebSocket events |
info | API requests (method + URL), successful responses, order creation/cancellation |
warn | Warnings only |
error | API errors (with status code), network errors, WebSocket connection errors |
Custom Logger for Production
Implement theILogger interface to integrate with your own logging infrastructure:
Passing Logger to SDK Components
All SDK components accept an optional logger:The SDK automatically redacts API keys in logs (shown as
***). Private keys are never logged.