---
title: "Submit detection feedback"
method: POST
path: "/detect/{uuid}/feedback"
tags: ["deepfakeDetection"]
---

# Submit detection feedback

`POST /detect/{uuid}/feedback`

Tell Resemble whether a detection verdict was right — and when it wasn't, what it
should have been. The answer is stored with a snapshot of what the model said at the
time of submission (verdict, score, media type, raw metrics), so it stays interpretable
even if the detect is later re-run or deleted.

Upserts on `(detect, user)`: re-posting edits your existing answer rather than adding a
second one. There is no separate update call. Feedback is per user, not per team — a
teammate's answer on the same detect is invisible to you.

The detect must have completed processing; feedback on a pending or failed detect is
rejected with 400. Teams without Detect access also receive 400 (not 403).

## Path parameters

- `uuid` string, required

## Headers

- `Authorization` string, required

## Request body

- object
  - `type` 'correct' | 'should_be_ai_generated' | 'should_be_authentic' | 'should_be_non_ai' | 'should_be_neutral' | 'skipped', required — What the verdict should have been. - `correct` — the verdict was right. - `should_be_ai_generated` — we said authentic; it is AI-generated. - `should_be_authentic` — we said AI-generated; it is genuine and unaltered. - `should_be_non_ai` — no model generated it, but it may still be edited, spliced, or a human impersonation. - `should_be_neutral` — neither call is right; the media is genuinely ambiguous. - `skipped` — the verdict was wrong, but the reviewer didn't say how.
  - `comment` string — Free text, up to 1000 characters. Trimmed; blank becomes `null`.
  - `source` string — Where the answer came from. Use a stable, aggregatable value such as a product or queue name — not a per-request identifier. Truncated to 64 characters rather than rejected.

## Response `200`

Feedback recorded

- DeepfakeDetectionCreateDetectFeedbackResponse200
  - `success` boolean
  - `item` DetectFeedback — A reviewer's answer about a detection verdict, stored with a snapshot of what the model said at the time the answer was submitted. Returned by `POST /detect/{uuid}/feedback` and `GET /detect/{uuid}/feedback`.
    - `detect_uuid` string — The detect this answer is attached to.
    - `type` 'correct' | 'should_be_ai_generated' | 'should_be_authentic' | 'should_be_non_ai' | 'should_be_neutral' | 'skipped' — What the verdict should have been.
    - `vote` 'up' | 'down' — Derived from `type` — `correct` is `up`, everything else is `down`. Never independent of `type`.
    - `verdict` 'ai_generated' | 'authentic' — What the model said, snapshotted when the feedback was submitted. `null` when the detection landed somewhere indeterminate. `should_be_neutral` and `should_be_non_ai` have no counterpart here — this field records only the two decided model outcomes.
    - `score` number, double, nullable — The model's headline confidence, 0.0–1.0, or `null`. For video, the higher of the audio and video confidences.
    - `media_type` 'audio' | 'video' | 'image' | 'text' — Media type of the detect.
    - `comment` string, nullable — The reviewer's free-text comment, or `null`.
    - `credit` integer — Credits awarded for this answer. Written by Resemble, never by the submitter; `0` on a fresh row.
    - `source` string — Attribution string recorded for this answer. Defaults to `api`.
    - `created_at` string, date-time
    - `updated_at` string, date-time — Moves when the answer is revised; `created_at` does not.

## Other responses

- `400` — Unknown or missing `type`, `comment` over 1000 characters, the detect has not completed processing, or the team does not have Detect access.
- `404` — No such detect for the authenticated team.

---

[API](https://skmtc.dev/resemble/apis/api-reference.md) · [All operations](https://skmtc.dev/resemble/apis/api-reference/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/resemble/api-reference/revisions/e93597a6b425/schema)
