Skip to main content

Error Response Format

All API errors return a consistent JSON structure:
{
  "error": "Human-readable error message",
  "code": "MACHINE_READABLE_CODE",
  "status": 400,
  "details": {
    "field": "Additional context when applicable"
  }
}

HTTP Status Codes

The Stanna API uses standard HTTP status codes:
Status CodeMeaningDescription
200SuccessRequest completed successfully
400Bad RequestInvalid request parameters or format
401UnauthorizedMissing or invalid API key
403ForbiddenValid API key but insufficient permissions
404Not FoundResource or endpoint doesn’t exist
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error (contact support)
502Bad GatewayTemporary server issue
503Service UnavailableMaintenance or temporary outage

Common Error Codes

Authentication Errors

AUTH_MISSING_KEY

Status: 401
{
  "error": "API key is required",
  "code": "AUTH_MISSING_KEY",
  "status": 401
}
Solution: Include your API key in the Authorization header.

AUTH_INVALID_KEY

Status: 401
{
  "error": "Invalid API key format or expired key",
  "code": "AUTH_INVALID_KEY",
  "status": 401
}
Solution: Check your API key format and ensure it hasn’t been deleted.

AUTH_WORKSPACE_MISMATCH

Status: 403
{
  "error": "API key does not have access to this workspace",
  "code": "AUTH_WORKSPACE_MISMATCH",
  "status": 403
}
Solution: Verify the workspaceId parameter matches your API key’s workspace.

Request Errors

VALIDATION_ERROR

Status: 400
{
  "error": "Invalid request parameters",
  "code": "VALIDATION_ERROR",
  "status": 400,
  "details": {
    "workspaceId": "workspaceId is required",
    "windowDays": "windowDays must be between 1 and 365"
  }
}
Solution: Check the required parameters and their valid ranges.

RESOURCE_NOT_FOUND

Status: 404
{
  "error": "Client not found",
  "code": "RESOURCE_NOT_FOUND",
  "status": 404,
  "details": {
    "resource": "client",
    "id": "client_123"
  }
}
Solution: Verify the resource ID exists in your workspace.

INVALID_WORKSPACE

Status: 404
{
  "error": "Workspace not found or inactive",
  "code": "INVALID_WORKSPACE",
  "status": 404,
  "details": {
    "workspaceId": "nonexistent.com"
  }
}
Solution: Check your workspace ID (domain) is correct and active.

Rate Limiting Errors

RATE_LIMIT_EXCEEDED

Status: 429
{
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED",
  "status": 429,
  "details": {
    "limit": 100,
    "window": "1 minute",
    "retryAfter": 45
  }
}
Solution: Wait before retrying or implement exponential backoff.

Data Errors

DATA_NOT_READY

Status: 404
{
  "error": "Metrics data is still being processed",
  "code": "DATA_NOT_READY",
  "status": 404,
  "details": {
    "estimatedReadyAt": "2024-02-01T10:30:00Z"
  }
}
Solution: Wait for data processing to complete, then retry.

INTEGRATION_NOT_CONNECTED

Status: 400
{
  "error": "Google integration is not connected",
  "code": "INTEGRATION_NOT_CONNECTED",
  "status": 400,
  "details": {
    "provider": "google",
    "connectUrl": "https://app.gostanna.com/integrations"
  }
}
Solution: Connect the required integration through your dashboard.

INSUFFICIENT_DATA

Status: 404
{
  "error": "Not enough data to generate metrics",
  "code": "INSUFFICIENT_DATA", 
  "status": 404,
  "details": {
    "minimumClients": 3,
    "currentClients": 1
  }
}
Solution: Add more clients or wait for more interaction data.

Server Errors

INTERNAL_ERROR

Status: 500
{
  "error": "An internal server error occurred",
  "code": "INTERNAL_ERROR",
  "status": 500,
  "details": {
    "requestId": "req_abc123"
  }
}
Solution: Contact support with the request ID.

INTEGRATION_ERROR

Status: 502
{
  "error": "External service temporarily unavailable",
  "code": "INTEGRATION_ERROR",
  "status": 502,
  "details": {
    "service": "google",
    "retryAfter": 300
  }
}
Solution: Retry after the specified delay.

Error Handling Best Practices

1. Check Status Codes

Always check the HTTP status code before parsing the response:
const response = await fetch(url, options);

if (!response.ok) {
  const error = await response.json();
  console.error(`API Error: ${error.code} - ${error.error}`);
  return;
}

const data = await response.json();

2. Implement Retry Logic

For temporary errors (429, 500, 502, 503), implement exponential backoff:
async function apiCallWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      
      if (response.ok) {
        return await response.json();
      }
      
      // Don't retry client errors (4xx except 429)
      if (response.status >= 400 && response.status < 500 && response.status !== 429) {
        throw new Error(`Client error: ${response.status}`);
      }
      
      // Calculate delay: 1s, 2s, 4s
      const delay = Math.pow(2, attempt) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
      
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
    }
  }
}

3. Handle Rate Limits

Respect rate limit headers and implement appropriate delays:
if (response.status === 429) {
  const retryAfter = response.headers.get('Retry-After');
  const delay = retryAfter ? parseInt(retryAfter) * 1000 : 60000;
  
  console.log(`Rate limited. Retrying after ${delay}ms`);
  await new Promise(resolve => setTimeout(resolve, delay));
  
  // Retry the request
}

4. Log Errors Appropriately

Log enough information for debugging without exposing sensitive data:
function logApiError(error, context) {
  console.error('API Error:', {
    code: error.code,
    status: error.status,
    message: error.error,
    endpoint: context.url,
    timestamp: new Date().toISOString(),
    // Don't log API keys or sensitive data
  });
}

5. Provide User-Friendly Messages

Convert technical error codes into user-friendly messages:
function getUserFriendlyMessage(errorCode) {
  const messages = {
    'AUTH_INVALID_KEY': 'Your API key is invalid. Please check your settings.',
    'RATE_LIMIT_EXCEEDED': 'Too many requests. Please wait a moment and try again.',
    'DATA_NOT_READY': 'Your data is still being processed. Please try again in a few minutes.',
    'INTEGRATION_NOT_CONNECTED': 'Please connect your integrations first.',
    'INSUFFICIENT_DATA': 'More client data is needed to generate insights.'
  };
  
  return messages[errorCode] || 'An unexpected error occurred. Please try again.';
}

Rate Limiting Details

The API enforces the following rate limits:
Limit TypeThresholdWindow
Per API Key100 requests1 minute
Per Workspace10,000 requests1 day
Bulk Operations10 requests1 minute

Rate Limit Headers

All responses include rate limiting information:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95  
X-RateLimit-Reset: 1643723400

Handling Rate Limits

When you hit a rate limit, the API returns:
{
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED", 
  "status": 429,
  "details": {
    "limit": 100,
    "remaining": 0,
    "resetAt": "2024-02-01T10:30:00Z",
    "retryAfter": 45
  }
}
Wait for the retryAfter seconds before making another request.

Getting Help

If you encounter errors not covered here:
  1. Check your API key and workspace ID
  2. Verify the endpoint URL and parameters
  3. Test with a simple cURL command
  4. Check our status page for known issues
  5. Contact support at support@gostanna.com with the error code and request details