> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agenthuman.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Response Object

> Schema definition for Error Response objects returned by the API

## 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

<ResponseField name="success" type="boolean">
  Always `false` for error responses
</ResponseField>

<ResponseField name="error" type="object">
  Error details object

  <Expandable title="Error Object Fields">
    <ResponseField name="message" type="string">
      Human-readable error message describing what went wrong
    </ResponseField>

    <ResponseField name="suggestion" type="string">
      Optional suggestion for resolving the issue (not present in all errors)
    </ResponseField>

    <ResponseField name="code" type="string">
      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
    </ResponseField>

    <ResponseField name="details" type="object | array">
      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
    </ResponseField>
  </Expandable>
</ResponseField>

## Error Response Formats

The API uses a consistent error format across all endpoints:

### 1. Standard Error

Most errors use this format:

```json theme={null}
{
  "success": false,
  "error": {
    "message": "Something went wrong",
    "suggestion": "Optional suggestion"
  }
}
```

### 2. Usage Enforcement Errors

Usage and billing-related errors include a machine-readable `code`:

```json theme={null}
{
  "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:

```json theme={null}
{
  "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:

```json theme={null}
{
  "success": false,
  "error": {
    "message": "Internal server error"
  }
}
```

## Field Reference

<Note>
  All error responses follow the structure defined in the Fields section above.
</Note>

## Examples

### Bad Request (400)

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

### Not Found (404)

```json theme={null}
{
  "success": false,
  "error": {
    "message": "Session not found"
  }
}
```

### Access Denied (403)

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

### Authentication Error (401)

```json theme={null}
{
  "success": false,
  "error": {
    "message": "API key required"
  }
}
```

### Validation Error (400) - Business Logic

```json theme={null}
{
  "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:

```json theme={null}
{
  "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:

```json theme={null}
{
  "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:

```json theme={null}
{
  "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                                                                                     |
| ----------- | --------------------- | -------------------------------------------------------------------------------------------------- |
| `400`       | Bad Request           | Missing required fields, invalid data format, field validation failures, business logic violations |
| `401`       | Unauthorized          | Missing or invalid API key, expired JWT token                                                      |
| `402`       | Payment Required      | Insufficient minutes remaining in account                                                          |
| `403`       | Forbidden             | User doesn't have permission to access the resource, invalid token                                 |
| `404`       | Not Found             | Session, avatar or other resource not found                                                        |
| `409`       | Conflict              | OAuth account already linked to another user                                                       |
| `429`       | Too Many Requests     | Rate limit exceeded                                                                                |
| `500`       | Internal Server Error | Unexpected server-side error                                                                       |
| `503`       | Service 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:

```javascript theme={null}
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

```javascript theme={null}
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

```javascript theme={null}
// 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
