The guard against a silent no-op. bulk-update returns matched: 0 and no error when its pattern selects nothing, so a configuration change appears saved and is not.
Send the SAME match the update will send as matchMetadata, and the same codes. Anything else measures a different population than the one about to be written — a trigger can carry the key you scope by and still miss the pattern, so "carries a label" and "will be reached" are different questions.
Set scope to the labels that select the PATIENTS in the group being written. It matches the labels on each patient, while match matches the labels on each trigger — that split is deliberate. A population selected by TRIGGER labels would exclude every trigger carrying none, and an unlabelled trigger is exactly what a bulk update silently fails to reach, so the gate would go green over a half-labelled group. Anchoring on the patient keeps those inside the population, where they show up as unmatched. It also stops the two predicates collapsing into one condition, which would make unmatched: 0 arithmetically unavoidable.
Within a scope, matched is the number to compare against how many triggers you expect in the set — only the caller knows what SHOULD be there. unmatched is the rest of the population the pattern will not touch, INCLUDING anything still unlabelled.
Without a scope the population is every patient in the tenant.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
400match was absent, or either pattern was not a non-empty JSON object. null is rejected — it is not the same as omitting the field.
401Missing, malformed or unrecognised Basic credentials.
403Authenticated, but the client's role does not permit this, or it is not attached to the patient.