# Comment on a film

`POST https://api.cream-ai.de/api/v1/films/{id}/comments`

Adds a comment to the latest finished revision of a film, at a time (`at_s`) and optionally a point (`x`, `y`) in the picture. `at_s` is the time in the film **without** the brand intro: if you play the approved file with an intro, subtract the intro length. `message` has 1–2000 characters. `attachments` are up to 5 ids of uploads of your company (`POST /uploads`); each use extends the upload's expiry. Comments are only possible on the latest finished revision: with `revision` set to an older one, or if a newer revision is finished in the meantime, the answer is `409 revision_locked` with `details.latest_revision`. Without a finished film: `409 film_not_ready`. The comment changes nothing by itself; `POST /films/{id}/comments/apply` applies the open comments as a new revision. A film cancelled through the API (`status: cancelled`) takes no more comments: `409 film_cancelled`.

Scopes: `feedback:write`

## Parameters

- `id` (path, required): Id of the film (id from POST /films or GET /films).
- `Idempotency-Key` (header, required): Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

## Request body

- `at_s` (number, required): Time in the film in seconds, without the brand intro.
- `x` (nullable number): Optional horizontal position (0–1).
- `y` (nullable number): Optional vertical position (0–1).
- `message` (string, required): Text of the comment (trimmed).
- `attachments` (nullable array of strings): Up to 5 upload ids of your company. Unknown ids and uploads of other companies: 400 upload_not_found; expired: 410 upload_expired.
- `revision` (nullable integer): Optional: the revision you commented on. If it is not the latest finished one, the answer is 409 revision_locked.

## Returns

- 201: The new comment.

## Errors

- 400: Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).
- 401: Missing, malformed, revoked or expired API key (unauthorized).
- 403: Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).
- 404: Not found (not_found).
- 409: revision_locked (details.latest_revision), film_not_ready or film_cancelled (the film was cancelled through the API).
- 410: An upload in attachments has expired (upload_expired, field names it).
- 413: Request body too large (payload_too_large).
- 415: Request body is not JSON (unsupported_media_type).
- 422: Idempotency-Key reused with a different request (idempotency_mismatch).
- 429: Too many requests (rate_limited).
- 500: Internal error (internal). Quote the request id when you contact support.
- 503: Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

## Example request

```sh
curl -X POST "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/comments" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "at_s": 42.5,
    "x": 0.62,
    "y": 0.31,
    "message": "The chart should show 2026, not 2025.",
    "attachments": [
      "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f"
    ]
  }'
```

## Example response (201)

```json
{
  "object": "comment",
  "id": "cmt_9QwX2rLm7Tz",
  "revision": 2,
  "at_s": 42.5,
  "x": 0.62,
  "y": 0.31,
  "scene": 5,
  "message": "The chart should show 2026, not 2025.",
  "author": {
    "kind": "api",
    "name": "Learning platform",
    "email": null
  },
  "status": "open",
  "result": null,
  "attachments": [
    {
      "upload_id": "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f",
      "media_id": "md_77120"
    }
  ],
  "created_at": "2026-11-11T15:02:19Z",
  "updated_at": "2026-11-11T15:02:19Z"
}
```
