PATCH /api/v1/groups/{groupId}
Changes only the fields sent for the Group named by the URL. The body cannot
select another Group. Omitted fields stay unchanged; nullable fields sent as
null are cleared.
| Role in the organization | This endpoint |
|---|---|
OWNER | Allowed |
ADMIN | Allowed |
MEMBER | Conditional |
| Requirement | Rule for this endpoint |
|---|---|
| Business role | An organization-scoped program_director assignment is required for MEMBER |
| Resource scope | Group in the Organization attached to the API key |
| Resource state | Expired Groups are read-only; type and scope freeze after membership history exists |
| Parameter | Type | Required | Description |
|---|---|---|---|
groupId | UUID | yes | Group to update; a body groupId is ignored |
| Header | Required | Description |
|---|---|---|
x-api-key | yes | API key created for this Organization |
Idempotency-Key | yes | Stable key for this update intent |
X-Correlation-Id | no | Caller correlation id, returned or generated |
| Field | Type | Required | Nullable | Description |
|---|---|---|---|---|
name | string | no | no | 2 to 100 characters |
type | string | no | no | level, specialty, or accountability; frozen after first membership |
scope | string | no | no | organization, program, or cohort; frozen after first membership |
programId | UUID | no | yes | Target Program; clear when moving to Organization scope |
cohortId | UUID | no | yes | Target Cohort; clear outside Cohort scope |
startsAt | ISO 8601 string | no | yes | New start instant or null |
endsAt | ISO 8601 string | no | yes | New end instant or null |
capacity | integer | no | yes | Positive maximum; null restores unlimited capacity |
curl -X PATCH "$COHORTE_API_BASE_URL/api/v1/groups/$GROUP_ID" \
-H "x-api-key: $COHORTE_API_KEY" \
-H "Idempotency-Key: group-capacity-unlimited" \
-H 'Content-Type: application/json' \
-d '{"capacity":null}'200 OK — the updated Group, or the original result on replay.400 Bad Request — the body/window/capacity/scope is invalid, capacity is below open periods, the Group is expired, or frozen identity was changed.401 Unauthorized — the API key is invalid or no longer attached to a member.403 Forbidden — the bearer is not an allowed operator.404 Not Found — the Group or selected scope target is unknown or foreign.500 Internal Server Error — the Group could not be updated.The response uses the same Group fields as Get a group, plus:
| Field | Type | Nullable | Description |
|---|---|---|---|
success | boolean | no | Always true on success |
replayed | boolean | no | true when this idempotency key already completed |
correlationId | string | no | Request correlation identifier |
{"success":true,"replayed":false,"data":{"id":"33333333-3333-4333-8333-333333333333","name":"Advanced","type":"level","scope":"program","programId":"11111111-1111-4111-8111-111111111111","programName":"Expert Track","cohortId":null,"cohortName":null,"startsAt":null,"endsAt":null,"capacity":null,"activeMembershipCount":8,"lifecycle":"active","memberships":[]},"correlationId":"req-42"}group.updated event are written atomically.