POST /api/v1/questions/{questionId}/answer
Answers a to_do question in one transaction: a resource of the
video library is published with kind
video_answer, the question's program, and the assigned coach as its
author, and the question becomes answered. The body is the body of
Publish a video resource
without programId, kind and category — an answer has no category
(null). The audit line records the real caller.
A question has one answer only. When its answer is unpublished, the question is
to_do again but cannot be answered a second time: republish or edit the
existing answer instead.
| Role in the organization | This endpoint |
|---|---|
OWNER | Allowed |
ADMIN | Allowed |
MEMBER | Allowed for an assigned coach, whatever the scope; otherwise refused — 403 |
| Requirement | Rule for this endpoint |
|---|---|
| Business role | coach (any scope) for a MEMBER; a reviewer is refused |
| Resource scope | Question, media and program of the key's organization |
| Participation | None |
| Resource state | The question is to_do with no answer yet; its program is not archived; the assigned person is still an owner or a coach |
| Parameter | Type | Required | Description |
|---|---|---|---|
questionId | UUID | yes | Question identifier |
| Header | Required | Description |
|---|---|---|
x-api-key | yes | API key created for this organization |
Idempotency-Key | yes | Stable key for this answer; a replay returns the same resource |
X-Correlation-Id | no | Caller correlation id, returned or generated |
| Field | Type | Required | Nullable | Description |
|---|---|---|---|---|
title | string | yes | no | 1 to 200 characters |
description | string | no | yes | Markdown, up to 10000 characters |
tags | string[] | no | no | Up to 10 tags of 1 to 40 characters |
videos | object[] | yes | no | 1 to 20 distinct videos, in display order |
videos[].mediaId | UUID | yes | no | A video media of the school |
videos[].title | string | no | yes | Line title, up to 200 characters |
thumbnailMediaId | UUID | no | yes | An image media of the school |
{
"title": "Validation belongs to the service",
"videos": [{"mediaId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"}]
}curl -X POST "$COHORTE_API_BASE_URL/api/v1/questions/8c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/answer" \
-H "x-api-key: $COHORTE_API_KEY" \
-H "Idempotency-Key: answer-validation-001" \
-H "Content-Type: application/json" \
-d '{"title":"Validation belongs to the service","videos":[{"mediaId":"9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"}]}'201 Created — the question, answered, and the published resource.200 OK — replayed: true: the key was already used, the same resource comes back.400 Bad Request — missing Idempotency-Key, invalid JSON, a field out of bounds, a media that is not a video (or not an image) of the school, an archived program, or an assigned person who is no longer an owner or a coach — assign another coach first.401 Unauthorized — missing, unknown or expired key.403 Forbidden — the bearer is neither OWNER, ADMIN nor an assigned coach.404 Not Found — no such question in this organization.409 Conflict — the question is cancelled or already has an answer.| Field | Type | Nullable | Description |
|---|---|---|---|
data.question | object | no | The question, with the fields of List received questions |
data.videoResource | object | no | The answer, with the fields of Publish a video resource |
{
"success": true,
"replayed": false,
"data": {
"question": {
"id": "8c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"programId": "3a1f7c2e-5b6d-4e8f-9a0b-1c2d3e4f5a6b",
"programName": "Agentic AI Developer",
"title": "Where should validation live?",
"body": "I hesitate between the server action and the service.",
"status": "answered",
"authorUserId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"authorName": "Léa Vasseur",
"assigneeUserId": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
"assigneeName": "Alice Moreau",
"answer": {
"videoResourceId": "6f2b1c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"title": "Validation belongs to the service",
"status": "published"
},
"cancellation": null,
"createdAt": "2026-10-18T10:00:00.000Z",
"updatedAt": "2026-10-18T11:00:00.000Z"
},
"videoResource": {
"id": "6f2b1c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"programId": "3a1f7c2e-5b6d-4e8f-9a0b-1c2d3e4f5a6b",
"kind": "video_answer",
"category": null,
"title": "Validation belongs to the service",
"description": null,
"tags": [],
"status": "published",
"thumbnailMediaId": null,
"createdBy": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
"publishedAt": "2026-10-18T11:00:00.000Z",
"unpublishedAt": null,
"createdAt": "2026-10-18T11:00:00.000Z",
"updatedAt": "2026-10-18T11:00:00.000Z"
}
},
"correlationId": "c0ffee00-1111-4222-8333-444455556666"
}video_resource.created event, then the question with a video_question.answered event — both audited under the real caller. No email and no in-app notification are sent.409 and publishes nothing.