> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.resemble.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.resemble.ai/_mcp/server.

# Detect Your First Deepfake

Submit an audio, image, or video file to Resemble Detect, wait for the analysis to finish, and read the authenticity verdict.

## What You Will Build

This walkthrough uses the asynchronous API workflow:

1. Submit a local media file.
2. Save the detection UUID.
3. Poll the detection until it reaches a terminal status.
4. Read the result for the submitted media type.

## Prerequisites

* A Resemble API token with Deepfake Detection access
* A local audio, image, or video file smaller than 150 MB
* `curl` and [`jq`](https://jqlang.github.io/jq/)

Set your API token and the path to your test file:

```bash
export RESEMBLE_API_TOKEN="YOUR_API_TOKEN"
export MEDIA_PATH="/path/to/media.mp4"
```

## 1. Submit the Media

Send the file as `multipart/form-data`:

```bash
DETECT_RESPONSE=$(curl --silent --show-error --fail-with-body \
  --request POST 'https://app.resemble.ai/api/v2/detect' \
  -H "Authorization: Bearer ${RESEMBLE_API_TOKEN}" \
  -F "file=@${MEDIA_PATH}")

echo "${DETECT_RESPONSE}" | jq
```

The API returns immediately while the analysis runs. Save the detection UUID from the response:

```bash
export DETECT_UUID=$(echo "${DETECT_RESPONSE}" | jq -r '.item.uuid')
echo "Detection UUID: ${DETECT_UUID}"
```

> **Note**
>
> Provide exactly one media source per request. In addition to a direct file upload, the API accepts a public `url` or a token from [Secure Upload](/detect/secure-uploads).

## 2. Wait for the Result

Poll the detection endpoint until the job is complete or has failed:

```bash
while true; do
  DETECT_RESULT=$(curl --silent --show-error --fail-with-body \
    --request GET \
    "https://app.resemble.ai/api/v2/detect/${DETECT_UUID}" \
    -H "Authorization: Bearer ${RESEMBLE_API_TOKEN}")

  STATUS=$(echo "${DETECT_RESULT}" | jq -r '.item.status')
  echo "Status: ${STATUS}"

  case "${STATUS}" in
    completed) break ;;
    failed)
      echo "${DETECT_RESULT}" | jq
      exit 1
      ;;
  esac

  sleep 3
done
```

Print the completed response:

```bash
echo "${DETECT_RESULT}" | jq
```

For production workloads, use a `callback_url` instead of polling continuously. For a one-off synchronous request, add the `Prefer: wait` header when submitting the detection.

## 3. Read the Verdict

The result fields depend on the media type:

| Media | Primary result                          | Useful fields                                                        |
| ----- | --------------------------------------- | -------------------------------------------------------------------- |
| Audio | `item.metrics`                          | `label`, `aggregated_score`, `consistency`                           |
| Image | `item.image_metrics`                    | `label`, `score`, `heatmap` when visualization is enabled            |
| Video | `item.metrics` and `item.video_metrics` | Separate audio and visual findings when both modalities are analyzed |

For audio, print a compact summary:

```bash
echo "${DETECT_RESULT}" | jq '{
  uuid: .item.uuid,
  media_type: .item.media_type,
  label: .item.metrics.label,
  score: .item.metrics.aggregated_score
}'
```

For an image:

```bash
echo "${DETECT_RESULT}" | jq '{
  uuid: .item.uuid,
  media_type: .item.media_type,
  label: .item.image_metrics.label,
  score: .item.image_metrics.score
}'
```

For a video, inspect both audio and visual findings. If the request used `modality=audio` or `modality=video`, the skipped result object is absent.

> **Warning**
>
> Use the returned label and supporting metrics together with your application context. Detection scores should inform a review workflow rather than act as the only basis for a consequential decision.

## Troubleshooting

| Response           | What to check                                                                                   |
| ------------------ | ----------------------------------------------------------------------------------------------- |
| `400 Bad Request`  | The file is empty, unsupported, larger than 150 MB, or more than one media source was supplied. |
| `401 Unauthorized` | The API token is missing or invalid.                                                            |
| `403 Forbidden`    | The account does not have Deepfake Detection access.                                            |
| `status: failed`   | Inspect the response for the job's error message and confirm that the source media is readable. |

## Extend the Workflow

* Use [Secure Upload](/detect/secure-uploads) for private or larger media.
* Enable [Intelligence](/detect/intelligence) to generate a richer description of the content.
* Use [Batch Detection](/detect/batch) when processing many files.
* Review the complete [Submit Detection Job](/detect/create) and [Get Detection Result](/detect/get) contracts.