Skip to main content

Error Response Format

All Hixbe APIs return errors in a consistent JSON format to make error handling predictable.

Standard Error Structure

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {
      // Additional error-specific information
    }
  }
}

Common Error Codes

Authentication Errors

Error CodeHTTP StatusDescriptionSolution
INVALID_API_KEY401API key is invalid or malformedCheck your API key in dashboard
MISSING_AUTH_HEADER401Authorization header missingInclude Authorization: Bearer YOUR_KEY
INSUFFICIENT_PERMISSIONS403API key lacks required permissionsCreate key with proper permissions
EXPIRED_API_KEY401API key has expiredGenerate new key in dashboard
INVALID_VERSION400API version not supportedUse Hixbe-Version: 2026-01-01

Request Errors

Error CodeHTTP StatusDescriptionSolution
INVALID_REQUEST400Request malformed or missing required fieldsCheck request format and required fields
VALIDATION_ERROR400Field validation failedReview field types and constraints
RATE_LIMIT_EXCEEDED429Too many requestsImplement exponential backoff
RESOURCE_NOT_FOUND404Requested resource doesn’t existVerify resource ID and endpoint
METHOD_NOT_ALLOWED405HTTP method not supportedUse correct HTTP method

Payment-Specific Errors

Error CodeHTTP StatusDescriptionSolution
CARD_DECLINED402Payment method was declinedTry different payment method
INSUFFICIENT_FUNDS402Account has insufficient fundsAdd funds or use different method
PAYMENT_INTENT_EXPIRED400Payment intent has expiredCreate new payment intent
AMOUNT_TOO_LARGE400Amount exceeds maximum allowedReduce amount or contact support

SMS-Specific Errors

Error CodeHTTP StatusDescriptionSolution
INSUFFICIENT_BALANCE402SMS balance too lowTop up account balance
INVALID_RECIPIENT400Phone number format invalidCheck phone number format
SENDER_ID_UNAVAILABLE400Sender ID not approvedRequest sender ID approval
MESSAGE_TOO_LONG400SMS exceeds character limitShorten message or use multiple parts

Certification Errors

Error CodeHTTP StatusDescriptionSolution
CREDENTIAL_ALREADY_EXISTS409Credential ID already in useUse unique credential identifier
INVALID_CREDENTIAL_DATA400Credential data malformedValidate credential format
VERIFICATION_FAILED400Credential verification failedCheck credential authenticity

Implementing Error Handling

Basic Error Handling

async function makeApiCall(endpoint, data) {
  try {
    const response = await fetch(`https://api.hixbe.com${endpoint}`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.HIXBE_API_KEY}`,
        'Hixbe-Version': '2026-01-01',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });

    const result = await response.json();

    if (!result.success) {
      throw new HixbeError(result.error);
    }

    return result.data;
  } catch (error) {
    if (error instanceof HixbeError) {
      handleHixbeError(error);
    } else {
      handleNetworkError(error);
    }
  }
}

class HixbeError extends Error {
  constructor(error) {
    super(error.message);
    this.code = error.code;
    this.details = error.details;
  }
}

Error-Specific Handling

function handleHixbeError(error) {
  switch (error.code) {
    case 'RATE_LIMIT_EXCEEDED':
      // Implement exponential backoff
      return retryWithBackoff();

    case 'INVALID_API_KEY':
      // Log security issue and alert admin
      console.error('Invalid API key used');
      throw new SecurityException('API key compromised');

    case 'CARD_DECLINED':
      // Handle payment failure
      notifyUser('Payment was declined. Please try a different card.');
      break;

    case 'INSUFFICIENT_BALANCE':
      // Handle SMS balance issue
      alertAdmin('SMS balance running low');
      break;

    default:
      // Log unknown errors for investigation
      console.error('Unknown error:', error);
      throw error;
  }
}

Retry Logic and Backoff

Exponential Backoff Implementation

class RetryHandler {
  constructor(maxRetries = 3, baseDelay = 1000) {
    this.maxRetries = maxRetries;
    this.baseDelay = baseDelay;
  }

  async executeWithRetry(operation) {
    let lastError;

    for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
      try {
        return await operation();
      } catch (error) {
        lastError = error;

        if (!this.shouldRetry(error) || attempt === this.maxRetries) {
          throw error;
        }

        const delay = this.calculateDelay(attempt);
        await this.sleep(delay);
      }
    }

    throw lastError;
  }

  shouldRetry(error) {
    // Retry on network errors and server errors
    const retryableCodes = ['RATE_LIMIT_EXCEEDED', 'INTERNAL_SERVER_ERROR'];

    return error.code && retryableCodes.includes(error.code);
  }

  calculateDelay(attempt) {
    // Exponential backoff with jitter
    const exponentialDelay = this.baseDelay * Math.pow(2, attempt);
    const jitter = Math.random() * 0.1 * exponentialDelay;

    return exponentialDelay + jitter;
  }

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// Usage
const retryHandler = new RetryHandler();

const result = await retryHandler.executeWithRetry(async () => {
  return await makeApiCall('/payment/payment_intents', paymentData);
});

Idempotency for Critical Operations

Implementing Idempotency

async function createPaymentIntent(data, idempotencyKey) {
  const response = await fetch('https://api.hixbe.com/payment/payment_intents', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.HIXBE_API_KEY}`,
      'Hixbe-Version': '2026-01-01',
      'Content-Type': 'application/json',
      'Idempotency-Key': idempotencyKey  // Include idempotency key
    },
    body: JSON.stringify(data)
  });

  return response.json();
}

// Generate unique idempotency keys
function generateIdempotencyKey() {
  return `payment_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}

// Safe retry with idempotency
async function createPaymentSafely(paymentData) {
  const idempotencyKey = generateIdempotencyKey();

  try {
    return await createPaymentIntent(paymentData, idempotencyKey);
  } catch (error) {
    if (error.code === 'RATE_LIMIT_EXCEEDED') {
      // Safe to retry with same key
      await sleep(2000);
      return await createPaymentIntent(paymentData, idempotencyKey);
    }
    throw error;
  }
}

Rate Limiting

Understanding Rate Limits

Hixbe implements rate limiting to ensure fair usage:
  • Payment API: 100 requests per minute per API key
  • SMS API: 50 requests per minute per API key
  • Certification API: 200 requests per minute per API key

Rate Limit Headers

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995260
X-RateLimit-Retry-After: 60

Handling Rate Limits

async function rateLimitedRequest(endpoint, options = {}) {
  const response = await fetch(`https://api.hixbe.com${endpoint}`, options);

  if (response.status === 429) {
    const retryAfter = response.headers.get('X-RateLimit-Retry-After');

    if (retryAfter) {
      await sleep(parseInt(retryAfter) * 1000);
      return rateLimitedRequest(endpoint, options); // Retry once
    }
  }

  return response;
}

Monitoring and Alerting

Error Tracking

class ErrorTracker {
  constructor() {
    this.errors = new Map();
  }

  trackError(error) {
    const key = `${error.code}_${Date.now()}`;
    this.errors.set(key, {
      error,
      timestamp: new Date(),
      stack: error.stack
    });

    // Alert on critical errors
    if (this.isCriticalError(error)) {
      this.alertAdmin(error);
    }

    // Clean old errors (keep last 24 hours)
    this.cleanup();
  }

  isCriticalError(error) {
    const criticalCodes = ['INVALID_API_KEY', 'INTERNAL_SERVER_ERROR'];
    return criticalCodes.includes(error.code);
  }

  alertAdmin(error) {
    // Send alert to admin (email, Slack, etc.)
    console.error('CRITICAL ERROR:', error);
  }

  cleanup() {
    const oneDayAgo = Date.now() - (24 * 60 * 60 * 1000);

    for (const [key, data] of this.errors) {
      if (data.timestamp.getTime() < oneDayAgo) {
        this.errors.delete(key);
      }
    }
  }
}

Best Practices

  • Always check the success field in responses
  • Implement proper error logging and monitoring
  • Use exponential backoff for retries
  • Implement idempotency for critical operations
  • Monitor rate limit headers
  • Handle both expected and unexpected errors
  • Test error scenarios in sandbox
  • Keep error messages user-friendly

Need Help?

Troubleshooting

Common error scenarios and solutions

Best Practices

Learn more integration best practices

Webhooks

Monitor errors with webhook notifications

Support

Get help with error handling