Skip to main content

Overview

An Error Response is returned when an API request fails. All endpoints return a standardized JSON error format. What Error Responses Include:
  • Human-readable error message
  • Optional suggestions for resolving the issue
  • Optional machine-readable error codes (for usage enforcement and billing errors)
  • Optional structured details (field validation, usage breakdowns)
  • HTTP status code indicating the error type

Fields

success
boolean
Always false for error responses
error
object
Error details object

Error Response Formats

The API uses a consistent error format across all endpoints:

1. Standard Error

Most errors use this format:
{
  "success": false,
  "error": {
    "message": "Something went wrong",
    "suggestion": "Optional suggestion"
  }
}

2. Usage Enforcement Errors

Usage and billing-related errors include a machine-readable code:
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_MINUTES",
    "message": "No minutes remaining. Please purchase additional minutes or upgrade your plan at https://app.agenthuman.com/settings/billing",
    "details": {
      "minutesRemaining": 0,
      "minutesUsed": 100
    }
  }
}
Error codes used:
  • MISSING_USER_ID - User ID required for operation
  • CONCURRENCY_LIMIT_EXCEEDED - Too many concurrent sessions
  • INSUFFICIENT_MINUTES - No minutes remaining in account
  • USAGE_CHECK_FAILED - Failed to verify usage limits
  • NO_SUBSCRIPTION - No active subscription found

3. Field Validation Errors

When request validation fails, the API returns detailed field-level errors:
{
  "success": false,
  "error": {
    "message": "Validation failed",
    "details": [
      { "field": "email", "message": "email must be a valid email" },
      { "field": "password", "message": "password must be at least 8 characters" }
    ]
  }
}

4. Unexpected Server Errors

When an unexpected error occurs, the global error handler returns:
{
  "success": false,
  "error": {
    "message": "Internal server error"
  }
}

Field Reference

All error responses follow the structure defined in the Fields section above.

Examples

Bad Request (400)

{
  "success": false,
  "error": {
    "message": "Avatar is required",
    "suggestion": "Provide a URL (https://...) or a base64-encoded image string (data:image/...;base64,...)"
  }
}

Not Found (404)

{
  "success": false,
  "error": {
    "message": "Session not found"
  }
}

Access Denied (403)

{
  "success": false,
  "error": {
    "message": "Access denied to this avatar",
    "suggestion": "You do not have permission to create sessions with this avatar"
  }
}

Authentication Error (401)

{
  "success": false,
  "error": {
    "message": "API key required"
  }
}

Validation Error (400) - Business Logic

{
  "success": false,
  "error": {
    "message": "Metadata must be a valid JSON object",
    "suggestion": "Metadata should be an object like {\"key\": \"value\"}, not an array or primitive"
  }
}

Validation Error (400) - Field-Level

When request validation fails (e.g., using Joi schemas), the API returns detailed field-level errors:
{
  "success": false,
  "error": {
    "message": "Validation failed",
    "details": [
      { "field": "email", "message": "email is required" },
      { "field": "display_name", "message": "display_name must be at least 1 character" }
    ]
  }
}

Usage Enforcement Error (402 / 429)

When usage limits are exceeded:
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_MINUTES",
    "message": "No minutes remaining. Please purchase additional minutes or upgrade your plan at https://app.agenthuman.com/settings/billing",
    "details": {
      "minutesRemaining": 0,
      "minutesUsed": 120,
      "monthlyAllowance": 100
    }
  }
}
Concurrency limit exceeded:
{
  "success": false,
  "error": {
    "code": "CONCURRENCY_LIMIT_EXCEEDED",
    "message": "You have reached your concurrent session limit.",
    "details": {
      "currentSessions": 5,
      "limit": 5
    }
  }
}

HTTP Status Codes

Status CodeDescriptionWhen It Occurs
400Bad RequestMissing required fields, invalid data format, field validation failures, business logic violations
401UnauthorizedMissing or invalid API key, expired JWT token
402Payment RequiredInsufficient minutes remaining in account
403ForbiddenUser doesn’t have permission to access the resource, invalid token
404Not FoundSession, avatar or other resource not found
409ConflictOAuth account already linked to another user
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server-side error
503Service UnavailableService temporarily unavailable, external service not ready

Rate Limiting

When rate limited (429 status code), you may receive headers indicating:
  • RateLimit-Limit: Maximum number of requests allowed
  • RateLimit-Remaining: Requests remaining in current window
  • RateLimit-Reset: Seconds until the window resets
  • Retry-After: Seconds to wait before making another request

Error Handling Best Practices

Always Check Response Status

Check both the HTTP status code and the success field:
const response = await fetch('https://api.agenthuman.com/v1/sessions/sess_123', {
  headers: { 'x-api-key': 'your-api-key' }
});

const data = await response.json();

if (!response.ok || !data.success) {
  // All errors now use standardized format
  const errorMessage = data.error?.message || 'Request failed';
  console.error('Error:', errorMessage);

  // Check for suggestions
  if (data.error?.suggestion) {
    console.log('Suggestion:', data.error.suggestion);
  }
  
  // Check for error code (usage/billing errors)
  if (data.error?.code) {
    console.log('Error code:', data.error.code);
  }
  
  // Check for field-level validation errors
  if (data.error?.details && Array.isArray(data.error.details)) {
    console.log('Field errors:');
    data.error.details.forEach(err => {
      console.log(`  - ${err.field}: ${err.message}`);
    });
  }
}

Implement Retry Logic for Rate Limits

async function apiCall(url, options, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const response = await fetch(url, options);
    
    if (response.status === 429) {
      // Exponential backoff
      const delay = 1000 * Math.pow(2, i);
      await new Promise(resolve => setTimeout(resolve, delay));
      continue;
    }
    
    return response;
  }
  
  throw new Error('Max retries exceeded');
}

Don’t Retry 4xx Errors

// Only retry on network errors or 5xx server errors
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
  // Client error - don't retry, fix the request
  throw new Error(data.error);
}

Notes

  • All errors use the standardized format with success: false and error as an object
  • Error codes are only used for usage enforcement and billing errors
  • Suggestions are optional - not all errors include them
  • Error messages are human-readable and safe to display to users
  • HTTP status codes follow standard REST conventions