> For the complete documentation index, see [llms.txt](https://docs.stellic.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stellic.com/stellic-partner-api/requirements/update-a-requirement-constraint.md).

# Update a requirement constraint

Use this endpoint to change a rule on a requirement in a draft audit, or to hide it from students and show it again. `{constraint_id}` is the rule's `id` from the draft's tree and must be on `{requirement_id}`. Send the full `data` for the rule's type and the `is_hidden` value you want; the type itself can't change.

## PUT /requirements/{requirement\_id}/constraints/{constraint\_id}

>

```json
{"openapi":"3.0.0","info":{"title":"Stellic for Developers","version":"1.0"},"tags":[{"name":"Requirements","description":"Add, update, and remove the constraints (rules) on a requirement inside a draft audit."}],"servers":[{"url":"https://{institution}.stellic.com/partnerapi/v1","variables":{"institution":{"default":"{institution}","description":"Your institution's Stellic subdomain: the part before `.stellic.com` in the URL you use to sign in. It becomes the host in every request, as in `https://{institution}.stellic.com/partnerapi/v1/...`. Replace the `{institution}` placeholder with your subdomain before sending."}}}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Personal Access Token issued by your Stellic integration partner. Send it as `Authorization: Bearer <token>` on every request. One token per institution; do not share across environments."}},"schemas":{"UpdateConstraintRequest":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"The constraint's full type-specific payload. The constraint's `type` cannot change; send the fields that type expects."},"is_hidden":{"type":"boolean","description":"Whether the constraint is hidden. Treated as `false` when omitted, which un-hides a hidden constraint; always send the value you want."}}},"UpdateConstraintResponse":{"type":"object","properties":{"success":{"type":"boolean"},"pending_change":{"type":"object","nullable":true,"allOf":[{"$ref":"#/components/schemas/PendingChange"}],"description":"`null` when the edit was folded into an add made earlier on this draft."},"constraint":{"$ref":"#/components/schemas/RequirementConstraint"}}},"PendingChange":{"type":"object","description":"A draft change queued for replay onto the published version when the draft is published.","properties":{"user":{"$ref":"#/components/schemas/PendingChangeUser"},"text":{"type":"string","description":"Plain-language summary of the change."},"timestamp":{"type":"string","description":"When the change was recorded, as `YYYY-MM-DD HH:MM:SS.ffffff+00:00`."}}},"PendingChangeUser":{"type":"object","description":"The account that made the change, as recorded on the change record.","properties":{"username":{"type":"string"},"display_username":{"type":"string"},"userid":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"first_name":{"type":"string"},"last_name":{"type":"string"},"photo_url":{"type":"string","nullable":true},"email":{"type":"string"},"sms_alerts_enabled":{"type":"boolean"},"last_log_in":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"is_admin":{"type":"boolean"},"role":{"type":"string","nullable":true},"mobile_number":{"type":"string","nullable":true},"hash":{"type":"string","description":"Opaque account token. Ignore it."}}},"RequirementConstraint":{"type":"object","description":"One rule on a requirement.","properties":{"id":{"type":"integer","description":"Internal database ID of the constraint; the `constraint_id` for update and remove calls."},"type":{"type":"string","description":"Constraint type name, for example `anyxof`, `minxunits`, `minxcourses`, `mingrade`, `notcount`, `xfromdepts`, `coderange`."},"type_string":{"type":"string","description":"Human-readable rendering of the rule. Present for most constraint types."},"data":{"type":"object","description":"Type-specific fields, in the same shape you send on the add and update calls. For `minxunits` that is `units` and `is_each`; for `anyxof` it is `x` and `is_and`."},"is_hidden":{"type":"boolean","description":"Whether the constraint is hidden from students in the audit view."}}},"ErrorMessage":{"type":"object","description":"Error envelope used by the programs, audits, and requirements endpoints.","properties":{"error":{"type":"string","description":"Human-readable reason. Match on it if you need to branch; the strings on each endpoint page are verbatim."}}}}},"paths":{"/requirements/{requirement_id}/constraints/{constraint_id}":{"put":{"tags":["Requirements"],"parameters":[{"name":"requirement_id","in":"path","required":true,"description":"Internal numeric ID of the requirement that carries the constraint (a node `id` in the draft's `requirement_tree`).","schema":{"type":"integer"}},{"name":"constraint_id","in":"path","required":true,"description":"Internal numeric ID of the constraint: the `id` inside a `constraints[]` entry of that node, or `constraint.id` from the add call. Must belong to `requirement_id`.","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConstraintRequest"}}}},"responses":{"200":{"description":"Constraint updated in the draft. `constraint` is the new state. `pending_change` is `null` when this edit was folded into an add you made earlier on the same draft, otherwise the change record replayed on publish.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConstraintResponse"}}}},"400":{"description":"Validation failure.\n\nCommon causes:\n- The payload is not a JSON object - returns `Payload must be a JSON object.`\n- Missing `data`, or `data` is not an object - returns `'data' must be provided and must be a dictionary.`\n- Type-specific rule broken - returns that constraint type's plain message, for example `Only one is_each allowed for minxunits in requirement {name} [{id}]`\n- Missing type-specific fields may return `Constraint type '{type}' requires '{field}' in data.`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorMessage"}}}},"401":{"description":"Missing or invalid Bearer token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"403":{"description":"Your IP address isn't on the allowlist for this endpoint. Contact Stellic to add it; the response includes the `client_ip` Stellic saw. Also returned, with only `error` set, when the requirement's audit isn't a draft (`Can only modify constraints on draft audits.`), belongs to a compliance requirement (`Compliance requirements are not available via the API.`), or the token's account cannot edit the audit (`Forbidden Access.`).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"client_ip":{"type":"string"}}}}}},"404":{"description":"No requirement has this ID, or no constraint with `constraint_id` sits on this requirement: `{\"detail\": \"No Requirement matches the given query.\"}` or `{\"detail\": \"No RequirementTypeDetail matches the given query.\"}`. A requirement with no audit returns `{\"error\": \"Requirement not found in an editable audit.\"}`. A requirement outside its draft audit's tree returns the same `error` response; compliance and non-draft audit checks take precedence over this tree check.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"},"error":{"type":"string"}}}}}},"500":{"description":"Malformed type-specific values can return a 500. For `timebased`, a non-numeric ID in `data.levels` can cause this."}}}}}}
```

#### What happens after the call

* The rule is updated, and the response returns its new state.
* If you added the rule in this draft, that add now carries the new values and `pending_change` is `null`. Otherwise the edit is recorded and applied to the published audit when you publish.

#### Notes

* **Always send `is_hidden`.** If it's missing it's read as `false`, so a call with only `data` shows a hidden rule again.
* **Send every field of `data`,** as the tree shows it for that rule, not only the field you're changing. For `timebased`, send `levels` as a list of numeric enrollment-level IDs.
* **To change the type, remove the rule and add a new one.**
* **The type's rules still apply.** Use the validation message to correct the rule's `data` before retrying.
* **Only drafts can be edited.** A requirement in a published or under-review audit returns a 403 with `Can only modify constraints on draft audits.` The token's account needs edit rights on the audit, or the call returns `Forbidden Access.`
* **Choose a requirement in the draft's tree.** If the requirement has been removed from the tree, read the draft again to choose a requirement to edit.

#### Related APIs

* [`GET /audits/{audit_id}`](/stellic-partner-api/audits/read-an-audit.md) to find the rule and its current `data`.
* [`DELETE /requirements/{requirement_id}/constraints/{constraint_id}`](/stellic-partner-api/requirements/remove-a-requirement-constraint.md) to remove it instead.
