Skip to main content

Error Structure

When an error occurs, the API returns a response with the following structure:
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Error description",
    "details": {
      // Additional information when available
    }
  }
}

Error Codes

Authentication Errors

Status: 401The API key is missing, invalid, or expired.
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}
Solution: Verify that the key is correct and not expired.
Status: 403The key doesn’t have permission for this resource.
{
  "error": {
    "code": "FORBIDDEN",
    "message": "You don't have permission to access this resource"
  }
}
Solution: Check your key permissions in the dashboard.

Validation Errors

Status: 400The submitted data is invalid.
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": {
      "field": "email",
      "reason": "Invalid email format"
    }
  }
}
Solution: Fix the fields indicated in details.
Status: 400A required field was not sent.
{
  "error": {
    "code": "MISSING_FIELD",
    "message": "Required field missing",
    "details": {
      "field": "phone"
    }
  }
}
Solution: Include the required field in the request.

Resource Errors

Status: 404The requested resource doesn’t exist.
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Lead not found"
  }
}
Solution: Verify that the ID is correct.
Status: 409A resource with the same data already exists.
{
  "error": {
    "code": "ALREADY_EXISTS",
    "message": "A lead with this phone number already exists"
  }
}
Solution: Use the update endpoint or use different data.

Rate Limit Errors

Status: 429Too many requests in a short time.
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests",
    "details": {
      "retry_after": 60
    }
  }
}
Solution: Wait for the time indicated in retry_after (seconds).

Implementing Retry Logic

async function requestWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);

      if (response.status === 429) {
        const data = await response.json();
        const retryAfter = data.error?.details?.retry_after || 60;
        console.log(`Rate limited. Retrying in ${retryAfter}s...`);
        await new Promise(r => setTimeout(r, retryAfter * 1000));
        continue;
      }

      if (response.status >= 500) {
        const delay = Math.pow(2, attempt) * 1000;
        console.log(`Server error. Retrying in ${delay}ms...`);
        await new Promise(r => setTimeout(r, delay));
        continue;
      }

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

      const delay = Math.pow(2, attempt) * 1000;
      await new Promise(r => setTimeout(r, delay));
    }
  }
}

Best Practices

Always Check Status

Never assume the request was successful. Always check the HTTP code.

Implement Retry

For 5xx and 429 errors, implement retry with exponential backoff.

Log Errors

Record errors for debugging and monitoring.

Handle Specific Cases

Implement specific handling for each error type.