Errors and idempotency
Public API errors use a stable code and a safe message:
{
"code": "invalid_access_key",
"message": "A valid API key is required"
}Branch on code, not on the human-readable message.
Status handling
| Status | Meaning | Client action |
|---|---|---|
400 | invalid shape, recipient, variable, state, or idempotency input | fix the request; do not retry unchanged |
401 | missing, invalid, expired, or revoked access key | replace/rotate credentials |
404 | environment, template, automation, profile, or other resource not found | verify identifiers and environment |
409 | lifecycle or idempotency conflict | inspect code; do not create a new key blindly |
429 | quota or rate limit | back off and retry if the business operation is still valid |
5xx | transient server failure | retry with exponential backoff and the same idempotency key |
Two idempotency forms
- Transactional send uses the JSON field
idempotencyKey. - Installation binding uses the HTTP header
Idempotency-Key.
Preserve the original key across connection failures and timeouts. If the first response was lost after admission, a new key can create a duplicate operation.
Retry policy
Use bounded exponential backoff with jitter, for example 1 s, 2 s, 4 s, 8 s, then a durable application job. Set a maximum business validity window based on the template TTL or operation.
Do not retry:
- malformed JSON;
- unknown/inactive template without a deployment change;
- invalid variable types;
- unauthorized requests without rotating the key;
- a conflicting idempotency key with different payload.
Timeouts
Set a short connect timeout and a practical response timeout. A timeout is ambiguous: the server may have admitted the operation. Retry with the same idempotency key.
Observability
Log the environment ID, endpoint family, template/automation key, idempotency key, HTTP status, Engage error code, and returned request/run ID. Redact authorization and recipient-sensitive payload fields.