Error Handling
The Heron API uses standard HTTP response codes to indicate the success or failure of an API request. In general:
- Codes in the
2xxrange indicate success. - Codes in the
4xxrange indicate an error that failed given the information provided (e.g., a required parameter was omitted, a charge failed, etc.). - Codes in the
5xxrange indicate a server-side or upstream failure.
Error Response Body
When an error occurs, the API returns the error payload directly:
{
"code": "invalid_request",
"message": "The provided parameter 'amount' must be a positive number.",
"details": {
"field": "amount"
}
}details is optional. When present, it contains endpoint-specific context that can help you correct the request or understand why the operation could not be completed.
Error Codes
The API Reference describes endpoint-specific HTTP responses and error payloads. Authentication, permission and rate-limit errors can also occur before an endpoint runs. The table below lists common codes; individual guides describe additional workflow-specific errors. Handle unknown codes with a safe fallback and keep the request ID for support.
| Code | Typical meaning |
|---|---|
missing_credentials | No API credentials were provided. |
unauthorized | The provided API key or bearer token was not accepted. |
auth_failure | Heron's authentication infrastructure is temporarily unavailable. |
invalid_request | The request shape or values were invalid. Check details when present. |
feature_not_enabled | The organization does not have the feature required for this operation. |
insufficient_role | The credential is valid but does not carry the required role for the operation. |
rate_limit_exceeded | Too many requests were sent in a short period. Use retry/backoff logic. |
service_unavailable | A required upstream dependency is temporarily unavailable. Retry later. |
transfer_not_found | The requested transfer does not exist in your organization or environment. |
report_not_found | The requested report does not exist in your organization or environment. |
quote_request_not_found | The referenced quote request does not exist. |
quote_option_not_found | The referenced quote option does not exist. |
quote_option_expired | The quote option is no longer valid and must be refreshed. |
idempotency_conflict | The same idempotency key was reused with different request parameters. |
entity_conflict | The request conflicts with an existing entity or a concurrent change. |
document_submission_history_conflict | The document cannot be deleted because its provider submission history must be retained. |
provider_follow_up_state_conflict | A provider follow-up requirement or document submission changed state concurrently. |
provider_document_submission_blocked | The provider cannot currently receive documents; retry the same file once collection is permitted again. |
customer_webhook_endpoint_limit_exceeded | Your organization has reached the maximum number of configured customer webhook endpoints. |
customer_webhook_delivery_replay_unavailable | The delivery cannot be replayed in its current state or the replay window has expired. |
crypto_wallet_screening_rejected | A crypto wallet address was blocked by required sanctions screening. |
crypto_wallet_screening_unavailable | The wallet was not saved because its security check could not be completed. Retry shortly; contact support if it persists. |
internal_server_error | An unexpected server-side failure occurred. |
Request IDs
API responses include an X-Request-Id header. Requests rejected before reaching the API may not include it. If you contact Heron support about a failed or unexpected request, include this header value along with the endpoint, timestamp, and response error code so support can correlate your report with Heron logs.
Handling Errors
We recommend handling errors by code, not just by HTTP status. For example, if you receive invalid_request, inspect details for field-level information when it is present; if you receive service_unavailable or rate_limit_exceeded, retry with exponential backoff. See Rate Limits for thresholds and handling 429 responses, including responses that do not use the JSON error format above. Preserve the original idempotency key and request body when retrying an idempotent write.
Transfer cancellation conflicts
POST /v1/transfers/{transferId}/cancel returns 409 / invalid_request when the transfer is no longer eligible. Read details.reason, refresh the transfer, and use the current cancellation.eligible result. Repeating a successful cancellation returns 200 without duplicate events. See Cancel an unused transfer for the complete eligibility and reason catalog.