Skip to main content

Error Codes

CodeDescriptionAction
AUTH_REQUIREDNo authentication providedSend auth message or reconnect with API key
AUTH_TIMEOUTAuthentication not completed in 5sReconnect and authenticate faster
INVALID_API_KEYAPI key is invalidCheck your API key
INACTIVE_API_KEYAPI key is disabledContact support
RATE_LIMIT_EXCEEDEDToo many messagesImplement backoff, reduce request rate
CONNECTION_LIMITToo many connectionsClose unused connections
SUBSCRIPTION_LIMITToo many subscriptionsUnsubscribe from unused streams
INVALID_MESSAGEMalformed messageCheck message format
INVALID_SUBSCRIPTIONInvalid subscription typeCheck subscription parameters
SUBSCRIPTION_ERRORSubscription failedRetry with valid parameters
MESSAGE_TOO_LARGEMessage exceeds 1MB limitReduce message size
INTERNAL_ERRORServer errorRetry with exponential backoff
CONNECTION_ERRORConnection errorCheck network and retry

Error Message Format

{
  "type": "error",
  "error_code": "RATE_LIMIT_EXCEEDED",
  "message": "Rate limit exceeded. Maximum 10 messages per second",
  "details": {
    "limit": 10,
    "window": "1s"
  },
  "timestamp": "2025-08-15T10:30:00Z"
}

Common Issues & Solutions

Connection Drops

Issue: Connection closes unexpectedly
// Solution: Implement automatic reconnection
let reconnectAttempts = 0;

function reconnect() {
  if (reconnectAttempts < 5) {
    reconnectAttempts++;
    const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);
    setTimeout(() => {
      connect();
    }, delay);
  }
}

ws.onclose = (event) => {
  if (event.code !== 1000) { // Not a normal closure
    reconnect();
  }
};

Rate Limiting

Issue: Receiving RATE_LIMIT_EXCEEDED errors
// Solution: Queue messages with rate limiting
class RateLimiter {
  constructor(maxPerSecond = 10) {
    this.queue = [];
    this.processing = false;
    this.maxPerSecond = maxPerSecond;
  }

  send(ws, message) {
    this.queue.push({ ws, message });
    if (!this.processing) {
      this.process();
    }
  }

  async process() {
    this.processing = true;
    while (this.queue.length > 0) {
      const { ws, message } = this.queue.shift();
      ws.send(JSON.stringify(message));
      await new Promise(r => setTimeout(r, 1000 / this.maxPerSecond));
    }
    this.processing = false;
  }
}

Authentication Failures

Issue: Connection closes with INVALID_API_KEY
# Solution: Verify API key before connecting
def validate_connection(api_key):
    # Test connection
    test_url = f"wss://api.corebot.app/ws/v1/stream?apiKey={api_key}"
    try:
        ws = websocket.create_connection(test_url, timeout=10)
        ws.close()
        return True
    except Exception as e:
        print(f"Invalid API key or connection error: {e}")
        return False

Subscription Failures

Issue: Subscription not receiving data
// Solution: Track and verify subscriptions
const subscriptions = new Map();

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  
  if (msg.type === 'subscription_confirmed') {
    subscriptions.set(msg.subscription_id, {
      confirmed: true,
      type: msg.subscription_type,
      params: msg.params
    });
  }
  
  // Retry unconfirmed subscriptions after timeout
  setTimeout(() => {
    for (const [id, sub] of subscriptions) {
      if (!sub.confirmed) {
        console.log(`Retrying subscription ${id}`);
        // Resubscribe
      }
    }
  }, 5000);
};

Recovery Strategies

Exponential Backoff

function exponentialBackoff(attempt, maxDelay = 30000) {
  const delay = Math.min(1000 * Math.pow(2, attempt), maxDelay);
  return new Promise(resolve => setTimeout(resolve, delay));
}

Circuit Breaker

class CircuitBreaker {
  constructor(threshold = 5, timeout = 60000) {
    this.failures = 0;
    this.threshold = threshold;
    this.timeout = timeout;
    this.state = 'CLOSED';
    this.nextAttempt = Date.now();
  }

  async call(fn) {
    if (this.state === 'OPEN') {
      if (Date.now() < this.nextAttempt) {
        throw new Error('Circuit breaker is OPEN');
      }
      this.state = 'HALF_OPEN';
    }

    try {
      const result = await fn();
      this.onSuccess();
      return result;
    } catch (error) {
      this.onFailure();
      throw error;
    }
  }

  onSuccess() {
    this.failures = 0;
    this.state = 'CLOSED';
  }

  onFailure() {
    this.failures++;
    if (this.failures >= this.threshold) {
      this.state = 'OPEN';
      this.nextAttempt = Date.now() + this.timeout;
    }
  }
}

Best Practices

Log all errors with timestamps for debugging and monitoring.
Never retry authentication errors immediately - they likely indicate configuration issues.
Implement health checks by sending periodic ping messages and monitoring pong responses.