POST /api/v1/programs/{programId}/member-tasks
Defines a task on a program. With a milestoneId, the task belongs to that
step of the path; without one, members see it under Other actions. The task
is created in draft: members do not see it until you publish it.
| Role in the organization | This endpoint |
|---|---|
OWNER | Allowed |
ADMIN | Allowed |
MEMBER | Refused — 403 |
| Requirement | Rule for this endpoint |
|---|---|
| Business role | None — a task is defined by whoever may change the program |
| Resource scope | Program of the school attached to the API key; the milestone, if given, must belong to that program |
| Participation | None |
| Resource state | An archived program refuses every write, and answers 403 |
| Parameter | Type | Required | Description |
|---|---|---|---|
programId | UUID | yes | Program visible from the key's school |
| Header | Required | Description |
|---|---|---|
x-api-key | yes | API key created for this school |
Idempotency-Key | yes | Stable key for this creation intention |
X-Correlation-Id | no | Caller correlation id, returned or generated |
| Field | Type | Required | Nullable | Description |
|---|---|---|---|---|
title | string | yes | no | 3 to 100 characters |
milestoneId | UUID | no | yes | The milestone this task belongs to. Omitted or null: the task stands on its own |
instructions | string | no | yes | What to do, up to 2000 characters |
context | string | no | yes | Why it matters, up to 2000 characters |
requirement | string | no | no | required (default), recommended or optional |
dueOffsetDays | integer | no | yes | Deadline in days after the member's enrollment, 0 to 730 |
dueAt | ISO 8601 string | no | yes | A fixed deadline, the same for every member |
dueOffsetDays and dueAt are mutually exclusive: a task has at most one
deadline rule, and may have none.
{
"title": "Ship your landing page",
"milestoneId": "7a0c9e1b-0000-4000-8000-000000000000",
"instructions": "Publish a landing page for your offer and share its URL.",
"requirement": "required",
"dueOffsetDays": 14
}curl -X POST "$COHORTE_API_BASE_URL/api/v1/programs/$PROGRAM_ID/member-tasks" \
-H "x-api-key: $COHORTE_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H 'Content-Type: application/json' \
-d '{"title":"Ship your landing page","milestoneId":"'"$MILESTONE_ID"'","dueOffsetDays":14}'201 Created — the task exists, in draft.200 OK — the same Idempotency-Key replayed the original creation; replayed is true.400 Bad Request — missing Idempotency-Key, invalid JSON, a field outside its limits, both deadline rules at once, or a milestone that does not belong to this program.401 Unauthorized — the key is missing, invalid, or no longer attached to a member.403 Forbidden — the bearer is not OWNER or ADMIN, or the program is archived.404 Not Found — the program is unknown or belongs to another school.| Field | Type | Nullable | Description |
|---|---|---|---|
success | boolean | no | true for a successful request |
data.id | UUID | no | Task identifier |
data.programId | UUID | no | Program that carries it |
data.milestoneId | UUID | yes | Its milestone, or null for a task under Other actions |
data.title | string | no | Task title |
data.instructions | string | yes | What to do |
data.context | string | yes | Why it matters |
data.requirement | string | no | required, recommended or optional |
data.dueOffsetDays | integer | yes | Days after enrollment, when the deadline is relative |
data.dueAt | ISO 8601 string | yes | The fixed deadline, in UTC, when there is one |
data.status | string | no | draft, published or archived |
data.createdAt | ISO 8601 string | no | Creation time, in UTC |
data.updatedAt | ISO 8601 string | no | Last change, in UTC |
replayed | boolean | no | true when this answer replays an earlier call |
correlationId | UUID | no | Correlation id for support |
{
"success": true,
"data": {
"id": "c3f1d2a4-0000-4000-8000-000000000000",
"programId": "4d19c0a2-0000-4000-8000-000000000000",
"milestoneId": "7a0c9e1b-0000-4000-8000-000000000000",
"title": "Ship your landing page",
"instructions": "Publish a landing page for your offer and share its URL.",
"context": null,
"requirement": "required",
"dueOffsetDays": 14,
"dueAt": null,
"status": "draft",
"createdAt": "2026-09-24T08:00:00.000Z",
"updatedAt": "2026-09-24T08:00:00.000Z"
},
"replayed": false,
"correlationId": "b0e7f1c2-1d3a-4a52-9f77-52a4b7c3d1e0"
}member_task.created event are written in
one transaction. A replay writes none of them a second time.dueOffsetDays: 14 is
resolved per member, from each one's enrollment date.