Error Codes

Complete reference for VAP API error handling

HTTP Status Codes

VAP REST API uses standard HTTP status codes to indicate success or failure.

Code Name Description Resolution
400 Bad Request Invalid input (empty description, invalid task type) Check request body parameters
401 Unauthorized Missing or invalid API key Include valid Bearer token
403 Forbidden Tier limit exceeded or agent paused Upgrade tier or contact support
404 Not Found Task or resource doesn't exist Verify task_id or endpoint URL
409 Conflict Duplicate idempotency key Use unique key per request
422 Unprocessable Entity Valid JSON but invalid parameters Check parameter constraints
429 Too Many Requests Rate limit exceeded Wait and retry with exponential backoff
500 Internal Server Error Server error Retry request, contact support if persists
503 Service Unavailable Maintenance or system overload Retry after delay (check Retry-After header)

Error Response Format

All errors return a structured JSON response:

{
  "error": {
    "code": "insufficient_balance",
    "message": "Not enough balance for this task",
    "details": {
      "required": "0.18",
      "available": "0.05"
    }
  }
}

Common Error Codes

Application-level error codes in the error.code field:

error.code HTTP Meaning
invalid_api_key 401 API key not found or revoked
insufficient_balance 403 Balance less than estimated cost
tier_limit_exceeded 403 Task cost exceeds tier maximum
agent_paused 403 Circuit breaker triggered, agent paused
invalid_task_type 400 Unsupported task type
invalid_description 400 Empty or missing description parameter
task_not_found 404 Task ID doesn't exist or not owned by agent
rate_limit_exceeded 429 Too many requests in time window
provider_not_allowed 403 Provider unavailable for current tier

Error Handling Examples

Insufficient Balance

{
  "error": {
    "code": "insufficient_balance",
    "message": "Not enough balance for this task",
    "details": {
      "required": "0.18",
      "available": "0.05",
      "shortfall": "0.13"
    }
  }
}

Tier Limit Exceeded

{
  "error": {
    "code": "tier_limit_exceeded",
    "message": "Task cost exceeds tier limit",
    "details": {
      "task_cost": "5.00",
      "tier_limit": "1.00",
      "current_tier": 1,
      "required_tier": 2
    }
  }
}

Agent Paused (Circuit Breaker)

{
  "error": {
    "code": "agent_paused",
    "message": "Agent is paused due to anomaly detection",
    "details": {
      "reason": "Spend spike detected (3x average)",
      "paused_at": "2026-01-09T12:00:00Z",
      "contact": "support@vapagent.com"
    }
  }
}

Rate Limit Exceeded

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded",
    "details": {
      "retry_after": 30,
      "limit": 60,
      "window": "1 minute"
    }
  }
}

Best Practices

1. Always Check HTTP Status First

if response.status_code == 200:
    # Success
    result = response.json()
elif response.status_code == 401:
    # Invalid API key
    raise AuthenticationError("Check API key")
elif response.status_code == 403:
    # Check error.code for specific reason
    error = response.json()["error"]
    if error["code"] == "insufficient_balance":
        # Deposit more funds
        ...
elif response.status_code == 429:
    # Rate limited, wait and retry
    retry_after = response.json()["error"]["details"]["retry_after"]
    time.sleep(retry_after)

2. Implement Exponential Backoff

For 429 and 500 errors, use exponential backoff:

import time

def request_with_retry(url, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(url, ...)

        if response.status_code == 200:
            return response.json()
        elif response.status_code == 429:
            retry_after = response.json()["error"]["details"].get("retry_after", 1)
            wait = retry_after * (2 ** attempt)
            time.sleep(wait)
        elif response.status_code >= 500:
            wait = 2 ** attempt
            time.sleep(wait)
        else:
            raise APIError(response.json()["error"])

    raise MaxRetriesExceeded()

3. Handle Circuit Breaker

If agent is paused, contact support:

if error["code"] == "agent_paused":
    reason = error["details"]["reason"]
    contact = error["details"]["contact"]

    logger.error(f"Agent paused: {reason}")
    logger.error(f"Contact: {contact}")

    # Alert monitoring system
    # Contact support@vapagent.com

Need Help?

If you encounter persistent errors: