Error Handling
Understand error codes and troubleshoot common issues with the CrossPostr API
Error Handling
The CrossPostr API uses conventional HTTP response codes to indicate the success or failure of an API request. Codes in the 2xx range indicate success, codes in the 4xx range indicate an error with the provided information, and codes in the 5xx range indicate a server error.
Error Response Format
All error responses follow a consistent JSON structure:
{ "success": false, "error": { "code": "ERROR_CODE", "message": "Human-readable error message", "details": "Additional error details (optional)" } }
HTTP Status Codes
2xx Success
| Code | Description | | ---- | ------------------------------------------------------------- | | 200 | OK - The request was successful | | 201 | Created - The resource was successfully created | | 204 | No Content - The request was successful, no content to return |
4xx Client Errors
| Code | Description | | ---- | ------------------------------------------------ | | 400 | Bad Request - The request was invalid | | 401 | Unauthorized - Authentication failed | | 403 | Forbidden - Insufficient permissions | | 404 | Not Found - The requested resource was not found | | 429 | Too Many Requests - Rate limit exceeded |
5xx Server Errors
| Code | Description | | ---- | ------------------------------------------------------- | | 500 | Internal Server Error - Something went wrong on our end | | 502 | Bad Gateway - Temporary server issue | | 503 | Service Unavailable - Service temporarily offline |
Error Codes
Authentication Errors
MISSING_API_KEY
HTTP Status: 401 Description: No API key was provided in the request.
{ "success": false, "error": { "code": "MISSING_API_KEY", "message": "API key is required for this endpoint" } }
Solution: Include your API key in the request headers.
INVALID_API_KEY
HTTP Status: 401 Description: The provided API key is invalid, expired, or deactivated.
{ "success": false, "error": { "code": "INVALID_API_KEY", "message": "The provided API key is invalid or expired" } }
Solution: Verify your API key and generate a new one if necessary.
INSUFFICIENT_PERMISSIONS
HTTP Status: 403 Description: The API key doesn't have the required permissions for this operation.
{ "success": false, "error": { "code": "INSUFFICIENT_PERMISSIONS", "message": "Your API key does not have the required permissions" } }
Solution: Update your API key permissions or create a new key with the required permissions.
Rate Limiting Errors
RATE_LIMIT_EXCEEDED
HTTP Status: 429 Description: You've exceeded the rate limit for your plan.
{ "success": false, "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Too many requests. Please try again later.", "details": "Rate limit: 1000/hour. Resets at: 2025-07-09T16:00:00Z" } }
Solution: Wait for the rate limit to reset or upgrade your plan.
Validation Errors
INVALID_PARAMETER
HTTP Status: 400 Description: One or more request parameters are invalid.
{ "success": false, "error": { "code": "INVALID_PARAMETER", "message": "Invalid parameter value", "details": "Parameter 'limit' must be between 1 and 50" } }
Solution: Check the parameter requirements in the API documentation.
MISSING_REQUIRED_FIELD
HTTP Status: 400 Description: A required field is missing from the request.
{ "success": false, "error": { "code": "MISSING_REQUIRED_FIELD", "message": "Missing required field", "details": "Field 'title' is required" } }
Solution: Include all required fields in your request.
Resource Errors
RESOURCE_NOT_FOUND
HTTP Status: 404 Description: The requested resource doesn't exist or you don't have access to it.
{ "success": false, "error": { "code": "RESOURCE_NOT_FOUND", "message": "The requested resource was not found" } }
Solution: Verify the resource ID and ensure you have access to it.
RESOURCE_CONFLICT
HTTP Status: 409 Description: The request conflicts with the current state of the resource.
{ "success": false, "error": { "code": "RESOURCE_CONFLICT", "message": "Resource conflict", "details": "A blog with this slug already exists" } }
Solution: Use a different value or update the existing resource.
Server Errors
INTERNAL_SERVER_ERROR
HTTP Status: 500 Description: An unexpected error occurred on our servers.
{ "success": false, "error": { "code": "INTERNAL_SERVER_ERROR", "message": "An internal server error occurred" } }
Solution: Try again later. If the problem persists, contact support.
SERVICE_UNAVAILABLE
HTTP Status: 503 Description: The service is temporarily unavailable.
{ "success": false, "error": { "code": "SERVICE_UNAVAILABLE", "message": "Service temporarily unavailable" } }
Solution: Try again later. Check our status page for updates.
Error Handling Best Practices
1. Always Check Status Codes
async function makeApiRequest(url, options) { const response = await fetch(url, options); if (!response.ok) { const error = await response.json(); throw new Error(`API Error (${response.status}): ${error.error.message}`); } return response.json(); }
2. Implement Retry Logic
async function apiRequestWithRetry(url, options, maxRetries = 3) { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { return await makeApiRequest(url, options); } catch (error) { const isLastAttempt = attempt === maxRetries; const isRetryableError = error.message.includes('500') || error.message.includes('502') || error.message.includes('503'); if (isLastAttempt || !isRetryableError) { throw error; } // Exponential backoff const delay = Math.pow(2, attempt) * 1000; await new Promise(resolve => setTimeout(resolve, delay)); } } }
3. Handle Rate Limiting
async function handleRateLimit(error) { if (error.message.includes('RATE_LIMIT_EXCEEDED')) { // Extract reset time from error details if available const match = error.message.match(/Resets at: (.+)/); if (match) { const resetTime = new Date(match[1]); const waitTime = resetTime.getTime() - Date.now(); if (waitTime > 0 && waitTime < 3600000) { // Wait max 1 hour console.log(`Rate limited. Waiting ${waitTime}ms...`); await new Promise(resolve => setTimeout(resolve, waitTime)); return true; // Indicate retry should be attempted } } } return false; }
4. Comprehensive Error Handler
class CrossPostrAPI { constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = 'https://crosspostr.ai/api/v1'; } async request(endpoint, options = {}) { const url = `${this.baseUrl}${endpoint}`; const config = { headers: { 'x-api-key': this.apiKey, 'Content-Type': 'application/json', ...options.headers, }, ...options, }; try { const response = await fetch(url, config); if (!response.ok) { await this.handleError(response); } return response.json(); } catch (error) { if (error.name === 'TypeError' && error.message.includes('fetch')) { throw new Error('Network error: Please check your internet connection'); } throw error; } } async handleError(response) { const error = await response.json(); switch (response.status) { case 401: throw new Error(`Authentication failed: ${error.error.message}`); case 403: throw new Error(`Access denied: ${error.error.message}`); case 404: throw new Error(`Not found: ${error.error.message}`); case 429: throw new Error(`Rate limit exceeded: ${error.error.message}`); case 500: case 502: case 503: throw new Error(`Server error: ${error.error.message}`); default: throw new Error(`API error: ${error.error.message}`); } } }
5. TypeScript Error Types
interface ApiError { success: false; error: { code: string; message: string; details?: string; }; } interface ApiResponse<T> { success: true; data: T; } type ApiResult<T> = ApiResponse<T> | ApiError; function isApiError(result: ApiResult<any>): result is ApiError { return !result.success; } // Usage const result = await api.getBlogs(); if (isApiError(result)) { console.error('API Error:', result.error.message); return; } // TypeScript knows result.data exists here console.log(result.data.blogs);
Debugging Tips
1. Enable Verbose Logging
const DEBUG = process.env.NODE_ENV === 'development'; function debugLog(message, data) { if (DEBUG) { console.log(`[CrossPostr API] ${message}`, data); } } // Use in your API calls debugLog('Making request to:', url); debugLog('Request headers:', headers); debugLog('Response status:', response.status);
2. Validate API Key Format
function validateApiKey(apiKey) { if (!apiKey) { throw new Error('API key is required'); } if (!apiKey.startsWith('cp_')) { throw new Error('Invalid API key format. Must start with "cp_"'); } if (apiKey.length !== 67) { // cp_ + 64 characters throw new Error('Invalid API key length'); } }
3. Test with curl
# Test authentication curl -i -H "x-api-key: your_api_key" \ https://crosspostr.ai/api/v1/blogs?limit=1 # Check response headers curl -D - -H "x-api-key: your_api_key" \ https://crosspostr.ai/api/v1/blogs # Verbose output for debugging curl -v -H "x-api-key: your_api_key" \ https://crosspostr.ai/api/v1/blogs
Getting Help
If you encounter persistent errors:
- Check API Status: Visit our status page
- Review Documentation: Ensure you're following the correct format
- Test with curl: Isolate the issue with simple requests
- Contact Support: Include error codes and request details
Support Information to Include
- API endpoint being called
- Complete error response
- Request headers (without API key)
- Programming language and library versions
- Steps to reproduce the issue