Documentation Index
Fetch the complete documentation index at: https://avala.ai/docs/llms.txt
Use this file to discover all available pages before exploring further.
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."
}
Some endpoints return structured errors with a machine-readable code and a link to the relevant documentation:
{
"detail": "Project approval requires a PRO or ENTERPRISE plan.",
"code": "plan_insufficient",
"doc_url": "https://docs.avala.ai/api/errors#plan_insufficient"
}
Use the code field for programmatic error handling in your pipeline. The detail field is human-readable and may change between versions.
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 Code | Name | Description |
|---|
400 | Bad Request | The request body is invalid, malformed, or missing required fields. |
401 | Unauthorized | Authentication failed — the API key is missing, invalid, or expired. |
403 | Forbidden | The authenticated key does not have permission to perform this action. |
404 | Not Found | The requested resource does not exist or has been deleted. |
405 | Method Not Allowed | The HTTP method is not supported for this endpoint. |
409 | Conflict | The request conflicts with the current state of the resource (e.g., duplicate name). |
413 | Payload Too Large | The request body exceeds the maximum allowed size. |
429 | Too Many Requests | Rate limit exceeded. Back off and retry after the window resets. |
500 | Internal Server Error | An unexpected error occurred on the server. |
503 | Service Unavailable | The 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
- API key is missing a required scope
- Organization plan does not include the requested feature
{
"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.
Structured Error Codes
Some 403 responses include a machine-readable code for programmatic handling:
plan_insufficient — Your organization’s plan does not support this action. Upgrade to PRO or ENTERPRISE to access this feature.
{
"detail": "Project approval requires a PRO or ENTERPRISE plan.",
"code": "plan_insufficient",
"doc_url": "https://docs.avala.ai/api/errors#plan_insufficient"
}
Remediation: Contact your Avala account manager to upgrade your organization’s plan.
scope_required — Your API key does not include the required scope for this action.
{
"detail": "API key requires 'projects.write' scope.",
"code": "scope_required",
"doc_url": "https://docs.avala.ai/api/errors#scope_required"
}
Remediation: Create a new API key with the required scope from Settings > Security in Mission Control. See API Key Scopes for the full list.
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:
| Header | Description |
|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix 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).
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://api.avala.ai/api/v1/datasets/",
headers={"X-Avala-Api-Key": "avk_your_api_key"},
)
if response.ok:
data = response.json()
else:
print(f"Error {response.status_code}: {response.json()['detail']}")
Handling Structured Error Codes
Some endpoints return structured errors with a code field for programmatic handling. Use the code to take specific actions in your pipeline:
response = requests.post(
f"https://api.avala.ai/api/v1/projects/{project_uid}/approve/",
headers={"X-Avala-Api-Key": API_KEY},
)
if response.ok:
project = response.json()
print(f"Approved: {project['name']}")
else:
error = response.json()
code = error.get("code")
if code == "plan_insufficient":
# Organization needs a plan upgrade
notify_ops("Plan upgrade needed for project approval")
elif code == "scope_required":
# API key is missing a required scope
notify_ops(f"API key needs scope: {error['detail']}")
elif response.status_code == 400:
# Invalid state transition (e.g., project already active)
log.warning(f"Cannot approve: {error['detail']}")
elif response.status_code == 404:
# Project not found or not owned by this user
log.error(f"Project {project_uid} not found")
Error Recovery Decision Tree
API call fails
|
+-- 401 Unauthorized
| -> API key invalid or expired. Rotate key. Do NOT retry.
|
+-- 403 Forbidden
| +-- code: "plan_insufficient" -> Upgrade org plan. Do NOT retry.
| +-- code: "scope_required" -> Create new key with scope. Do NOT retry.
| +-- (no code) -> Wrong owner/org. Do NOT retry.
|
+-- 404 Not Found
| -> Check resource UID. Do NOT retry.
|
+-- 400 Bad Request
| -> Fix request body or check resource state. Do NOT retry.
|
+-- 429 Too Many Requests
| -> Wait for Retry-After header, then retry.
|
+-- 500 / 503
-> Retry with exponential backoff (1s, 2s, 4s).