Error Handling
All error responses use a consistent JSON format. This page documents the HTTP status codes, error body format, and common error scenarios for each module.
Error Response Format
All errors return a JSON body with a detail field:
{
"detail": "Human-readable error message"
}
Some validation errors (HTTP 422) from Pydantic return a structured list of field-level errors:
{
"detail": [
{
"loc": ["body", "email"],
"msg": "value is not a valid email address",
"type": "value_error.email"
}
]
}
HTTP Status Codes
Code |
Name |
Description |
|---|---|---|
200 |
OK |
Request succeeded. The response body contains the result. |
201 |
Created |
Resource was successfully created. The response body contains the new resource ID. |
302 |
Found |
Redirect to another URL (used by download endpoints). |
400 |
Bad Request |
The request body or parameters are malformed. Check the |
401 |
Unauthorized |
No valid authentication credentials provided. Either the session has expired or the API key is missing/invalid. |
403 |
Forbidden |
The authenticated user does not have permission for this action. This can occur when accessing another user’s resources or when the API key lacks the required scope. |
404 |
Not Found |
The requested resource does not exist, or the authenticated user does not have access to it. For privacy, the server does not distinguish between “does not exist” and “no access.” |
409 |
Conflict |
The request conflicts with the current state. Common causes: report artifact not ready yet, duplicate resource name, or resource is still processing. |
422 |
Unprocessable Entity |
Request body failed validation. The |
429 |
Too Many Requests |
Rate limit exceeded. Wait for the number of seconds indicated in
the |
500 |
Internal Server Error |
An unexpected error occurred. The |
Rate Limiting
Rate-limited endpoints include the following headers in every response:
Header |
Description |
|---|---|
|
Maximum number of requests allowed in the current window. |
|
Number of requests remaining in the current window. |
|
Unix timestamp when the rate limit window resets. |
|
(Only on 429 responses) Seconds to wait before retrying. |
Rate-limited endpoints:
Authentication –
POST /api/auth/login,POST /api/auth/register,POST /api/auth/forgot-passwordPredictions –
POST /api/mlops/deployments/{id}/predict,POST /api/models/{id}/predict
Common Error Scenarios
Authentication Errors
Code |
Error |
Cause |
|---|---|---|
401 |
|
No session cookie or API key, or the credentials have expired. |
401 |
|
Wrong password during login. |
403 |
|
API key does not have the required scope (e.g. |
409 |
|
Attempting to register with an email that is already taken. |
422 |
|
Password too short during registration or reset. |
429 |
|
Too many login/register attempts. |
Project Errors
Code |
Error |
Cause |
|---|---|---|
404 |
|
Project ID does not exist or the user is not a member. |
422 |
|
Name was blank or whitespace-only. |
Dataset Errors
Code |
Error |
Cause |
|---|---|---|
404 |
|
Dataset ID does not exist or belongs to another project. |
404 |
|
No version exists for the given dataset. |
422 |
|
Uploaded file is not CSV or Parquet. |
Experiment Errors
Code |
Error |
Cause |
|---|---|---|
404 |
|
Experiment ID does not exist or is inaccessible. |
422 |
|
The specified target column does not exist in the dataset schema. |
422 |
|
Must be |
Model Errors
Code |
Error |
Cause |
|---|---|---|
404 |
|
Model ID does not exist or is inaccessible. |
500 |
|
H2O model failed to produce a prediction. Check input features match the training schema. |
Deployment Errors
Code |
Error |
Cause |
|---|---|---|
404 |
|
Deployment does not exist or has been deactivated. |
422 |
|
Invalid stage value when creating a deployment. |
422 |
|
The model is from a different project. |
422 |
|
Invalid promote target. |
422 |
|
Rollback request missing both identifiers. |
Report Errors
Code |
Error |
Cause |
|---|---|---|
409 |
|
Attempting to view or download a report that is still being generated. |
422 |
|
Report kind must be one of: |
Privacy Suite Errors
Code |
Error |
Cause |
|---|---|---|
404 |
|
Privacy session does not exist or is inaccessible. |
404 |
|
Attempting to download before transformation is complete. |
404 |
|
Rule ID does not exist in the given policy. |
422 |
|
Session creation without specifying which dataset to scan. |
422 |
|
Cross-project dataset/policy mismatch. |
SynthGen Errors
Code |
Error |
Cause |
|---|---|---|
400 |
|
Attempting to generate from a model that is still training. |
404 |
|
SynthGen model does not exist or is inaccessible. |
409 |
|
Attempting to download before generation completes. |
422 |
|
Model type must be one of: |
422 |
|
Requested row count exceeds the streaming limit. |
Studio Errors
Code |
Error |
Cause |
|---|---|---|
404 |
|
The deployment linked to the session is no longer active. |
500 |
|
The baseline input caused a prediction error. Check that input features match the deployment’s feature schema. |
500 |
|
A scenario’s modified input caused a prediction error. |
Retry Strategy
For transient errors (429, 500, 502, 503, 504) the recommended retry strategy is exponential backoff:
import time
import requests
def api_request(method, url, **kwargs):
"""Make an API request with exponential backoff retry."""
max_retries = 3
for attempt in range(max_retries + 1):
resp = requests.request(method, url, **kwargs)
if resp.status_code == 429:
wait = int(resp.headers.get("Retry-After", 2 ** attempt))
time.sleep(wait)
continue
if resp.status_code >= 500 and attempt < max_retries:
time.sleep(2 ** attempt)
continue
resp.raise_for_status()
return resp.json()
raise Exception(f"Request failed after {max_retries} retries")
See also
Authentication – How to authenticate API requests.
API Reference – API overview and conventions.