Skip to main content
When a request fails, the Avala API returns an appropriate HTTP status code along with a JSON body describing the error. Use the status code to determine the category of failure and the response body for specifics.

Standard Error Response

Most errors return a JSON object with a detail field:
{
  "detail": "A human-readable description of the error."
}

Validation Errors

Requests that fail input validation return a 400 status code with field-specific error details:
{
  "detail": {
    "name": ["This field is required."],
    "email": ["Enter a valid email address."]
  }
}
Each key corresponds to a request field, and the value is an array of error messages for that field.

Error Code Reference

Status CodeNameDescription
400Bad RequestThe request body is invalid, malformed, or missing required fields.
401UnauthorizedAuthentication failed — the API key is missing, invalid, or expired.
403ForbiddenThe authenticated key does not have permission to perform this action.
404Not FoundThe requested resource does not exist or has been deleted.
405Method Not AllowedThe HTTP method is not supported for this endpoint.
409ConflictThe request conflicts with the current state of the resource (e.g., duplicate name).
413Payload Too LargeThe request body exceeds the maximum allowed size.
429Too Many RequestsRate limit exceeded. Back off and retry after the window resets.
500Internal Server ErrorAn unexpected error occurred on the server.
503Service UnavailableThe API is temporarily offline for maintenance or under heavy load.

Detailed Error Descriptions

400 — Bad Request

The request is malformed or contains invalid data. Common causes:
  • Missing a required field in the request body
  • Sending an invalid data type (e.g., string where an integer is expected)
  • Malformed JSON in the request body
{
  "detail": {
    "name": ["This field is required."],
    "schedule": ["Invalid cron expression."]
  }
}
Remediation: Check the request body against the endpoint’s schema. Ensure all required fields are present and correctly typed.

401 — Unauthorized

Authentication failed. Common causes:
  • No X-Avala-Api-Key header included in the request
  • The API key is invalid or has been revoked
  • The API key has expired
{
  "detail": "Invalid API key."
}
Remediation: Verify your API key is correct and active. Generate a new key from Mission Control if needed. See Authentication.

403 — Forbidden

The API key is valid but lacks permission for the requested action. Common causes:
  • Attempting to access a resource owned by a different organization
  • Insufficient role or permission level for the operation
{
  "detail": "You do not have permission to perform this action."
}
Remediation: Confirm the resource belongs to your organization. Contact your team admin if you need elevated permissions.

404 — Not Found

The requested resource does not exist. Common causes:
  • The resource ID is incorrect or misspelled
  • The resource was previously deleted
  • The URL path is wrong
{
  "detail": "Not found."
}
Remediation: Verify the resource ID and endpoint path. List resources to confirm the ID exists.

405 — Method Not Allowed

The HTTP method is not supported on the endpoint. Common causes:
  • Sending a PATCH request to an endpoint that only supports GET and POST
  • Using DELETE on a resource that does not support deletion
{
  "detail": "Method \"PATCH\" not allowed."
}
Remediation: Check the API reference for the supported methods on the endpoint.

409 — Conflict

The request conflicts with the current state of a resource. Common causes:
  • Creating a resource with a name that already exists
  • Attempting a state transition that is not allowed (e.g., re-activating a completed run)
{
  "detail": "An agent with this name already exists."
}
Remediation: Change the conflicting field value, or fetch the existing resource and update it instead.

413 — Payload Too Large

The request body exceeds the maximum allowed size. Common causes:
  • Uploading a file that exceeds the size limit
  • Sending an excessively large JSON payload
{
  "detail": "Request body too large. Maximum size is 100MB."
}
Remediation: Reduce the payload size. For file uploads, compress the file or split it into smaller parts.

429 — Too Many Requests

You have exceeded the rate limit. Common causes:
  • Sending more than 100 requests per minute
  • Exceeding concurrent upload or export limits
{
  "detail": "Request was throttled. Expected available in 12 seconds."
}
The response includes rate limit headers:
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
Remediation: Wait until the rate limit window resets, then retry. Implement exponential backoff in your client.

500 — Internal Server Error

An unexpected error occurred on the server. Common causes:
  • A bug or transient failure in the Avala backend
{
  "detail": "Internal server error."
}
Remediation: Retry the request after a brief delay. If the error persists, contact support@avala.ai with the request details.

503 — Service Unavailable

The API is temporarily unable to handle requests. Common causes:
  • Scheduled maintenance
  • The service is under heavy load
{
  "detail": "Service temporarily unavailable. Please try again later."
}
Remediation: Wait and retry with exponential backoff. Check the Avala status page for incident updates.

Handling Errors

Implement retry logic with exponential backoff for transient errors (429, 500, 503). Do not retry client errors (400, 401, 403, 404).
Python
import time
import requests

def request_with_retry(method, url, headers, json=None, max_retries=3):
    """Make an API request with exponential backoff for transient errors."""
    retryable_status_codes = {429, 500, 503}

    for attempt in range(max_retries + 1):
        response = requests.request(
            method, url, headers=headers, json=json
        )

        if response.status_code not in retryable_status_codes:
            return response

        if attempt == max_retries:
            return response

        # Use Retry-After or X-RateLimit-Reset if available
        retry_after = response.headers.get("Retry-After")
        if retry_after:
            wait = int(retry_after)
        else:
            wait = 2 ** attempt  # 1s, 2s, 4s

        print(f"Request failed with {response.status_code}. "
              f"Retrying in {wait}s (attempt {attempt + 1}/{max_retries})...")
        time.sleep(wait)

    return response


# Usage
response = request_with_retry(
    method="GET",
    url="https://server.avala.ai/api/v1/agents",
    headers={"X-Avala-Api-Key": "avala_sk_your_api_key"},
)

if response.ok:
    data = response.json()
else:
    print(f"Error {response.status_code}: {response.json()['detail']}")