Skip to main content

Errors

Audience​

Integrators handling API error responses in automation and retry logic.

HTTP status codes​

StatusMeaning
400Malformed request
401Missing, invalid, or revoked API key
402Insufficient org credits for an assessment
403Not permitted (missing scope, billing gate)
404Resource unknown or not visible to your key
409State conflict (duplicate upload, artifact cited by assessment)
422Request body failed validation
429Rate limit (authentication flows only — see below)
503Service temporarily unavailable

Errors return JSON with a message field. Use the HTTP status and message in your automation — you do not need to parse internal type names.

Troubleshooting matrix​

SymptomStatusLikely causeFix
Invalid key401Revoked, wrong, or malformed Authorization headerCheck secret; mint new key in portal
Missing scope403Key lacks scope for routeNew key with scope from Authentication
Project not found404Wrong projectPid or key for different domainGET /domains/<domainPid>/projects; confirm domain
Slug lookup fails404Wrong slugs or project outside key domainUse pid listing instead — Concepts
Out of credits402Org credit balance exhaustedShow the recovery string — Credits and feedback
Duplicate upload409Reused storage key on completeRe-run upload-init and PUT
Cannot delete artifact409Cited by an assessmentPOST .../archive instead
Validation error422Wrong field types or missing required fieldsCompare body to API reference
Auth rate limit429Too many login/OTP attemptsWait retryAfter seconds (portal flows only)
Service down503Temporary outageExponential backoff and retry

Not found vs forbidden​

Many routes return 404 when a resource exists but is outside your API key's domain, rather than 403. This avoids revealing whether a resource exists.

Retry guidance​

StatusRetry?
401, 403, 404, 409, 402, 422No — fix credentials, scopes, or request body
429Yes — wait at least retryAfter seconds
503Yes — exponential backoff

Rate limits​

Integrator API calls (bearer key on domains, projects, assessments, uploads, search) are not rate-limited today. Use reasonable poll intervals — see Async jobs.

Rate limiting applies to portal authentication (login, OTP, password reset). Integrators using API keys do not hit these limits in normal operation.

When 429 occurs (typically portal flows):

{
"message": "Too many authentication attempts",
"retryAfter": 60
}

retryAfter is in seconds. Per-key API rate limits may be introduced later; this page and the changelog will be updated.

Example error bodies​

401

{
"message": "Invalid authentication state"
}

403 (missing scope)

{
"message": "API key missing required scope: projects:write"
}

402

InsufficientCreditsError and TrialExpiredError both carry a required recovery field naming the next step. Display it verbatim rather than composing your own wording — it is the same sentence the AIR web app shows, so a person who reads it in your client and then opens the portal gets one consistent instruction.

{
"_tag": "air/InsufficientCreditsError",
"orgPid": "org_…",
"available": 0,
"required": 1,
"recovery": "Request more assessment credits from Thalus, or buy a 5-credit pack to continue now."
}

To act on it, see Credits and feedback — read the balance before you spend, request credits, or hand a person a purchase link.