Error Handling

The SuprSonic API uses conventional HTTP response codes and provides structured error messages to help you handle errors gracefully in your applications.

Error Response Format

All API errors follow a consistent structure:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {
      "additional": "context-specific details"
    }
  }
}

HTTP Status Codes

The API uses standard HTTP status codes to indicate the success or failure of requests:

Status CodeMeaningDescription
200OKRequest succeeded
400Bad RequestInvalid request data or malformed JSON
401UnauthorizedMissing, invalid, or expired API key
403ForbiddenValid API key but insufficient permissions
404Not FoundRequested resource doesn’t exist
429Too Many RequestsRate limit exceeded
500Internal Server ErrorSomething went wrong on our end

Error Codes

Authentication Errors

{
  "success": false,
  "error": {
    "code": "AUTHENTICATION_ERROR",
    "message": "Authentication required"
  }
}

Common Causes:

  • Missing Authorization header
  • Malformed API key format
  • Revoked or expired API key
  • Using account API key where admin key is required

Authorization Errors

{
  "success": false,
  "error": {
    "code": "AUTHORIZATION_ERROR",
    "message": "Article creation currently requires admin API key"
  }
}

Common Causes:

  • Using account API key for admin-only operations
  • Insufficient permissions for the requested action

Validation Errors

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": {
      "errors": [
        {
          "code": "invalid_type",
          "expected": "string",
          "received": "number",
          "path": ["title"],
          "message": "Expected string, received number"
        }
      ]
    }
  }
}

Common Causes:

  • Missing required fields
  • Invalid data types
  • Values outside allowed ranges
  • Malformed JSON

Resource Errors

{
  "success": false,
  "error": {
    "code": "ACCOUNT_NOT_FOUND",
    "message": "Account abc123 not found"
  }
}

Rate Limiting

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded"
  }
}

Rate limits are applied per API key. See our rate limits guide for details.

Error Handling Best Practices

1. Always Check Response Status

const response = await fetch('/api/v1/articles', {
  headers: { 'Authorization': `Bearer ${apiKey}` }
});

if (!response.ok) {
  const error = await response.json();
  console.error('API Error:', error.error.message);
  return;
}

const data = await response.json();

2. Handle Different Error Types

async function handleApiError(response) {
  const error = await response.json();
  
  switch (error.error.code) {
    case 'AUTHENTICATION_ERROR':
    case 'INVALID_API_KEY':
      // Redirect to login or refresh API key
      redirectToAuth();
      break;
      
    case 'AUTHORIZATION_ERROR':
      // Show permission denied message
      showError('You don\'t have permission for this action');
      break;
      
    case 'VALIDATION_ERROR':
      // Display field-specific errors
      showValidationErrors(error.error.details.errors);
      break;
      
    case 'RATE_LIMIT_EXCEEDED':
      // Implement exponential backoff
      await retryAfterDelay();
      break;
      
    default:
      // Generic error handling
      showError('Something went wrong. Please try again.');
  }
}

3. Implement Retry Logic

async function apiRequestWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        // Rate limited - wait before retry
        const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      
      if (response.status >= 500) {
        // Server error - retry
        if (attempt === maxRetries) throw new Error('Server error after retries');
        continue;
      }
      
      return response;
      
    } catch (error) {
      if (attempt === maxRetries) throw error;
    }
  }
}

4. Validate Before Sending

function validateArticleData(article) {
  const errors = [];
  
  if (!article.title || article.title.length > 500) {
    errors.push('Title is required and must be 500 characters or less');
  }
  
  if (!article.content) {
    errors.push('Content is required');
  }
  
  if (article.tags && article.tags.length > 20) {
    errors.push('Maximum 20 tags allowed');
  }
  
  return errors;
}

// Use before API call
const validationErrors = validateArticleData(articleData);
if (validationErrors.length > 0) {
  showErrors(validationErrors);
  return;
}

Debugging Tips

Enable Request/Response Logging

// Log all API requests and responses
const originalFetch = fetch;
window.fetch = async (...args) => {
  console.log('API Request:', args);
  const response = await originalFetch(...args);
  const clonedResponse = response.clone();
  const body = await clonedResponse.json();
  console.log('API Response:', response.status, body);
  return response;
};

Common Troubleshooting

IssueCheck
401 UnauthorizedAPI key format, expiration, proper Bearer token
403 ForbiddenUsing admin key for create operations, account permissions
404 Not FoundResource IDs, endpoint URLs, resource existence
422 Validation ErrorRequired fields, data types, field constraints
429 Rate LimitedRequest frequency, implement backoff strategy

Support

If you encounter persistent errors:

  1. Check our status page for known issues
  2. Review your API key permissions in the dashboard
  3. Contact support with request IDs for faster debugging