Skip to content

enrollments.requirementOverrides

A requirement override adjusts program policy for one enrollment: the negotiated-contract layer. Effective policy is always program defaults ∘ operating-type scoping ∘ enrollment overrides — the override merges first, then capacity and scope filters apply.

// This member qualifies at 500 instead of the program's 1000:
await boomin.enrollments.requirementOverrides.create("enr_...", {
requirement: "<requirement uuid>",
threshold: 500,
});
MethodRouteScope
create(enrollmentId, params, options)POST /enrollments/{id}/requirement_overridesrequirement_overrides:write
list(enrollmentId, params, options)GET /enrollments/{id}/requirement_overridesrequirement_overrides:read
retrieve(enrollmentId, id, options)GET /enrollments/{id}/requirement_overrides/{ovrId}requirement_overrides:read
update(enrollmentId, id, params, options)POST /enrollments/{id}/requirement_overrides/{ovrId}requirement_overrides:write
del(enrollmentId, id, options)DELETE /enrollments/{id}/requirement_overrides/{ovrId}requirement_overrides:write

Every mutation re-evaluates the enrollment’s standing.

ModeHowEffect
Patchrequirement set, fields presentNamed fields replace the program requirement’s — threshold, operator, windowDays, failurePolicy. Absent fields inherit.
Disablerequirement set, disabled: trueThe requirement is suppressed for this enrollment.
Addrequirement omitted; full requirement fieldsA net-new requirement that exists for this enrollment only. metricKey + scope required.

One active patch per (enrollment, requirement) — a second answers requirement_override_already_exists (409); update or archive the existing one.

// Suppress a requirement for one member:
await boomin.enrollments.requirementOverrides.create("enr_...", {
requirement: "<requirement uuid>",
disabled: true,
});
// Add a member-only gate:
await boomin.enrollments.requirementOverrides.create("enr_...", {
metricKey: "x:demo_submitted",
scope: "program_maintenance",
operator: "gte",
threshold: 1,
});

Added requirements pass the same metric vocabulary gate as program-level ones: built-ins, active x: keys, and assert: claims.

{
"id": "ovr_...",
"object": "requirement_override",
"enrollment": "enr_...",
"requirement": "<uuid or null>",
"disabled": false,
"threshold": 500,
"operator": null,
"windowDays": null,
"failurePolicy": null,
"metricKey": null,
"status": "active",
"metadata": {},
"livemode": true
}

requirement is the program requirement’s bare uuid in patch/disable mode and null in add mode. null policy fields mean inherit.

A patch against a requirement that can never apply to this enrollment’s current capacity — the requirement is scoped to an operating type the enrollment doesn’t hold — is refused with requirement_override_inapplicable (409) rather than stored: configuration that looks meaningful but can never execute is a bug factory. Set the enrollment’s operating type first, then patch.

An override created while applicable whose enrollment later changes capacity goes dormant instead: the patched requirement filters out with its patch, and wakes if the capacity returns.

del archives — the inherited requirement applies again, and the override’s history stays readable. Nothing under an enrollment is ever hard deleted.

programs.standingPreview marks each enrollment’s overrides patched | disabled | added, so boomin standing test (and your own tooling) can show why a member’s effective policy differs from the program’s:

const preview = await boomin.programs.standingPreview("prog_...");
// preview.enrollments[n].overrides -> [{ id, requirement, mode }]