Error Codes

Understanding and handling API errors

Error Codes

The CaneToad API uses standard HTTP status codes and returns consistent error responses to help you debug issues quickly.

Error Response Format

All error responses follow this structure:

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable message",
    "details": {
      // Additional context (optional)
    }
  }
}

HTTP Status Codes

CodeMeaning
200Success
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing token
403Forbidden - Valid token but insufficient permissions
404Not Found - Resource doesn't exist
429Too Many Requests - Rate limit exceeded
500Server Error - Internal error

Error Codes Reference

Authentication Errors

Request Errors

Rate Limiting Errors

Server Errors

Handling Errors in Code

JavaScript/TypeScript

interface ApiError {
  error: {
    code: string;
    message: string;
    details?: Record<string, unknown>;
  };
}

async function fetchApi(url: string, token: string) {
  const response = await fetch(url, {
    headers: { 'Authorization': `Bearer ${token}` }
  });

  if (!response.ok) {
    const error: ApiError = await response.json();
    
    switch (error.error.code) {
      case 'UNAUTHORIZED':
        throw new Error('Invalid API token. Please check your credentials.');
      case 'RATE_LIMITED':
        const resetAt = error.error.details?.reset_at as number;
        throw new Error(`Rate limited. Try again at ${new Date(resetAt * 1000)}`);
      case 'NOT_FOUND':
        throw new Error(`Resource not found: ${error.error.message}`);
      default:
        throw new Error(error.error.message);
    }
  }

  return response.json();
}

Python

import requests
from datetime import datetime

def fetch_api(url: str, token: str):
    response = requests.get(url, headers={'Authorization': f'Bearer {token}'})
    
    if not response.ok:
        error = response.json()['error']
        
        if error['code'] == 'UNAUTHORIZED':
            raise Exception('Invalid API token. Please check your credentials.')
        elif error['code'] == 'RATE_LIMITED':
            reset_at = datetime.fromtimestamp(error['details']['reset_at'])
            raise Exception(f"Rate limited. Try again at {reset_at}")
        elif error['code'] == 'NOT_FOUND':
            raise Exception(f"Resource not found: {error['message']}")
        else:
            raise Exception(error['message'])
    
    return response.json()

Debugging Tips

When debugging API issues, always check:

  1. The HTTP status code
  2. The error code in the response body
  3. The message and details for context
  4. Rate limit headers to ensure you're not being throttled