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
Always false for error responses
Error details object Human-readable error message describing what went wrong
Optional suggestion for resolving the issue (not present in all errors)
Optional machine-readable error code. Only present for usage enforcement and billing errors. Possible codes:
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
Optional structured details. Format varies by error type:
Usage/Billing errors : Object with usage breakdown (minutesRemaining, minutesUsed, etc.)
Field validation errors : Array of objects with field and message properties
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 Code Description When It Occurs 400Bad Request Missing required fields, invalid data format, field validation failures, business logic violations 401Unauthorized Missing or invalid API key, expired JWT token 402Payment Required Insufficient minutes remaining in account 403Forbidden User doesn’t have permission to access the resource, invalid token 404Not Found Session, avatar or other resource not found 409Conflict OAuth account already linked to another user 429Too Many Requests Rate limit exceeded 500Internal Server Error Unexpected server-side error 503Service Unavailable Service 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