biofrq.update
Mutate an existing subject's metadata: display name, attributes,
and group membership. Doesn't touch face templates — to attach
another template, call biofrq.enroll with mode: "addReference".
Billed at 0 credits today; every call still writes a Usage ledger entry for audit.
Params
Exactly one locator is required:
| Field | Type | Notes |
|---|---|---|
subjectId | UUID | Internal id (returned by biofrq.enroll). |
externalId | string | Your stable id. Unique per tenant. |
Mutators (all optional; any subset):
| Field | Type | Notes |
|---|---|---|
displayName | string | null | Replace; null clears. Omit to leave alone. |
attributes | object | null | Replace the whole attributes JSONB; null clears. Omit to leave alone. |
addGroups | string[] | Union into existing Groups. |
removeGroups | string[] | Difference from existing Groups. |
setGroups | string[] | Full replace. Mutually exclusive with addGroups / removeGroups. |
Composition order: when both addGroups and removeGroups are
present, removeGroups is applied first, then addGroups. Net
result is predictable regardless of JSON key order.
Final group set must be 1..30 entries after the mutation; an
update that ends up with 0 groups is INVALID_REQUEST.
Request — add / remove groups
json
{
"action": "biofrq.update",
"params": {
"subjectId": "8a1c...",
"addGroups": ["VIP", "AllStaff"],
"removeGroups": ["OnboardingTrial"],
"displayName": "Asha Rao",
"attributes": { "role": "vip", "team": "ops" }
}
}
Request — setGroups (full replace)
json
{
"action": "biofrq.update",
"params": {
"externalId": "emp-4421",
"setGroups": ["Staff", "Watchlist"]
}
}
Response
json
{
"tenantId": "...",
"subjectId": "8a1c...",
"externalId": "emp-4421",
"groups": ["Staff", "VIP", "AllStaff"],
"groupName": "Staff"
}
groupName is a legacy alias for groups[0].
Common errors
INVALID_REQUEST— bothsubjectIdandexternalIdprovided; neither provided;setGroupsmixed withaddGroups/removeGroups; final group set 0 or > 30.SUBJECT_NOT_FOUND— locator doesn't resolve in the active project.