POST /api/v1/lessons/{lessonId}/discussion/comments
Posts a comment under a lesson, as the key's holder. The first comment opens the lesson's thread in the first active community space of the program: the thread carries the lesson's title, is signed by the lesson's author (or the school's owner), and links back to the lesson. The comment is its first reply. Every later comment replies in that same thread, even when two members comment at the same moment.
| Role in the organization | This endpoint |
|---|---|
OWNER | Allowed — as when previewing the program |
ADMIN | Allowed — as when previewing the program |
MEMBER | Conditional — on a lesson its own enrollment lets it read |
| Requirement | Rule for this endpoint |
|---|---|
| Business role | None |
| Resource scope | The lesson belongs to the key's organization |
| Participation | For a MEMBER: an enrollment that can read the lesson, and the right to post in the program's community space |
| Resource state | Published lesson; the program has an active community space |
| Parameter | Type | Required | Description |
|---|---|---|---|
lessonId | UUID | yes | Lesson 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 comment; a replay returns the first comment |
X-Correlation-Id | no | Caller correlation id, returned or generated |
| Field | Type | Required | Nullable | Description |
|---|---|---|---|---|
body | string | yes | no | Markdown, 1 to 10000 characters |
parentReplyId | UUID | no | no | A first-level comment of the lesson's thread; refused before the first comment |
curl -X POST "$COHORTE_API_BASE_URL/api/v1/lessons/$LESSON_ID/discussion/comments" \
-H "x-api-key: $COHORTE_API_KEY" \
-H "Idempotency-Key: lesson-question-3" \
-H "Content-Type: application/json" \
-d '{"body": "Question 3 is where I get stuck — how do you phrase it on a cold call?"}'201 Created — the comment; threadCreated: true when it opened the lesson's thread.200 OK — replayed: true: the key was already used, the original comment comes back.400 Bad Request — missing Idempotency-Key, invalid JSON, a body out of bounds, a parentReplyId with no thread yet, an unpublished lesson, or a program without a community space.401 Unauthorized — missing, unknown or expired key.403 Forbidden — the holder cannot post in the program's community space.404 Not Found — the lesson is unknown, belongs to another school, or the key's holder cannot read it.409 Conflict — the lesson's thread changed space meanwhile; read the discussion again.| Field | Type | Nullable | Description |
|---|---|---|---|
success | boolean | no | true |
replayed | boolean | no | true on a replay of the same key |
data.threadId | UUID | no | The lesson's thread |
data.threadCreated | boolean | no | true when this comment opened it |
data.reply.id | UUID | no | Comment id |
data.reply.threadId | UUID | no | Its thread |
data.reply.parentReplyId | UUID | yes | The comment it answers, or null |
data.reply.body | string | no | As posted |
data.reply.authorUserId | UUID | no | The key's holder |
data.reply.createdAt | string | no | ISO 8601, UTC |
{
"success": true,
"replayed": false,
"data": {
"threadId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f6a",
"threadCreated": true,
"reply": {
"id": "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b",
"threadId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f6a",
"parentReplyId": null,
"body": "Question 3 is where I get stuck — how do you phrase it on a cold call?",
"authorUserId": "22222222-2222-4222-8222-222222222222",
"createdAt": "2026-10-19T08:35:00.000Z"
}
},
"correlationId": "c0ffee00-1111-4222-8333-444455556666"
}