POST /api/v1/programs/{programId}/restore
Restores an archived program to its verified previous status (active or draft). Enrollments, progress, submissions and history are preserved. Active programs become accessible again subject to existing publication, pause, payment, prerequisite and schedule rules. A previously draft program is not published by restoration.
An API key bound to the school and an owner or administrator in that school are required, with the same permissions as archival. MCP exposes restore_program with mcp:manage and the same current bearer permissions.
| Parameter | Required | Description |
|---|---|---|
programId | yes | Program UUID in the key's school |
x-api-key | yes | School API key |
Idempotency-Key | yes | Stable key for this restoration intention |
X-Correlation-Id | no | UUID used to trace the command |
Send {}. The previous status is determined from verified history, never from a client-selected status.
curl -X POST "$COHORTE_API_BASE_URL/api/v1/programs/$PROGRAM_ID/restore" \
-H "x-api-key: $COHORTE_API_KEY" \
-H "Idempotency-Key: restore-program-2026-10" \
-H 'Content-Type: application/json' -d '{}'200: the program projection, with success, data, correlationId and replayed.400: invalid request, program not archived, or previous status cannot be verified. No data changes on refusal.401: missing or invalid authentication.403: insufficient school permissions.404: unknown program or another school's program.409: the same idempotency key was used for a different intention.A retry returns the current program with replayed: true, without another restoration event. Replaying an old restoration after another archival does not restore again. Use a new key for a genuinely new restoration.
The status, audit record and program.restored event are committed together. No email is sent. No enrollment or progress record is recreated. Billing, dates and independent access restrictions are unchanged.
For older archives, the preceding status must be corroborated by history. Missing or contradictory history causes an explicit refusal; the application never guesses that the program should become active.