Skip to main content

Overview

An Error Response is returned when an API request fails. Most /v1/* endpoints return a standardized JSON error shape, but authentication and some middleware responses may use a simpler format. What Error Responses Include:
  • Human-readable error message
  • Optional suggestions for resolving the issue
  • Optional structured details (error code, usage/concurrency details, etc.)
  • HTTP status code indicating the error type

Fields

The API may return one of these common shapes:
  1. Standard endpoint errors
{
  "success": false,
  "error": {
    "message": "Something went wrong",
    "suggestion": "Optional suggestion"
  }
}
  1. Authentication errors
{
  "error": "API key required"
}
  1. Usage enforcement errors (minutes/concurrency)
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_MINUTES",
    "message": "No minutes remaining. Please purchase additional minutes or upgrade your plan."
  }
}
FieldTypeDescription
successbooleanPresent on most endpoint errors (false)
errorobject | stringError details (object for most endpoints; string for some auth/middleware responses)
error.messagestringHuman-readable error message (when error is an object)
error.suggestionstringOptional suggestion for resolving the issue
error.codestringOptional machine-readable error code (e.g. INSUFFICIENT_MINUTES)
error.detailsobjectOptional structured details (e.g. minutes/concurrency breakdown)

Examples

Bad Request (400)

{
  "success": false,
  "error": {
    "message": "Avatar ID is required",
    "suggestion": "Include avatar_id in the request body"
  }
}

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)

{
  "error": "API key required"
}

Validation Error (400)

{
  "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"
  }
}

HTTP Status Codes

Status CodeDescriptionWhen It Occurs
400Bad RequestMissing required fields, invalid data format, business logic violations
401UnauthorizedMissing or invalid API key
403ForbiddenUser doesn’t have permission to access the resource
404Not FoundSession, avatar, or other resource not found
409ConflictRequest conflicts with current state (e.g., resource already exists)
422Unprocessable EntityWell-formed request but contains semantic errors
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server-side error
502Bad GatewayInvalid response from upstream server
503Service UnavailableService temporarily unavailable

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) {
  const errorMessage =
    typeof data.error === 'string'
      ? data.error
      : data.error?.message || data.error || 'Request failed';

  console.error('Error:', errorMessage);

  const suggestion = typeof data.error === 'object' ? data.error?.suggestion : undefined;
  if (suggestion) console.log('Suggestion:', suggestion);
}

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

  • Suggestions are optional - not all errors include them
  • Success field is present on most /v1/* endpoint responses, but authentication failures may return { "error": "..." }
  • Error messages are human-readable and safe to display to users
  • HTTP status codes follow standard REST conventions