Authentication
Review API-key header and authorization failure cases.
Reference
Standard public error body, reason codes, and client handling guidance.
Public API errors use a standard JSON object with a stable reason code and developer-readable message.
{
"error": "api_key_validation_failed",
"reason_code": "invalid_limit",
"message": "The limit query parameter is invalid.",
"field": "limit"
}
error names a broad category. Every 422 validation error, such as invalid_limit, uses api_key_validation_failed, even though nothing is wrong with the key.
Client code should follow these rules:
reason_code, not message or error.message as developer-readable text that may change for clarity.field to identify a query parameter when it is present. It is null when no single field applies.| HTTP status | Recommended handling |
|---|---|
400 or 422 |
Fix the request before retrying. Use field and reason_code to identify the invalid input. |
401 |
Do not retry with the same key until the key, environment, or header format has been corrected. |
403 |
Check scopes, route availability, and whether the resource is available to the caller. A 403 without the standard error body comes from ChartHero's firewall, usually the rate limit. |
404 |
Treat the resource as not found or unavailable through the public API. |
503 |
Retry with backoff. If the error continues, contact ChartHero support. |
Authentication, route availability, organization-scope, and scope checks run before query parsing. A request can receive an authentication or authorization error even when the URL also contains an invalid query parameter. After those route-level checks pass, unsupported query parameters can be reported before resource-not-found or resource-unavailable checks.
Send one request at a time, at most about one per second across all your requests to the API. The limit counts every request from one IP address, so integrations that share an outbound address share it. Well above that rate, ChartHero's firewall blocks requests from that address for a few minutes, with a 403 that has no reason_code or standard error body. Wait five minutes, then retry more slowly.
The firewall also blocks requests that look like attacks or come from addresses known for malicious traffic, with the same 403. That block doesn't clear by waiting: if the 403 continues after five minutes, stop retrying and contact ChartHero support. Every 403 from the API itself has a reason_code.
| Code | When it can occur |
|---|---|
invalid_limit |
limit is blank, non-integer, non-canonical, below 1, or above 100. |
invalid_offset |
offset is blank, non-integer, non-canonical, negative, or above 10000. |
invalid_sort |
sort_order is not asc or desc. |
invalid_query |
Date filters are malformed, timezone-naive, or in an invalid range, or a parameter on an evaluation route is repeated. |
unsupported_filter |
A query key is not supported for the authorized public route. |
{
"error": "api_key_validation_failed",
"reason_code": "invalid_limit",
"message": "The limit query parameter is invalid.",
"field": "limit"
}
| Code | When it can occur |
|---|---|
missing_bearer |
The request does not include Authorization: Bearer <api_key>. |
malformed_token |
The API key in the bearer header cannot be parsed. |
invalid_key |
The key is not recognized for the target environment. |
api_keys_disabled |
API-key authentication is not available for the request. |
test_prefix_not_allowed |
A test key was sent to an environment that does not allow it. |
disabled_key, expired_key, revoked_key |
The key exists but cannot be used. |
missing_scope |
The key does not include every scope required by the route. |
org_scope_only_required |
The request requires an organization-scoped API key. |
route_not_allowed |
The route has not been enabled. |
cross_organization_denied |
The requested resource is outside the caller's organization. |
demo_training_denied |
Demo or training resources are not available through this API. |
{
"error": "api_key_unauthorized",
"reason_code": "missing_bearer",
"message": "A bearer API key is required.",
"field": null
}
{
"error": "api_key_forbidden",
"reason_code": "missing_scope",
"message": "The API key is missing a required scope.",
"field": null
}
These errors use HTTP 503. Retry with backoff, and contact ChartHero support if the error continues.
| Code | When it can occur |
|---|---|
digest_key_unavailable |
API-key verification is temporarily unavailable. |
audio_storage_unavailable |
Audio storage is temporarily unavailable. |
evaluation_read_unavailable |
The evaluation list query timed out, or a record's availability changed while includes were loading. ChartHero returns no partial page. |
{
"error": "public_api_unavailable",
"reason_code": "digest_key_unavailable",
"message": "API-key verification is temporarily unavailable.",
"field": null
}
Path IDs are opaque ChartHero IDs. Clients must not infer organization, type, date, or storage behavior from ID format. Demo, training, cross-organization, and ineligible resources fail closed.
| Code | When it can occur |
|---|---|
encounter_not_found |
The encounter was not found or is not available to the caller. |
document_not_found |
The document was not found or is not available to the caller. |
evaluation_not_found |
The evaluation was not found or is not a completed evaluation available to the caller, for example because its encounter was removed or moved to another organization. |
transcript_not_found |
The finalized transcript was not found or is not available. |
audio_not_found |
The audio object was not found or is not available. |
unsupported_document_type |
The document type is not supported for the requested route. |
audio_not_available_for_document |
The document does not have retrievable audio for this API route. |
{
"error": "public_api_not_found",
"reason_code": "document_not_found",
"message": "The document was not found.",
"field": null
}
Review API-key header and authorization failure cases.
Handle invalid list query parameters.
Inspect generated error schemas and response status codes.