Error Codes
This reference documents all error codes returned by the x3Algo API, their meanings, and how to resolve them.
Error Response Format
All errors follow a standard format:
{
"error": {
"message": "Human-readable error message",
"code": "ERROR_CODE",
"status": 400,
"details": {},
"requestId": "abc-123-def"
}
}
HTTP Status Codes
400 Bad Request
Invalid request data or validation errors.
VALIDATION_ERROR
Message: "Validation failed" or specific validation message
Cause: Request data doesn't meet validation requirements
Resolution:
- Check request body against API documentation
- Ensure all required fields are present
- Verify data types match expected types
- Check value ranges and formats
Example:
{
"error": {
"message": "Invalid timeframe",
"code": "VALIDATION_ERROR",
"status": 400,
"details": {
"field": "timeframe",
"value": "invalid",
"allowedValues": ["1m", "5m", "15m", "30m", "1h", "4h", "1d", "1w"]
}
}
}
401 Unauthorized
Authentication required or invalid credentials.
UNAUTHORIZED
Message: "Authentication required" or "Invalid credentials"
Cause: Missing, invalid, or expired access token
Resolution:
- Include valid access token in Authorization header
- Refresh expired access token using refresh token endpoint
- Re-authenticate if refresh token is expired
Example:
{
"error": {
"message": "Token expired",
"code": "UNAUTHORIZED",
"status": 401
}
}
INVALID_TOKEN
Message: "Invalid token"
Cause: Token is malformed or tampered with
Resolution:
- Verify token format (should be JWT)
- Re-authenticate to get new token
- Check for token corruption during storage/transmission
TOKEN_EXPIRED
Message: "Token expired"
Cause: Access token has expired (15 minutes)
Resolution:
- Use refresh token endpoint to get new access token
- Implement automatic token refresh in your application
403 Forbidden
Insufficient permissions or action not allowed.
FORBIDDEN
Message: Varies by context
Cause: User doesn't have permission to perform action
Resolution:
- Verify user has required permissions
- Check if resource belongs to authenticated user
- Ensure account is in good standing
Common Cases:
Daily Loss Limit:
{
"error": {
"message": "Daily loss limit reached",
"code": "FORBIDDEN",
"status": 403,
"details": {
"dailyLoss": 5000,
"limit": 5000
}
}
}
Active Algorithm:
{
"error": {
"message": "Cannot update active algorithm",
"code": "FORBIDDEN",
"status": 403,
"details": {
"algorithmId": "507f1f77bcf86cd799439011",
"status": "active"
}
}
}
404 Not Found
Resource doesn't exist.
NOT_FOUND
Message: "Resource not found" or specific resource message
Cause: Requested resource doesn't exist or was deleted
Resolution:
- Verify resource ID is correct
- Check if resource was deleted
- Ensure you have access to the resource
Example:
{
"error": {
"message": "Algorithm not found",
"code": "NOT_FOUND",
"status": 404,
"details": {
"algorithmId": "507f1f77bcf86cd799439011"
}
}
}
409 Conflict
Resource conflict or duplicate entry.
CONFLICT
Message: Varies by context
Cause: Resource already exists or conflicts with existing data
Resolution:
- Check if resource already exists
- Use different unique identifiers
- Update existing resource instead of creating new one
Example:
{
"error": {
"message": "Email already registered",
"code": "CONFLICT",
"status": 409,
"details": {
"email": "user@example.com"
}
}
}
422 Unprocessable Entity
Business logic error or invalid state transition.
UNPROCESSABLE_ENTITY
Message: Varies by context
Cause: Request is valid but cannot be processed due to business rules
Resolution:
- Review business logic requirements
- Check resource state before operation
- Ensure prerequisites are met
Common Cases:
Incomplete Configuration:
{
"error": {
"message": "Algorithm configuration incomplete",
"code": "UNPROCESSABLE_ENTITY",
"status": 422,
"details": {
"missingFields": ["entryConditions", "exitConditions"]
}
}
}
Invalid State Transition:
{
"error": {
"message": "Cannot start draft algorithm",
"code": "UNPROCESSABLE_ENTITY",
"status": 422,
"details": {
"currentStatus": "draft",
"requiredStatus": "stopped"
}
}
}
429 Too Many Requests
Rate limit exceeded.
TOO_MANY_REQUESTS
Message: "Rate limit exceeded" or "Too many requests"
Cause: Exceeded rate limit for endpoint
Resolution:
- Wait for rate limit window to reset
- Implement exponential backoff
- Reduce request frequency
- Cache responses when possible
Example:
{
"error": {
"message": "Rate limit exceeded",
"code": "TOO_MANY_REQUESTS",
"status": 429,
"details": {
"limit": 100,
"window": "1 minute",
"retryAfter": 45
}
}
}
Response Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000000
Retry-After: 45
500 Internal Server Error
Unexpected server error.
INTERNAL_SERVER_ERROR
Message: "Internal server error"
Cause: Unexpected error on server side
Resolution:
- Retry request after brief delay
- Check API status page
- Contact support if error persists
- Include requestId in support request
Example:
{
"error": {
"message": "Internal server error",
"code": "INTERNAL_SERVER_ERROR",
"status": 500,
"requestId": "abc-123-def"
}
}
503 Service Unavailable
Service temporarily unavailable.
SERVICE_UNAVAILABLE
Message: "Service temporarily unavailable"
Cause: Service is down for maintenance or overloaded
Resolution:
- Wait and retry after delay
- Check API status page
- Implement exponential backoff
Example:
{
"error": {
"message": "Service temporarily unavailable",
"code": "SERVICE_UNAVAILABLE",
"status": 503,
"details": {
"retryAfter": 300
}
}
}
Domain-Specific Errors
Algorithm Errors
ALGORITHM_NOT_FOUND
- Status: 404
- Cause: Algorithm ID doesn't exist
- Resolution: Verify algorithm ID
ALGORITHM_ALREADY_ACTIVE
- Status: 422
- Cause: Attempting to start already active algorithm
- Resolution: Check algorithm status before starting
ALGORITHM_INCOMPLETE
- Status: 422
- Cause: Algorithm missing required configuration
- Resolution: Complete all 5 configuration steps
Backtest Errors
BACKTEST_NOT_FOUND
- Status: 404
- Cause: Backtest ID doesn't exist
- Resolution: Verify backtest ID
INSUFFICIENT_DATA
- Status: 422
- Cause: Not enough historical data for backtest
- Resolution: Reduce date range or choose different symbols
BACKTEST_RUNNING
- Status: 422
- Cause: Attempting to modify running backtest
- Resolution: Wait for backtest to complete or cancel it
Trading Errors
INSUFFICIENT_BALANCE
- Status: 422
- Cause: Not enough balance for trade
- Resolution: Reduce position size or add funds
POSITION_LIMIT_REACHED
- Status: 422
- Cause: Maximum open positions reached
- Resolution: Close existing positions or increase limit
DAILY_LOSS_LIMIT
- Status: 403
- Cause: Daily loss limit reached
- Resolution: Wait until next trading day
Broker Errors
BROKER_CONNECTION_FAILED
- Status: 503
- Cause: Cannot connect to broker API
- Resolution: Check broker credentials and API status
BROKER_RATE_LIMIT
- Status: 429
- Cause: Broker API rate limit exceeded
- Resolution: Wait for rate limit reset
INVALID_SYMBOL
- Status: 400
- Cause: Symbol not supported by broker
- Resolution: Use valid symbol format (EXCHANGE:SYMBOL)
Error Handling Best Practices
1. Always Check Status Code
const response = await fetch(url, options)
if (!response.ok) {
const error = await response.json()
console.error('API Error:', error.error.message)
throw new Error(error.error.message)
}
2. Implement Retry Logic
async function apiRequestWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url, options)
if (response.ok) {
return await response.json()
}
// Don't retry client errors (4xx)
if (response.status >= 400 && response.status < 500) {
throw new Error('Client error')
}
// Retry server errors (5xx)
if (i < maxRetries - 1) {
await sleep(Math.pow(2, i) * 1000) // Exponential backoff
continue
}
} catch (error) {
if (i === maxRetries - 1) throw error
}
}
}
3. Handle Rate Limits
async function handleRateLimit(response) {
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After')
await sleep(parseInt(retryAfter) * 1000)
return true // Retry
}
return false
}
4. Log Errors with Context
try {
await createAlgorithm(data)
} catch (error) {
logger.error('Failed to create algorithm', {
error: error.message,
requestId: error.requestId,
userId: user.id,
data: data
})
}
5. Provide User-Friendly Messages
function getUserFriendlyMessage(error) {
const messages = {
'VALIDATION_ERROR': 'Please check your input and try again',
'UNAUTHORIZED': 'Please log in to continue',
'NOT_FOUND': 'The requested resource was not found',
'TOO_MANY_REQUESTS': 'Too many requests. Please try again later',
'INTERNAL_SERVER_ERROR': 'Something went wrong. Please try again'
}
return messages[error.code] || error.message
}
Debugging Tips
1. Use Request ID
Every error includes a requestId. Include this when contacting support:
console.error('Error:', error.error.message)
console.error('Request ID:', error.error.requestId)
2. Check API Status
Before debugging, check the API status page:
3. Enable Detailed Logging
Log full error responses during development:
if (process.env.NODE_ENV === 'development') {
console.log('Full Error:', JSON.stringify(error, null, 2))
}
4. Test with cURL
Isolate issues by testing with cURL:
curl -v -X GET https://api.x3algo.com/api/trading/algorithms \
-H "Authorization: Bearer YOUR_TOKEN"