Error Handling
Complete reference for error codes, messages, and troubleshooting in the Boring API.
Error Response Format
All errors return JSON with the following structure:
{
"success": false,
"error": "ErrorCode",
"message": "Human-readable error description"
}
HTTP status codes indicate the error category:
400- Bad Request (client error)401- Unauthorized (authentication error)404- Not Found (resource doesn't exist)500- Internal Server Error (server error)
Authentication Errors
InvalidApiKey
HTTP Status: 401
{
"success": false,
"error": "InvalidApiKey",
"message": "Invalid or missing API key"
}
Causes:
- API key is incorrect
- API key header is missing
- API key was deleted
- API key belongs to different account
Solutions:
- Check header name is exactly
boring-api-key - Verify API key starts with
boring_ - Generate new API key from Settings
- Ensure no extra spaces in key value
Unauthorized
HTTP Status: 401
{
"success": false,
"error": "Unauthorized",
"message": "Authentication required"
}
Causes:
- No session cookie (for dashboard endpoints)
- JWT token expired
- Not signed in to dashboard
Solutions:
- Sign in to dashboard
- Refresh your session
- Check cookies are enabled
Account Errors
InvalidAccountId
HTTP Status: 400
{
"success": false,
"error": "InvalidAccountId",
"message": "Account not found or does not belong to this user"
}
Causes:
- Account ID doesn't exist
- Account belongs to different user
- Account was disconnected
- Typo in account ID
Solutions:
- Copy account ID again from dashboard
- Verify you're using correct Google account
- Reconnect account if it was disconnected
- Check for extra spaces or characters
AccountDisabled
HTTP Status: 400
{
"success": false,
"error": "AccountDisabled",
"message": "This account has been disconnected"
}
Causes:
- Account was disconnected from dashboard
Solutions:
- Reconnect the account
- Use a different account ID
TokenExpired
HTTP Status: 401
{
"success": false,
"error": "TokenExpired",
"message": "Access token has expired"
}
Causes:
- Instagram token (60 days) expired
- Threads token (60 days) expired
- Facebook data access (90 days) expired
Solutions:
- Reconnect the account from dashboard
- Set up token expiration monitoring
- For Threads, check if auto-refresh failed
InvalidToken
HTTP Status: 401
{
"success": false,
"error": "InvalidToken",
"message": "Access token is invalid or revoked"
}
Causes:
- User revoked access in Facebook/Instagram/Threads settings
- Token was invalidated by platform
- User changed password
Solutions:
- Reconnect account from dashboard
- Grant all required permissions
Request Errors
InvalidRequest
HTTP Status: 400
{
"success": false,
"error": "InvalidRequest",
"message": "Invalid request format"
}
Causes:
- Missing required fields
- Invalid JSON syntax
- Wrong data types
Solutions:
- Check JSON is valid
- Verify all required fields present
- Match data types (string, array, etc.)
MissingParameter
HTTP Status: 400
{
"success": false,
"error": "MissingParameter",
"message": "Required parameter missing: accountId"
}
Causes:
- Required field not provided
Solutions:
- Add the missing parameter
- Check API documentation
InvalidPlatform
HTTP Status: 400
{
"success": false,
"error": "InvalidPlatform",
"message": "Platform must be 'facebook', 'instagram', or 'threads'"
}
Causes:
- Platform value is incorrect
Solutions:
- Use lowercase: "facebook", "instagram", or "threads"
- Check for typos
Media Errors
MediaDownloadFailed
HTTP Status: 400
{
"success": false,
"error": "MediaDownloadFailed",
"message": "Failed to download media from URL: https://..."
}
Causes:
- Media URL is not accessible
- URL returns 404 or other error
- URL requires authentication
- Network timeout
Solutions:
- Test URL in browser
- Ensure URL is publicly accessible
- Check URL returns correct content-type
- Verify URL uses HTTPS
InvalidMediaType
HTTP Status: 400
{
"success": false,
"error": "InvalidMediaType",
"message": "Unsupported media type: application/pdf"
}
Causes:
- File format not supported
- Wrong content-type header
Solutions:
- Convert to supported format (JPG, PNG, MP4)
- Check server returns correct content-type
InvalidMediaUrl
HTTP Status: 400
{
"success": false,
"error": "InvalidMediaUrl",
"message": "Invalid media URL format"
}
Causes:
- URL format is invalid
- Not a valid HTTP/HTTPS URL
- Local file path used
Solutions:
- Use full HTTPS URLs
- Don't use file:// or relative paths
- Check URL syntax
MediaTooLarge
HTTP Status: 400
{
"success": false,
"error": "MediaTooLarge",
"message": "Media file exceeds maximum size: 100MB"
}
Causes:
- Image/video file too large
- Platform limits exceeded
Solutions:
- Compress media file
- Check platform limits:
- Images: 8MB
- Videos: 100MB (Instagram), 512MB (Threads)
Content Errors
TextRequired
HTTP Status: 400
{
"success": false,
"error": "TextRequired",
"message": "Text is required for this post type"
}
Causes:
- Text field empty or missing for Facebook/Instagram
Solutions:
- Add text content
- For Threads text-only, ensure text is not empty
MediaRequired
HTTP Status: 400
{
"success": false,
"error": "MediaRequired",
"message": "Instagram requires at least one media item"
}
Causes:
- Instagram post without media
- mediaUrls is empty array
Solutions:
- Add at least one image or video URL
- Instagram doesn't support text-only posts
InvalidCarouselSize
HTTP Status: 400
{
"success": false,
"error": "InvalidCarouselSize",
"message": "Carousel must have 2-10 images for Instagram"
}
Causes:
- Too few images (< 2)
- Too many images (> limit)
Solutions:
- Ensure 2-10 images (Instagram, Facebook)
- Ensure 2-20 images (Threads)
TextTooLong
HTTP Status: 400
{
"success": false,
"error": "TextTooLong",
"message": "Text exceeds maximum length: 500 characters for Threads"
}
Causes:
- Single post text too long
- Platform character limits exceeded
Solutions:
- Shorten text
- For Threads, use array format to create thread
InvalidTextFormat
HTTP Status: 400
{
"success": false,
"error": "InvalidTextFormat",
"message": "Text must be string or array of strings"
}
Causes:
- Text is wrong data type
- Array contains non-string items
Solutions:
- Use string for single post
- Use array of strings for Threads thread
Publishing Errors
PublishingFailed
HTTP Status: 500
{
"success": false,
"error": "PublishingFailed",
"message": "Failed to publish post",
"details": "Platform error message"
}
Causes:
- Platform API error
- Temporary platform issue
- Content violates platform policies
Solutions:
- Check error details
- Retry after a few minutes
- Verify content meets platform guidelines
- Check platform status page
VideoProcessingFailed
HTTP Status: 500
{
"success": false,
"error": "VideoProcessingFailed",
"message": "Video processing timed out or failed"
}
Causes:
- Video format issue
- Processing timeout
- Platform processing error
Solutions:
- Convert to MP4 with H.264 codec
- Reduce video file size
- Check video duration limits
- Retry after a few minutes
CarouselCreationFailed
HTTP Status: 500
{
"success": false,
"error": "CarouselCreationFailed",
"message": "Failed to create carousel container"
}
Causes:
- Image aspect ratios don't match (Instagram)
- One or more images failed to upload
- Platform API error
Solutions:
- Ensure all images same aspect ratio (Instagram)
- Verify all image URLs are accessible
- Retry the request
Rate Limiting
RateLimitExceeded
HTTP Status: 429
{
"success": false,
"error": "RateLimitExceeded",
"message": "Rate limit exceeded. Try again in 3600 seconds",
"retry_after": 3600
}
Causes:
- Too many requests in time window
- Platform rate limits reached
Solutions:
- Wait for retry_after seconds
- Implement exponential backoff
- Reduce request frequency
- Spread requests over time
Platform limits:
- Facebook: 200 calls/hour per page
- Instagram: 200 calls/hour per user
- Threads: 250 calls/hour per user
Permission Errors
InsufficientPermissions
HTTP Status: 403
{
"success": false,
"error": "InsufficientPermissions",
"message": "Missing required permission: threads_manage_replies"
}
Causes:
- Required permission not granted
- Permission was revoked
Solutions:
- Reconnect account
- Grant all required permissions
- For Threads threads, ensure
threads_manage_repliesis granted
Server Errors
InternalServerError
HTTP Status: 500
{
"success": false,
"error": "InternalServerError",
"message": "An unexpected error occurred"
}
Causes:
- Server issue
- Database connection error
- Unexpected exception
Solutions:
- Retry after a few minutes
- Contact support if persists
- Check status page
ServiceUnavailable
HTTP Status: 503
{
"success": false,
"error": "ServiceUnavailable",
"message": "Service temporarily unavailable"
}
Causes:
- Server maintenance
- Platform API down
- High load
Solutions:
- Retry after a few minutes
- Implement retry with exponential backoff
- Check status pages
Timeout
HTTP Status: 504
{
"success": false,
"error": "Timeout",
"message": "Request timed out"
}
Causes:
- Video processing took too long
- Network issues
- Server overload
Solutions:
- Check publishing history to see if it succeeded
- Retry with smaller file
- Contact support if persists
Error Handling Best Practices
1. Always Check Success Flag
response = requests.post(API_URL, headers=headers, json=data)
result = response.json()
if not result.get("success"):
handle_error(result["error"], result["message"])
return None
return result["data"]
2. Implement Retry Logic
RETRYABLE_ERRORS = [
"RateLimitExceeded",
"ServiceUnavailable",
"Timeout",
"InternalServerError"
]
def should_retry(error_code):
return error_code in RETRYABLE_ERRORS
def publish_with_retry(data, max_attempts=3):
for attempt in range(max_attempts):
try:
result = publish(data)
if result["success"]:
return result
if not should_retry(result.get("error")):
return result # Don't retry
wait_time = result.get("retry_after", 2 ** attempt)
time.sleep(wait_time)
except Exception as e:
if attempt == max_attempts - 1:
raise
return {"success": False, "error": "MaxRetriesExceeded"}
3. Log All Errors
import logging
logger = logging.getLogger(__name__)
def handle_api_error(error_code, message, context=None):
logger.error(f"API Error: {error_code} - {message}")
if context:
logger.error(f"Context: {context}")
# Send alert for critical errors
if error_code in ["TokenExpired", "InsufficientPermissions"]:
send_admin_alert(error_code, message)
4. User-Friendly Messages
ERROR_MESSAGES = {
"InvalidApiKey": "Your API key is invalid. Please check your Settings.",
"TokenExpired": "Your account connection has expired. Please reconnect your account.",
"MediaDownloadFailed": "We couldn't access your media. Please check the URL.",
"RateLimitExceeded": "You're publishing too fast. Please wait a few minutes."
}
def get_user_message(error_code):
return ERROR_MESSAGES.get(error_code, "An error occurred. Please try again.")
5. Monitor Error Rates
from collections import Counter
error_counter = Counter()
def track_error(error_code):
error_counter[error_code] += 1
# Alert if error rate is high
if error_counter[error_code] > 10:
notify_admin(f"High error rate for {error_code}")
Debugging
Enable Verbose Logging
import logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
Inspect Full Response
response = requests.post(API_URL, headers=headers, json=data)
print("Status Code:", response.status_code)
print("Headers:", response.headers)
print("Body:", response.text)
Test Media URLs
# Test if media is accessible
curl -I https://example.com/image.jpg
# Should return:
# HTTP/2 200
# content-type: image/jpeg
# content-length: 123456
Validate JSON
import json
try:
data = json.loads(request_body)
except json.JSONDecodeError as e:
print(f"Invalid JSON: {e}")
Getting Help
If you're stuck:
- Check this error reference - Find your error code
- Review platform guides - See platform-specific requirements
- Check examples - Compare with working code
- Test in isolation - Try simplest possible request
- Check status pages - Verify platforms are operational
- Contact support - Provide error details and context
Next Steps
- Publishing API - Learn the publishing endpoint
- Examples - See error handling in practice
- Platform Guides - Platform-specific errors