Skip to main content
Skip to main content
Version: 1.0 (Current)

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"