Skip to main content

Overview

The PricingSaaS Intelligence API uses standard HTTP status codes and returns detailed error messages to help you diagnose and fix issues quickly.

HTTP Status Codes

The API returns these status codes:
200 OK
success
Request successful, data returned
400 Bad Request
error
Invalid request parameters or malformed query
401 Unauthorized
error
Missing or invalid API key
403 Forbidden
error
Valid API key but insufficient permissions
404 Not Found
error
Resource not found (e.g., invalid company slug)
429 Too Many Requests
error
Rate limit exceeded
500 Internal Server Error
error
Server error - contact support if persistent
503 Service Unavailable
error
Temporary service disruption - retry with backoff

Error Response Format

All errors return a consistent JSON structure:
{
  "error": "Error category",
  "message": "Human-readable error description",
  "details": {
    "field": "Additional context (optional)"
  }
}

Common Errors

400 Bad Request

Invalid or malformed request parameters. Example:
curl "https://api.pricingsaas.com/functions/v1/api/companies?limit=invalid" \
  -H "Authorization: Bearer $API_KEY"
Response:
{
  "error": "Bad Request",
  "message": "Invalid value for 'limit' parameter. Must be an integer between 1 and 100.",
  "details": {
    "parameter": "limit",
    "provided": "invalid",
    "expected": "integer (1-100)"
  }
}
Solutions:
  • Validate input parameters before making requests
  • Check parameter types (string, integer, etc.)
  • Ensure values are within acceptable ranges
function validateLimit(limit) {
  const num = parseInt(limit);
  if (isNaN(num) || num < 1 || num > 100) {
    throw new Error('Limit must be between 1 and 100');
  }
  return num;
}

const limit = validateLimit(userInput);

401 Unauthorized

Missing or invalid API key. Example:
curl "https://api.pricingsaas.com/functions/v1/api/companies"
# Missing Authorization header
Response:
{
  "error": "Unauthorized",
  "message": "Invalid or missing API key",
  "details": {
    "hint": "Include 'Authorization: Bearer YOUR_API_KEY' header"
  }
}
Solutions:
  • Ensure API key is included in Authorization header
  • Verify API key format: Bearer YOUR_API_KEY
  • Check API key hasn’t been revoked
  • Regenerate API key if necessary
async function fetchWithAuth(url) {
  const apiKey = process.env.PRICINGSAAS_API_KEY;

  if (!apiKey) {
    throw new Error('API key not configured');
  }

  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${apiKey}`
    }
  });

  if (response.status === 401) {
    throw new Error('Invalid API key. Please check your credentials.');
  }

  return response;
}

403 Forbidden

Valid API key but insufficient permissions. Response:
{
  "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"
  }
}
Solutions:
  • Upgrade to a plan that includes the feature
  • Contact support for enterprise features
  • Use alternative endpoints available in your plan

404 Not Found

Requested resource doesn’t exist. Example:
curl "https://api.pricingsaas.com/functions/v1/api/companies/nonexistent-slug" \
  -H "Authorization: Bearer $API_KEY"
Response:
{
  "error": "Not Found",
  "message": "Company with slug 'nonexistent-slug' not found",
  "details": {
    "slug": "nonexistent-slug",
    "suggestion": "Use /api/companies?search=nonexistent to search"
  }
}
Solutions:
  • Verify the resource identifier (slug, ID) is correct
  • Use search endpoint to find the correct identifier
  • Check for typos in the slug
async function getCompany(slug) {
  const response = await fetch(
    `https://api.pricingsaas.com/functions/v1/api/companies/${slug}`,
    {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    }
  );

  if (response.status === 404) {
    // Try searching instead
    const searchResponse = await fetch(
      `https://api.pricingsaas.com/functions/v1/api/companies?search=${slug}`,
      {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
      }
    );

    const data = await searchResponse.json();

    if (data.data.length > 0) {
      return data.data[0]; // Return first match
    }

    throw new Error(`Company '${slug}' not found`);
  }

  return response.json();
}

429 Too Many Requests

Rate limit exceeded. Response:
{
  "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:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995200
Retry-After: 3600
Solutions:
  • Wait for rate limit to reset
  • Implement exponential backoff
  • Cache responses to reduce requests
  • Upgrade to Pro tier for higher limits
See Rate Limits for detailed guidance.

500 Internal Server Error

Server-side error. Response:
{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred",
  "details": {
    "request_id": "req_abc123",
    "timestamp": "2024-01-15T10:30:00Z"
  }
}
Solutions:
  • Retry the request after a short delay
  • If persistent, contact support with request_id
  • Check API status page for known issues

503 Service Unavailable

Temporary service disruption. Response:
{
  "error": "Service Unavailable",
  "message": "Service temporarily unavailable. Please retry.",
  "details": {
    "retry_after": 60
  }
}
Solutions:
  • Retry with exponential backoff
  • Check API status page
  • Implement circuit breaker pattern

Error Handling Patterns

Basic Error Handling

async function fetchCompanies() {
  try {
    const response = await fetch(
      'https://api.pricingsaas.com/functions/v1/api/companies',
      {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
      }
    );

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.message);
    }

    return response.json();
  } catch (error) {
    console.error('API Error:', error.message);
    throw error;
  }
}

Advanced Error Handling

class APIError extends Error {
  constructor(status, error, message, details) {
    super(message);
    this.status = status;
    this.error = error;
    this.details = details;
  }
}

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

  if (!response.ok) {
    const errorData = await response.json();
    throw new APIError(
      response.status,
      errorData.error,
      errorData.message,
      errorData.details
    );
  }

  return response.json();
}

// Usage
try {
  const data = await fetchWithErrorHandling(url);
} catch (error) {
  if (error instanceof APIError) {
    switch (error.status) {
      case 400:
        console.error('Invalid request:', error.details);
        break;
      case 401:
        console.error('Authentication failed. Check your API key.');
        // Redirect to login or refresh credentials
        break;
      case 429:
        const retryAfter = error.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('API Error:', error.message);
    }
  } else {
    console.error('Network error:', error);
  }
}

Retry 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}` }
      });

      if (response.status === 429 || response.status >= 500) {
        const retryAfter = response.headers.get('Retry-After') || Math.pow(2, attempt);
        const delayMs = parseInt(retryAfter) * 1000;

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

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.message);
      }

      return response.json();

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

Best Practices

Never assume success. Always check the HTTP status code before processing the response.
Log full error details including request_id for debugging:
console.error('API Error:', {
  status: response.status,
  error: errorData.error,
  message: errorData.message,
  requestId: errorData.details?.request_id,
  timestamp: new Date().toISOString()
});
Automatically retry transient errors (429, 500, 503) with exponential backoff.
Show meaningful error messages to users:
if (error.status === 401) {
  showMessage('Please check your API credentials');
} else if (error.status === 429) {
  showMessage('Too many requests. Please try again later.');
} else {
  showMessage('Something went wrong. Please try again.');
}
Track error rates to identify issues early:
const errorMetrics = {
  total: 0,
  byStatus: {}
};

function trackError(status) {
  errorMetrics.total++;
  errorMetrics.byStatus[status] = (errorMetrics.byStatus[status] || 0) + 1;
}

Testing Error Handling

Test your error handling with these patterns:
// Test 401 Unauthorized
await fetch(url, {
  headers: { 'Authorization': 'Bearer invalid_key' }
});

// Test 400 Bad Request
await fetch(url + '?limit=invalid');

// Test 404 Not Found
await fetch('https://api.pricingsaas.com/functions/v1/api/companies/nonexistent');

// Test 429 Rate Limit (make 101 requests quickly on free tier)
for (let i = 0; i < 101; i++) {
  await fetch(url, { headers: { 'Authorization': `Bearer ${API_KEY}` } });
}

Need Help?