Skip to main content

Error Response Format

All API errors return a consistent JSON structure:
{
  "error": "Error Type",
  "message": "Human-readable error description",
  "details": {
    "field": "Additional context"
  }
}

HTTP Status Codes

2xx Success

200 OK
success
Request successful, data returned

4xx Client Errors

400 Bad Request
error
Invalid request parameters or malformed queryCommon causes:
  • Invalid parameter type (e.g., string instead of integer)
  • Parameter value out of range
  • Malformed query syntax
  • Missing required parameters
Example:
{
  "error": "Bad Request",
  "message": "Invalid value for 'limit' parameter",
  "details": {
    "parameter": "limit",
    "provided": "invalid",
    "expected": "integer (1-100)"
  }
}
401 Unauthorized
error
Missing or invalid API keyCommon causes:
  • Missing Authorization header
  • Invalid API key format
  • Revoked API key
  • Expired API key
Example:
{
  "error": "Unauthorized",
  "message": "Invalid or missing API key",
  "details": {
    "hint": "Include 'Authorization: Bearer YOUR_API_KEY' header"
  }
}
Solution: Include valid API key in Authorization header
403 Forbidden
error
Valid API key but insufficient permissionsCommon causes:
  • Plan doesn’t include requested feature
  • Endpoint requires higher tier
  • Resource access restricted
Example:
{
  "error": "Forbidden",
  "message": "Your current plan does not include access to this endpoint",
  "details": {
    "required_plan": "Pro",
    "current_plan": "Free",
    "upgrade_url": "https://api.pricingsaas.com/pricing"
  }
}
Solution: Upgrade to required plan or contact support
404 Not Found
error
Requested resource doesn’t existCommon causes:
  • Invalid company slug
  • Typo in resource identifier
  • Resource has been deleted
Example:
{
  "error": "Not Found",
  "message": "Company with slug 'invalid-slug' not found",
  "details": {
    "slug": "invalid-slug",
    "suggestion": "Use /api/companies?search=invalid to search"
  }
}
Solution: Verify resource identifier or use search endpoint
429 Too Many Requests
error
Rate limit exceededHeaders included:
  • X-RateLimit-Limit: Maximum requests allowed
  • X-RateLimit-Remaining: Requests remaining
  • X-RateLimit-Reset: Unix timestamp when limit resets
  • Retry-After: Seconds to wait before retrying
Example:
{
  "error": "Rate limit exceeded",
  "message": "You have exceeded your rate limit of 100 requests per hour",
  "details": {
    "limit": 100,
    "remaining": 0,
    "reset_at": "2024-01-15T11:00:00Z",
    "retry_after": 3600
  }
}
Solution: Wait for reset or upgrade to higher tier

5xx Server Errors

500 Internal Server Error
error
Unexpected server errorExample:
{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred",
  "details": {
    "request_id": "req_abc123",
    "timestamp": "2024-01-15T10:30:00Z"
  }
}
Solution: Retry after brief delay. Contact support if persistent with request_id
503 Service Unavailable
error
Temporary service disruptionExample:
{
  "error": "Service Unavailable",
  "message": "Service temporarily unavailable. Please retry.",
  "details": {
    "retry_after": 60
  }
}
Solution: Retry with exponential backoff. Check status page

Common Error Scenarios

Invalid API Key

Request
curl "https://api.pricingsaas.com/functions/v1/api/companies" \
  -H "Authorization: Bearer invalid_key"
Response (401)
{
  "error": "Unauthorized",
  "message": "Invalid or missing API key"
}

Invalid Parameter Type

Request
curl "https://api.pricingsaas.com/functions/v1/api/companies?limit=abc" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response (400)
{
  "error": "Bad Request",
  "message": "Invalid value for 'limit' parameter. Must be an integer between 1 and 100.",
  "details": {
    "parameter": "limit",
    "provided": "abc",
    "expected": "integer (1-100)"
  }
}

Out of Range Parameter

Request
curl "https://api.pricingsaas.com/functions/v1/api/companies?limit=500" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response (400)
{
  "error": "Bad Request",
  "message": "Parameter 'limit' exceeds maximum value",
  "details": {
    "parameter": "limit",
    "provided": 500,
    "max": 100
  }
}

Invalid Category

Request
curl "https://api.pricingsaas.com/functions/v1/api/companies?category=InvalidCategory" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response (400)
{
  "error": "Bad Request",
  "message": "Invalid category value",
  "details": {
    "parameter": "category",
    "provided": "InvalidCategory",
    "valid_values": [
      "Communication",
      "Productivity",
      "Development",
      "Marketing",
      "Sales",
      "Customer Support",
      "Finance",
      "HR"
    ]
  }
}

Company Not Found

Request
curl "https://api.pricingsaas.com/functions/v1/api/companies/nonexistent" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response (404)
{
  "error": "Not Found",
  "message": "Company with slug 'nonexistent' not found",
  "details": {
    "slug": "nonexistent",
    "suggestion": "Use /api/companies?search=nonexistent to search"
  }
}

Rate Limit Exceeded

Request
# 101st request in an hour on free tier
curl "https://api.pricingsaas.com/functions/v1/api/companies" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response (429)
{
  "error": "Rate limit exceeded",
  "message": "You have exceeded your rate limit of 100 requests per hour",
  "details": {
    "limit": 100,
    "remaining": 0,
    "reset_at": "2024-01-15T11:00:00Z",
    "retry_after": 3600
  }
}
Headers
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995200
Retry-After: 3600

Insufficient Permissions

Request
# Accessing enterprise-only endpoint with free tier
curl "https://api.pricingsaas.com/functions/v1/api/companies/advanced-analytics" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response (403)
{
  "error": "Forbidden",
  "message": "This endpoint requires an Enterprise plan",
  "details": {
    "required_plan": "Enterprise",
    "current_plan": "Free",
    "upgrade_url": "https://api.pricingsaas.com/pricing"
  }
}

Error Handling Best Practices

Check Status Codes

Always check HTTP status codes before processing responses:
const response = await fetch(url, {
  headers: { 'Authorization': `Bearer ${API_KEY}` }
});

if (!response.ok) {
  const error = await response.json();
  console.error(`API Error (${response.status}):`, error.message);
  throw new Error(error.message);
}

const data = await response.json();

Handle Specific Errors

Handle different error types appropriately:
try {
  const response = await fetch(url);
  const data = await response.json();

  if (!response.ok) {
    switch (response.status) {
      case 400:
        console.error('Invalid request:', data.details);
        break;
      case 401:
        console.error('Authentication failed');
        // Redirect to login or refresh credentials
        break;
      case 403:
        console.error('Insufficient permissions');
        // Show upgrade prompt
        break;
      case 404:
        console.error('Resource not found');
        // Show not found message
        break;
      case 429:
        const retryAfter = data.details.retry_after;
        console.log(`Rate limited. Retry in ${retryAfter}s`);
        // Implement retry logic
        break;
      case 500:
      case 503:
        console.error('Server error. Retrying...');
        // Implement retry with backoff
        break;
      default:
        console.error('Unexpected error:', data.message);
    }
  }
} catch (error) {
  console.error('Network error:', error);
}

Log Error Details

Always log full error context for debugging:
console.error('API Error:', {
  status: response.status,
  error: errorData.error,
  message: errorData.message,
  details: errorData.details,
  requestId: errorData.details?.request_id,
  timestamp: new Date().toISOString(),
  url: response.url
});

Implement Retry Logic

Retry transient errors with exponential backoff:
async function fetchWithRetry(url, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
      });

      // Retry on rate limit or server errors
      if (response.status === 429 || response.status >= 500) {
        const error = await response.json();
        const retryAfter = error.details?.retry_after || Math.pow(2, attempt);
        const delayMs = retryAfter * 1000;

        console.log(`Attempt ${attempt + 1} failed. Retrying in ${delayMs}ms`);
        await new Promise(resolve => setTimeout(resolve, delayMs));
        continue;
      }

      return response;

    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
    }
  }
}

Need Help?