POST /api/v1/cohorts/{cohortId}/status
Moves a cohort to its next state. The lifecycle only goes forward:
| From | Allowed next status |
|---|
draft | open, archived |
open | active, archived |
active | completed, archived |
completed | archived |
archived | — |
An illegal move is a 400, not a 409: the request asks for something the
lifecycle does not have. archived carries its own effective date and reason.
| Role in the organization | This endpoint |
|---|
OWNER | Allowed |
ADMIN | Allowed |
MEMBER | Refused — 403 |
| Requirement | Rule for this endpoint |
|---|
| Business role | None |
| Resource scope | The cohort belongs to the key's organization |
| Participation | None |
| Resource state | The move is allowed by the table above |
| Parameter | Type | Required | Description |
|---|
cohortId | UUID | yes | Cohort of the key's organization |
| Header | Required | Description |
|---|
x-api-key | yes | API key created for this organization |
Idempotency-Key | yes | Stable key for this move; a replay returns the first result |
X-Correlation-Id | no | Caller correlation id, returned or generated |
Request body
| Field | Type | Required | Nullable | Description |
|---|
status | string | yes | no | open, active, completed or archived |
effectiveAt | string | no | no | Only with archived: when the archive takes effect, ISO date. Defaults to now |
reason | string | no | yes | Only with archived: up to 500 characters |
curl -X POST "$COHORTE_API_BASE_URL/api/v1/cohorts/$COHORT_ID/status" \
-H "x-api-key: $COHORTE_API_KEY" \
-H "Idempotency-Key: cohort-autumn-open" \
-H "Content-Type: application/json" \
-d '{"status": "open"}'
200 OK — the cohort in its new status. replayed: true when the key was already used.
400 Bad Request — missing Idempotency-Key, invalid JSON, an unknown status, or a move the lifecycle does not allow.
401 Unauthorized — missing, unknown or expired key.
403 Forbidden — the bearer is not OWNER or ADMIN.
404 Not Found — the cohort is unknown or belongs to another school.
Same fields as Create a cohort: id,
programId, name, status, startDate, endDate, timezone, capacity,
occupancy, overCapacity, phases[].
{
"success": true,
"replayed": false,
"data": {
"id": "3a1f7c2e-5b6d-4e8f-9a0b-1c2d3e4f5a6b",
"programId": "9f2c4a10-8f7e-4a3b-9c1d-2e5f6a7b8c9d",
"name": "Autumn cohort",
"status": "open",
"startDate": "2026-10-05T00:00:00.000Z",
"endDate": "2026-12-18T00:00:00.000Z",
"timezone": "Europe/Paris",
"capacity": 24,
"occupancy": 0,
"overCapacity": false,
"phases": []
},
"correlationId": "c0ffee00-1111-4222-8333-444455556666"
}
- Every move is recorded in the school's audit trail. Neither a status change nor an archive is a webhook event today.
- Enrollments are accepted until the cohort is
completed or archived; a closed cohort refuses them with 403.