ConnectAI
Developers/Errors

Errors

One envelope for every failure, with an explicit flag for whether retrying will help.

422 Unprocessable Entity
{
  "error": {
    "code": "validation_failed",
    "message": "phone must be E.164",
    "field": "phone",
    "eventId": "0f4e2a9c-1b77-4d2e-9a03-5c8b71e6d402",
    "retryable": false
  }
}

Branch on code, and let retryable decide whether your queue backs off or dead-letters. You should not have to encode our status codes.

Codes

StatusCodeMeaningWhat to do
400malformed_requestBody is not JSON, or a header is missingFix and resend
401signature_invalidSignature mismatch, unknown key, or clock skew over 300sCheck clock and secret; do not retry blindly
403key_inactiveThe key is pausedStop; contact ConnectAI
403key_revokedThe key is permanently revokedStop; a new key must be issued
403ip_not_allowedSource address is not allowlistedStop; contact ConnectAI
404resource_not_foundThat externalId has no mapping yetSend the parent record first
409slot_unavailableThe slot is at capacityPick an alternative from the response
409doctor_unmappeddoctorPhone matches nobody on the clinic's rosterCheck the number, or ask the clinic to add them
409terminal_stateAlready cancelled or completedStop and reconcile
422validation_failedA field failed validationFix and resend
429rate_limitedOver the per-key limitBack off; honour Retry-After
5xxinternal_errorOur faultRetry with backoff
Only 429 and 5xx are retryable. A 409 is a business answer, not a transport failure — retrying it changes nothing.

An unknown key looks like a bad signature

Both return 401 signature_invalid with the same message. That is deliberate: it stops the endpoint being used to discover which keys exist. If you are sure the key is right, check your clock and your raw-body handling.