POST /api/v1/groups
Creates a Group for level, specialty, or accountability work. Creating a Group does not move an Enrollment and changes neither its Cohort nor its Path.
| 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 | Organization attached to the API key |
| Resource state | The selected Program and Cohort must exist in that Organization |
| Header | Required | Description |
|---|---|---|
x-api-key | yes | API key created for this Organization |
Idempotency-Key | yes | Stable key for this creation intent |
X-Correlation-Id | no | Caller correlation id, returned or generated |
| Field | Type | Required | Nullable | Description |
|---|---|---|---|---|
name | string | yes | no | 2 to 100 characters |
type | string | yes | no | level, specialty, or accountability |
scope | string | yes | no | organization, program, or cohort |
programId | UUID | by scope | yes | Required for Program and Cohort scope; absent/null for Organization scope |
cohortId | UUID | by scope | yes | Required only for Cohort scope |
startsAt | ISO 8601 string | no | yes | Optional start instant |
endsAt | ISO 8601 string | no | yes | Optional end instant, not before startsAt |
capacity | integer | no | yes | Positive maximum; null means unlimited |
curl -X POST "$COHORTE_API_BASE_URL/api/v1/groups" \
-H "x-api-key: $COHORTE_API_KEY" \
-H "Idempotency-Key: group-advanced-2026" \
-H 'Content-Type: application/json' \
-d '{"name":"Advanced","type":"level","scope":"program","programId":"11111111-1111-4111-8111-111111111111","capacity":20}'201 Created — the Group was created.200 OK — the same idempotent creation was replayed.400 Bad Request — a required header or field is missing, or the scope/window/capacity is invalid.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 — a selected Program or Cohort is unknown or belongs to another Organization.500 Internal Server Error — the Group could not be created.| Field | Type | Nullable | Description |
|---|---|---|---|
success | boolean | no | Always true on success |
replayed | boolean | no | true when the idempotency key already completed |
data.id | UUID | no | Created Group identifier |
data.name | string | no | Group name |
data.type | string | no | Group type |
data.scope | string | no | Group scope |
data.programId | UUID | yes | Scoped Program |
data.cohortId | UUID | yes | Scoped Cohort |
data.startsAt | ISO 8601 string | yes | Optional start instant |
data.endsAt | ISO 8601 string | yes | Optional end instant |
data.capacity | integer | yes | Maximum open periods or null |
data.activeMembershipCount | integer | no | Initially zero |
data.lifecycle | string | no | Derived lifecycle |
data.memberships | array | no | Initially empty membership history |
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":20,"activeMembershipCount":0,"lifecycle":"active","memberships":[]},"correlationId":"req-42"}group.created event are written atomically.organizationId in the body is ignored; tenant identity comes from the API key.