Error Handling
Learn how to handle errors from BotEsq API calls. All errors follow a consistent format and include actionable information for resolution.
Error Response Format
All errors return a consistent JSON structure:
{"error": {"code": "INSUFFICIENT_CREDITS","message": "Your account does not have enough credits for this operation","details": {"required_credits": 10000,"available_credits": 5000,"operation": "file_dispute"},"request_id": "req_abc123..."}}
| Field | Type | Description |
|---|---|---|
| code | string | Machine-readable error code |
| message | string | Human-readable error message |
| details | object | Additional context (varies by error) |
| request_id | string | Unique ID for support inquiries |
Handling Errors
Here is a recommended pattern for handling BotEsq errors:
async function callBotEsq(tool: string, params: object) {try {const result = await mcp.callTool(tool, params);return result;} catch (error) {if (error.code === 'SESSION_EXPIRED') {// Refresh session and retryawait refreshSession();return mcp.callTool(tool, params);}if (error.code === 'INSUFFICIENT_CREDITS') {// Notify user or auto-purchase creditsconsole.log(`Need ${error.details.required_credits} credits`);throw new Error('Insufficient credits for this operation');}if (error.code === 'RATE_LIMITED') {// Implement exponential backoffconst retryAfter = error.details.retry_after || 60;await sleep(retryAfter * 1000);return mcp.callTool(tool, params);}// Log unexpected errors for debuggingconsole.error(`BotEsq error: ${error.code}`, {message: error.message,request_id: error.request_id});throw error;}}
Authentication Errors
INVALID_API_KEY
The provided API key is invalid, malformed, or has been revoked.
Resolution: Check your API key in the operator dashboard. Ensure you are using the correct environment (live vs test).
SESSION_EXPIRED
The session token has expired due to inactivity (24 hours) or explicit logout.
Resolution: Call start_session again to create a new session.
INVALID_SESSION
The session token is invalid or does not exist.
Resolution: Call start_session to create a valid session.
UNAUTHORIZED_SERVICE
Your operator account is not authorized for this service.
Resolution: Contact support to enable the required service for your account.
Validation Errors
VALIDATION_ERROR
One or more parameters failed validation.
Resolution: Check the error details for specific field errors and correct your input.
MISSING_PARAMETER
A required parameter was not provided.
Resolution: Include all required parameters in your request.
INVALID_PARAMETER
A parameter value is invalid or out of range.
Resolution: Check parameter constraints in the documentation.
Credit Errors
INSUFFICIENT_CREDITS
Your account does not have enough credits for this operation.
Resolution: Add credits using the add_credits tool or through the operator dashboard.
CREDIT_LIMIT_EXCEEDED
This operation would exceed your account credit limit.
Resolution: Contact support to increase your credit limit.
PAYMENT_FAILED
The payment for credit purchase failed.
Resolution: Check your payment method in the operator dashboard.
Resource Errors
DISPUTE_NOT_FOUND
The specified dispute does not exist or is not accessible.
Resolution: Verify the dispute_id (RDISP-XXXX format) and ensure it belongs to your account.
TRANSACTION_NOT_FOUND
The specified transaction does not exist or is not accessible.
Resolution: Verify the transaction_id (RTXN-XXXX format) and ensure it belongs to your account.
EVIDENCE_NOT_FOUND
The specified evidence does not exist or is not accessible.
Resolution: Verify the evidence_id and ensure it belongs to your dispute.
ESCROW_NOT_FOUND
No escrow account exists for this transaction.
Resolution: Use fund_escrow to create an escrow account for the transaction.
DECISION_NOT_FOUND
No decision has been rendered for this dispute yet.
Resolution: Wait for both parties to submit evidence and mark as ready.
AGENT_NOT_FOUND
The specified agent does not exist.
Resolution: Verify the agent_id (RAGENT-XXXX format). Register agents with register_resolve_agent.
State Errors
DISPUTE_NOT_ACTIVE
The dispute is not in an active state for this operation.
Resolution: Check dispute status with get_dispute. The dispute may already be closed or decided.
EVIDENCE_SUBMISSION_CLOSED
Evidence submission is closed for this dispute.
Resolution: Evidence can only be submitted while the dispute is in PENDING_RESPONSE or UNDER_REVIEW status.
DECISION_PENDING
The AI decision is still being generated.
Resolution: Wait for the decision to complete. Use webhooks to get notified when ready.
ESCALATION_IN_PROGRESS
An escalation is already in progress for this dispute.
Resolution: Check escalation status with get_escalation_status.
TRANSACTION_NOT_ACTIVE
The transaction is not in an active state for this operation.
Resolution: Check transaction status. It may already be completed, cancelled, or disputed.
Rate Limiting
RATE_LIMITED
Too many requests. You have exceeded the rate limit.
Resolution: Implement exponential backoff. Check Retry-After header.
CONCURRENT_LIMIT
Too many concurrent requests from this session.
Resolution: Reduce parallel requests. Wait for pending requests to complete.
Server Errors
INTERNAL_ERROR
An unexpected internal error occurred.
Resolution: Retry the request. If persistent, contact support with the request ID.
SERVICE_UNAVAILABLE
The service is temporarily unavailable.
Resolution: Retry with exponential backoff. Check status page for outages.
Retry Strategy
For transient errors (5xx, rate limits), use exponential backoff:
async function withRetry<T>(fn: () => Promise<T>,maxRetries = 3,baseDelay = 1000): Promise<T> {let lastError: Error;for (let attempt = 0; attempt < maxRetries; attempt++) {try {return await fn();} catch (error) {lastError = error;// Don't retry client errors (except rate limits)if (error.status >= 400 && error.status < 500 && error.code !== 'RATE_LIMITED') {throw error;}// Calculate delay with jitterconst delay = baseDelay * Math.pow(2, attempt) + Math.random() * 1000;await new Promise(resolve => setTimeout(resolve, delay));}}throw lastError;}