Ana içeriğe geç

One lazily-loaded section of this contact's CRM record

GET 

/api/contacts/:contact/crm/records

Offers, sales, open balance, the clinic's own notes, or the files on the patient — ONE of them per request.

Separate from GET /api/contacts/{contact}/crm because that endpoint runs every time an agent clicks a conversation, and every provider call on it is multiplied by that. The tenant's whole CRM allowance is sixty requests a minute shared with the reminder engine and the webhook fan-out, so these live behind a tab: an unopened section costs nothing, and asking for one section rather than five costs one read rather than five.

state is the answer's own shape and must be rendered differently for each value: ready (items are present), unsupported (this CRM does not hold that kind of record — render no tab), unlinked (this contact is not matched to anybody over there — offer matching), unavailable (we could not ask; see refused and error).

items is null, never [], whenever state is not ready. An empty list is a claim — "this patient owes nothing" — and an agent repeats claims like that to somebody sitting in a waiting room.

Nothing here is cached: an unopened tab has no answer to invalidate, and an opened one is a deliberate act by somebody who wants the current number. A budget refusal therefore has nothing to fall back on and says so through refused + retry_after rather than erroring.

The debts section never carries a total. Each open item has its own currency, and one number over them is wrong by the size of whichever currency was dropped; meta.currencies lists which are present so a panel can say "2 open items" honestly. Debt rows also carry overdue as a nullable boolean rather than a day count: the vendor publishes a day count and nothing documents what date it counts from, so this API drops it (doc 33 S11).

Requires Contact view.

Request​

Responses​

The section, or the reason there is none.