Skip to main content
HASP uses one stable set of error codes across the AI API and the App Builder SDK. The two identifiers to branch on are the HTTP status code and error.codeerror.message is human-readable and may change without notice.

The error envelope

Every error shares the same shape:
{
  "success": false,
  "error": {
    "code": "PHI_BLOCKED",
    "type": "forbidden",
    "message": "Message contains PHI that cannot be sent without redaction.",
    "retryable": false,
    "request_id": "req_01JQREQ000000000000000000"
  },
  "meta": {
    "request_id": "req_01JQREQ000000000000000000"
  }
}
Always log request_id — it is the key for support and for retrieving the corresponding audit record.

Error categories

The codes fall into five categories. Each maps to an HTTP status range and a clear handling rule:
CategoryTypical statusWhat it meansWhat to do
Authentication401The API key is missing, malformed, or revoked (INVALID_API_KEY).Fix the credential. Not retryable.
Authorization & scope403The key lacks a required scope (MISSING_SCOPE), or a feature is not enabled for the org.Grant the scope or enable the feature. Not retryable.
Compliance / PHI402, 403No active BAA (BAA_REQUIRED), PHI blocked by policy (PHI_BLOCKED), PHI in a tool schema (PHI_IN_TOOL_SCHEMA), or credits exhausted (AI_CREDITS_EXHAUSTED).Sign the BAA, adjust PHI mode, or top up credits. Generally not retryable until the underlying condition changes.
Validation400, 422The request body failed validation (VALIDATION_FAILED) or an input was unprocessable. error.param names the offending field.Fix the request. Not retryable as-is.
Rate limit & budget429RPM/daily limit hit (RATE_LIMITED) or a spend cap reached (BUDGET_EXCEEDED).Honor Retry-After and back off. Retryable. See Rate Limits.
Server / upstream500, 502, 503An internal error (INTERNAL_ERROR), an upstream provider failure (INFERENCE_UPSTREAM_FAILURE), or a temporarily unavailable gateway (INFERENCE_UNAVAILABLE).Retry with exponential backoff. Retryable.

Retry guidance

The error.retryable boolean tells you whether a retry can ever succeed without changing the request:
  • Retry 429 and 5xx errors. Prefer error.details.retry_after_seconds (or the Retry-After header) when present; otherwise use exponential backoff with a ceiling.
  • Do not retry 400, 401, 403, and 422 — they require a change to the request, the credential, or the org’s configuration. Retrying an identical request will fail identically.
Streaming responses deliver errors that occur after the stream opens as SSE error events rather than HTTP status codes — handle both paths.

Full reference

This page is the platform-level overview. The complete code table — every code, its exact HTTP status, the error.details fields it carries, and a worked retry loop — lives in the AI API error reference:

AI API Error Reference

The authoritative, exhaustive list of error codes and handling patterns, including streaming errors.