The Buena.ai API uses conventional HTTP status codes and returns detailed error information to help you debug issues quickly.
All errors follow a consistent JSON format:
{
"error": true,
"code": "ERROR_CODE",
"message": "Human-readable error description",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"details": {
"field": "Additional context when applicable"
}
}
Fields
Field | Description |
---|
error | Always true for error responses |
code | Machine-readable error code |
message | Human-readable error description |
version | API version |
timestamp | ISO 8601 timestamp of the error |
details | Additional context (optional) |
HTTP Status Codes
2xx Success
200
OK - Request succeeded - 201
Created - Resource created - 204
No
Content - Request succeeded, no content
4xx Client Errors
400
Bad Request - Invalid request - 401
Unauthorized - Invalid API key
403
Forbidden - Insufficient permissions - 404
Not Found - Resource
not found - 429
Too Many Requests - Rate limited
5xx Server Errors
500
Internal Server Error - Server issue - 502
Bad Gateway - Upstream
error - 503
Service Unavailable - Temporary unavailability
Common Error Codes
Authentication Errors
UNAUTHORIZED (401)
{
"error": true,
"code": "UNAUTHORIZED",
"message": "Invalid API key",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z"
}
Causes:
- Missing
x-api-key
header
- Invalid API key format
- Expired API key
- Deactivated API key
PERMISSION_DENIED (403)
{
"error": true,
"code": "PERMISSION_DENIED",
"message": "Insufficient permissions",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"permissionHelp": {
"required": "linkedin:schedule",
"available": ["linkedin:read"],
"documentation": "https://docs.buena.ai/authentication"
}
}
Causes:
- API key lacks required permission
- Attempting to access restricted resource
Validation Errors
VALIDATION_ERROR (400)
{
"error": true,
"code": "VALIDATION_ERROR",
"message": "Invalid request data",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"details": {
"fields": {
"email": "Invalid email format",
"firstName": "Field is required"
}
}
}
Causes:
- Missing required fields
- Invalid field formats
- Invalid field values
INVALID_LINKEDIN_URL (400)
{
"error": true,
"code": "INVALID_LINKEDIN_URL",
"message": "Invalid LinkedIn profile URL format",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"details": {
"providedUrl": "https://example.com/profile",
"expectedFormat": "https://linkedin.com/in/username"
}
}
Rate Limiting Errors
RATE_LIMIT_EXCEEDED (429)
{
"error": true,
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"retryAfter": 45,
"rateLimitInfo": {
"limit": 60,
"remaining": 0,
"reset": 1640995245,
"window": "minute"
}
}
Resource Errors
NOT_FOUND (404)
{
"error": true,
"code": "NOT_FOUND",
"message": "Lead not found",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"details": {
"resource": "lead",
"id": "lead_abc123"
}
}
DUPLICATE_RESOURCE (409)
{
"error": true,
"code": "DUPLICATE_RESOURCE",
"message": "Lead with this email already exists",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"details": {
"field": "email",
"value": "john@example.com",
"existingId": "lead_xyz789"
}
}
Integration Errors
LINKEDIN_NOT_CONNECTED (400)
{
"error": true,
"code": "LINKEDIN_NOT_CONNECTED",
"message": "LinkedIn account not connected",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"details": {
"action": "Connect your LinkedIn account in the dashboard",
"dashboardUrl": "https://app.buena.ai/integrations/linkedin"
}
}
ENRICHMENT_CREDITS_EXHAUSTED (402)
{
"error": true,
"code": "ENRICHMENT_CREDITS_EXHAUSTED",
"message": "Insufficient enrichment credits",
"version": "2.0",
"timestamp": "2024-01-20T15:30:00Z",
"details": {
"remaining": 0,
"required": 5,
"upgradeUrl": "https://app.buena.ai/billing"
}
}
Error Handling Best Practices
Language-Specific Examples
JavaScript/TypeScript
interface APIError {
error: boolean;
code: string;
message: string;
version: string;
timestamp: string;
details?: any;
}
class BuenaAPIClient {
private apiKey: string;
constructor(apiKey: string) {
this.apiKey = apiKey;
}
async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
const response = await fetch(`https://api.buena.ai/api/v2${endpoint}`, {
...options,
headers: {
"x-api-key": this.apiKey,
"Content-Type": "application/json",
...options.headers,
},
});
const data = await response.json();
if (!response.ok) {
throw new BuenaAPIError(response.status, data);
}
return data;
}
}
class BuenaAPIError extends Error {
constructor(public status: number, public errorData: APIError) {
super(errorData.message);
this.name = "BuenaAPIError";
}
get code() {
return this.errorData.code;
}
get details() {
return this.errorData.details;
}
}
Python
import requests
from typing import Dict, Any, Optional
import time
class BuenaAPIError(Exception):
def __init__(self, status_code: int, error_data: Dict[str, Any]):
self.status_code = status_code
self.error_data = error_data
super().__init__(error_data.get('message', 'Unknown error'))
@property
def code(self) -> str:
return self.error_data.get('code', 'UNKNOWN')
@property
def details(self) -> Optional[Dict[str, Any]]:
return self.error_data.get('details')
class BuenaAPIClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = 'https://api.buena.ai/api/v2'
def request(
self,
endpoint: str,
method: str = 'GET',
json_data: Optional[Dict] = None,
max_retries: int = 3
) -> Dict[str, Any]:
headers = {
'x-api-key': self.api_key,
'Content-Type': 'application/json'
}
for attempt in range(max_retries):
try:
response = requests.request(
method=method,
url=f'{self.base_url}{endpoint}',
headers=headers,
json=json_data
)
if response.ok:
return response.json()
error_data = response.json()
error = BuenaAPIError(response.status_code, error_data)
# Handle specific error types
if error.code == 'RATE_LIMIT_EXCEEDED':
if attempt < max_retries - 1:
retry_after = error_data.get('retryAfter', 2 ** attempt)
time.sleep(retry_after)
continue
raise error
except requests.RequestException as e:
if attempt == max_retries - 1:
raise e
time.sleep(2 ** attempt)
Error Monitoring
Setting Up Alerts
class ErrorMonitor {
constructor(alertThreshold = 0.05) {
this.alertThreshold = alertThreshold; // 5% error rate
this.errorCounts = new Map();
this.totalRequests = 0;
}
trackRequest(isError, errorCode = null) {
this.totalRequests++;
if (isError) {
const count = this.errorCounts.get(errorCode) || 0;
this.errorCounts.set(errorCode, count + 1);
this.checkAlertThreshold();
}
}
checkAlertThreshold() {
const totalErrors = Array.from(this.errorCounts.values()).reduce(
(sum, count) => sum + count,
0
);
const errorRate = totalErrors / this.totalRequests;
if (errorRate >= this.alertThreshold) {
this.sendAlert(errorRate, this.errorCounts);
}
}
sendAlert(errorRate, errorCounts) {
console.error(`High error rate detected: ${(errorRate * 100).toFixed(2)}%`);
console.error("Error breakdown:", Object.fromEntries(errorCounts));
// Send to monitoring service (Datadog, New Relic, etc.)
}
}
Need Help?
If you’re experiencing persistent errors or need assistance:
When contacting support, please include:
- API key prefix (first 8 characters)
- Error response with timestamp
- Request details (endpoint, method, payload)
- Expected vs actual behavior