Errors and retries
Three categories, and treating them alike is how integrations create duplicate clinical work.
#Retry
| Code | Meaning | How |
|---|---|---|
429 | Rate limited. | Exponential backoff. Respect Retry-After when present. |
503 | A dependency is unavailable. | Backoff. Work is queued on our side rather than lost. |
-32000 | Transient internal error. | Retry the same call with the same task id. |
#Fix, do not retry
| Code | Meaning |
|---|---|
-32602 | Invalid params. A required field is missing or a skill name is wrong. |
400 | The request failed validation. The errors name the fields. |
401 | Token missing, malformed or expired. Mint a new one - once. |
#Stop and ask
| Code | Meaning | Why retrying will not help |
|---|---|---|
-32003 / 403 | Not authorised for that practice or scope. | A practice decides this. Retrying cannot change it, and it may have revoked you deliberately. |
404 | Not found. | We do not distinguish "does not exist" from "not yours". Either way it is not reachable by you. |
Never retry message/send after a timeout
If a request times out, you do not know whether the task was created. Retrying creates a duplicate. Instead, poll for tasks you started - the response to a duplicate names the existing task id rather than making another one.
#Rate limits
Applied per integration and per practice, so one busy practice cannot exhaust your quota for the others. If you are hitting them while polling, your poll interval is too short - see When it waits for a human.
#Idempotency
Send an Idempotency-Key header on message/send. A repeat with the same key returns the original task rather than creating a second one, which is the cheapest protection against every duplicate scenario on this page.
bash
-H "Idempotency-Key: your-own-stable-id-for-this-request"