Skip to main content
The API uses standard HTTP status codes and a consistent error envelope. When something goes wrong, the response body always has the same shape, so your error-handling code works for every endpoint.

Error object

Most error responses contain a JSON body with a detail field:
{
  "detail": "Session not found."
}
For validation errors (422), detail is an array describing each field that failed:
{
  "detail": [
    {
      "type": "missing",
      "loc": ["body", "agent"],
      "msg": "Field required",
      "input": {}
    }
  ]
}
Requests rejected at the API gateway (for example a missing or invalid key, 401) return a { "message": ... } body instead of { "detail": ... }. Handle both keys when reading error text.

HTTP status codes

Success codes

CodeMeaningUsed by
200 OKRequest succeeded.GET endpoints, updates.
201 CreatedResource created.POST /sessions, POST /agents.
202 AcceptedAction accepted, processing asynchronously.POST /messages, POST /pause, POST /resume.
204 No ContentAction succeeded, no response body.DELETE /sessions, DELETE /agents.

Client error codes

CodeMeaningCommon causeWhat to do
400 Bad RequestMalformed request or invalid parameters.Sending an event to a session that can’t accept it.Check the request body against the endpoint docs.
401 UnauthorizedMissing or invalid API key.No Authorization header, or expired key.Verify your API key is correct and properly formatted.
403 ForbiddenValid credentials, insufficient permissions.Trying to modify a reserved h/ agent.Check that your role allows this operation.
404 Not FoundResource doesn’t exist or isn’t visible to you.Wrong session ID, or querying another team’s resource.Verify the ID and that you have access.
409 ConflictResource already exists, or an identical idempotent request is still in flight.Creating an agent with a duplicate name, or retrying a request with the same Idempotency-Key before the first one finished.Use a unique identifier, fetch the existing resource, or wait for the in-flight request to complete.
422 Unprocessable EntityRequest body fails validation.Missing required fields, wrong types.Check the detail array for specific field errors.
429 Too Many RequestsConcurrency limit exceeded.Too many sessions running simultaneously.Wait for running sessions to complete, or request a quota increase. See Rate limits.

Server error codes

CodeMeaningWhat to do
502 Bad GatewayUpstream service error.Retry after a brief pause.
503 Service UnavailableTemporary capacity issue.Check the Retry-After header and retry.
504 Gateway TimeoutRequest took too long to process.Retry the request.

Handling errors with the SDK

The SDKs raise a typed error on any non-2xx response (carrying the status_code / statusCode and parsed body) and return the parsed model on success, so you never narrow a data | error union by hand:
from hai_agents.core import ApiError

try:
    session = client.sessions.create_session(
        agent="h/web-surfer-holo3-1-35b",
        messages=[{"type": "user_message", "message": "Top 3 stories on Hacker News?"}],
    )
except ApiError as err:
    print(err.status_code, err.body)
The SDKs also retry transient errors (429, 503, 504) with backoff automatically, twice by default. Tune it with max_retries (Python) / maxRetries (TypeScript) on the client, or per call via request options.

Retry strategy

Without the SDK, retry 429, 503, and 504 errors with exponential backoff:
import time
import requests

def create_session_with_retry(payload, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(
            "https://agp.eu.hcompany.ai/api/v2/sessions",
            headers={"Authorization": f"Bearer {API_KEY}"},
            json=payload,
        )

        if response.status_code == 201:
            return response.json()

        if response.status_code in (429, 503, 504):
            wait = 2 ** attempt  # 1s, 2s, 4s
            retry_after = response.headers.get("Retry-After")
            if retry_after:
                wait = int(retry_after)
            print(f"Retrying in {wait}s...")
            time.sleep(wait)
            continue

        # Non-retryable error
        response.raise_for_status()

    raise Exception("Max retries exceeded")
Do not retry 400, 401, 403, 404, or 409 errors. These indicate a problem with your request that won’t be fixed by retrying. Fix the issue in your code first.