Submit Detection Job

POST https://app.resemble.ai/api/v2/detect

By default the request is asynchronous. The API responds immediately with a job UUID while analysis continues in the background. Include Prefer: wait to block until completion.

You can supply media in one of three ways:

  • Direct file upload — POST a multipart/form-data request with the file attached as file. Best for one-off requests against files up to 150 MB.
  • Public URL — pass url when the media is already hosted at a publicly reachable HTTPS address. No upload size limit on this path because the API fetches the URL itself.
  • Secure upload token — upload the file first via POST /secure_uploads and pass the returned token as media_token. Use this when you do not want to host the source file publicly, or when the file is larger than the 150 MB direct-upload cap. The token is a short-lived JWT that expires 1 hour after issuance.

Exactly one of file, url, or media_token must be provided per request.

Using a direct file upload

$curl --request POST 'https://app.resemble.ai/api/v2/detect' \
> -H 'Authorization: Bearer YOUR_API_TOKEN' \
> -H 'Prefer: wait' \
> -F 'file=@/path/to/media.mp4' \
> -F 'callback_url=https://example.com/webhooks/detect' \
> -F 'intelligence=true' \
> -F 'visualize=true' \
> -F 'frame_length=2'

Optional parameters (callback_url, intelligence, visualize, etc.) are sent as additional form fields when uploading directly.

File constraints

ConstraintValue
Maximum size150 MB. Larger files must use the Secure Uploads API instead.
Allowed extensions.wav, .mp3, .m4a, .ogg, .aac, .flac, .amr, .3gp, .3gpp, .mp4, .mov, .avi, .mkv, .webm, .jpg, .jpeg, .png, .gif, .webp
Allowed content typesaudio/*, video/*, image/* matching the extensions above. application/octet-stream is accepted when paired with a recognized extension.
Empty filesRejected with HTTP 400.

Requests outside these constraints are rejected with HTTP 400 before any analysis or billing runs. The size-limit error response includes a pointer to the Secure Uploads API as the recommended path for larger uploads.

Using a public URL

$curl --request POST 'https://app.resemble.ai/api/v2/detect' \
> -H 'Authorization: Bearer YOUR_API_TOKEN' \
> -H 'Prefer: wait' \
> -H 'Content-Type: application/json' \
> --data '{
> "url": "https://example.com/media.mp4",
> "callback_url": "https://example.com/webhooks/detect",
> "intelligence": true,
> "visualize": true,
> "frame_length": 2
> }'

Using a secure upload token

First, upload the file to obtain a token (see Secure Upload):

$curl --request POST 'https://app.resemble.ai/api/v2/secure_uploads' \
> -H 'Authorization: Bearer YOUR_API_TOKEN' \
> -F 'file=@/path/to/media.mp4'

Then submit the detect job using the returned token as media_token:

$curl --request POST 'https://app.resemble.ai/api/v2/detect' \
> -H 'Authorization: Bearer YOUR_API_TOKEN' \
> -H 'Content-Type: application/json' \
> --data '{
> "media_token": "eyJhbGciOiJIUzI1NiJ9...",
> "callback_url": "https://example.com/webhooks/detect"
> }'

Media Source

Provide exactly one of the following.

FieldDescription
fileA media file uploaded as multipart/form-data. Maximum 150 MB; allowed extensions are .wav, .mp3, .m4a, .ogg, .aac, .flac, .amr, .3gp, .3gpp, .mp4, .mov, .avi, .mkv, .webm, .jpg, .jpeg, .png, .gif, .webp. For files over 150 MB, use media_token.
urlPublic HTTPS URL to the media to analyze (wav, mp3, ogg, m4a, aac, flac, amr, 3gp, 3gpp, mp4, mov, avi, mkv, webm, jpg, jpeg, png, gif, webp).
media_tokenToken returned by POST /secure_uploads. Valid for 1 hour after upload.

Optional Parameters

FieldApplies ToDescription
callback_urlAllPOST destination when analysis completes. Payload matches the standard response.
visualizeAllGenerate visualization artifacts (images/treeview).
frame_lengthAudio & VideoWindow size in seconds (14, default 2).
start_region / end_regionAudio & VideoAnalyze a segment (seconds).
max_video_secsVideoCap processed duration.
model_typesVideoimage or talking_head. Use talking_head for face-swaps.
intelligenceAllBoolean. Run multimodal intelligence analysis on the media. Returns speaker info, transcription, emotion, abnormalities, misinformation, and anti-cheating indicators. Default: false.
audio_source_tracingAudioBoolean. Enable audio source tracing to identify the origin of synthetic audio (e.g., Resemble AI, ElevenLabs). Default: false.
use_reverse_searchImageBoolean. Enable reverse image search to improve detection accuracy. Searches the web for matching images and uses AI to classify whether the match indicates a known fake. Default: false.
use_ood_detectorAudioBoolean. Enable out-of-distribution detection. Default: false.
zero_retention_modeAllBoolean. Enable zero retention mode to automatically delete the submitted media file after detection completes. When enabled, media URLs are redacted from all responses and the filename is tokenized. Default: false.

Response

Asynchronous Response

By default, the API responds immediately while processing continues in the background:

1{
2 "success": true,
3 "item": {
4 "uuid": "DETECTION_UUID",
5 "metrics": {},
6 "created_at": "2024-01-15T10:30:00Z",
7 "updated_at": "2024-01-15T10:30:00Z",
8 "media_type": "audio",
9 "intelligence": null
10 }
11}

Use the UUID to check status via the Get Detection Result endpoint, or provide a callback_url to receive results automatically.

Synchronous Response (with Prefer: wait header)

When using the Prefer: wait header, the API returns complete results immediately:

Audio File Response

1{
2 "success": true,
3 "item": {
4 "uuid": "DETECTION_UUID",
5 "metrics": {
6 "image": "",
7 "label": "fake",
8 "score": ["0.9", "0.8", "0.7"],
9 "consistency": "0.85",
10 "aggregated_score": "0.80"
11 },
12 "created_at": "2024-01-15T10:30:00Z",
13 "updated_at": "2024-01-15T10:30:05Z",
14 "duration": "5.2",
15 "media_type": "audio",
16 "intelligence": {
17 "description": "Adult male speaker with confident tone...",
18 "created_at": "2024-01-15T10:30:05Z"
19 }
20 }
21}

Image File Response

1{
2 "success": true,
3 "item": {
4 "uuid": "DETECTION_UUID",
5 "metrics": {},
6 "created_at": "2024-01-15T10:30:00Z",
7 "updated_at": "2024-01-15T10:30:02Z",
8 "url": "https://example.com/image.jpg",
9 "duration": "5.0",
10 "media_type": "image",
11 "image_metrics": {
12 "ifl": {
13 "score": 1,
14 "heatmap": "https://..."
15 },
16 "type": "FinalResult",
17 "image": "https://...",
18 "label": "Fake",
19 "score": 1,
20 "children": []
21 },
22 "intelligence": {
23 "uuid": "INTELLIGENCE_UUID",
24 "description": "...",
25 "created_at": "2024-01-15T10:30:02Z",
26 "detect_uuid": "DETECTION_UUID"
27 },
28 "visualize": false,
29 "audio_source_tracing_enabled": false,
30 "use_ood_detector": false,
31 "filename": "image.jpg",
32 "extra_params": {
33 "search_identity_requested": false
34 },
35 "status": "completed",
36 "audio_url": "https://example.com/image.jpg",
37 "zero_retention_mode": false,
38 "file_deleted_at": null
39 }
40}

When use_reverse_search is enabled, the image_metrics object includes a reverse_image_search_sources array containing web sources that matched the submitted image, along with a verdict and similarity score for each:

$curl --request POST 'https://app.resemble.ai/api/v2/detect' \
> -H 'Authorization: Bearer YOUR_API_TOKEN' \
> -H 'Prefer: wait' \
> -H 'Content-Type: application/json' \
> --data '{
> "url": "https://example.com/image.jpg",
> "intelligence": true,
> "use_reverse_search": true
> }'
1{
2 "success": true,
3 "item": {
4 "uuid": "DETECTION_UUID",
5 "metrics": {},
6 "created_at": "2024-01-15T10:30:00Z",
7 "updated_at": "2024-01-15T10:30:12Z",
8 "url": "https://example.com/image.jpg",
9 "duration": "5.0",
10 "media_type": "image",
11 "image_metrics": {
12 "ifl": {
13 "score": 1,
14 "heatmap": "https://..."
15 },
16 "type": "FinalResult",
17 "image": "https://...",
18 "label": "Fake",
19 "score": 1,
20 "children": [],
21 "reverse_image_search_sources": [
22 {
23 "url": "https://example-stock-site.com/ai-generated-images/",
24 "title": "example-stock-site.com",
25 "reason": "This exact image is hosted on a stock photography site and labeled as a 'Premium AI-generated image'.",
26 "verdict": "known_fake",
27 "similarity": 1
28 },
29 {
30 "url": "https://another-stock-site.com/search/ai-art",
31 "title": "another-stock-site.com",
32 "reason": "The site lists near-identical variations of this image, explicitly labeling them as AI generated.",
33 "verdict": "known_fake",
34 "similarity": 0.9
35 }
36 ]
37 },
38 "intelligence": {
39 "uuid": "INTELLIGENCE_UUID",
40 "description": "...",
41 "created_at": "2024-01-15T10:30:12Z",
42 "detect_uuid": "DETECTION_UUID"
43 },
44 "visualize": false,
45 "audio_source_tracing_enabled": false,
46 "use_ood_detector": false,
47 "filename": "image.jpg",
48 "extra_params": {
49 "use_reverse_search": true,
50 "search_identity_requested": false
51 },
52 "status": "completed",
53 "audio_url": "https://example.com/image.jpg",
54 "zero_retention_mode": false,
55 "file_deleted_at": null
56 }
57}

Video File Response

1{
2 "success": true,
3 "item": {
4 "uuid": "DETECTION_UUID",
5 "metrics": {
6 "image": "https://...",
7 "label": "fake",
8 "score": ["0.9", "0.8", "0.7"],
9 "consistency": "0.85",
10 "aggregated_score": "0.80"
11 },
12 "created_at": "2024-01-15T10:30:00Z",
13 "updated_at": "2024-01-15T10:30:10Z",
14 "duration": "10.5",
15 "media_type": "video",
16 "video_metrics": {
17 "label": "Fake",
18 "score": 0.95,
19 "certainty": 0.93,
20 "treeview": "...",
21 "children": [
22 {
23 "type": "VideoResult",
24 "conclusion": "Fake",
25 "score": 0.99,
26 "certainty": 0.9,
27 "certainty (%)": "90.0",
28 "children": [
29 {
30 "type": "ImageResult",
31 "conclusion": "Fake",
32 "score": 0.9,
33 "certainty": 0.95,
34 "certainty (%)": "95.0",
35 "timestamp": 0.23,
36 "children": [
37 {
38 "type": "Segment",
39 "conclusion": "Fake",
40 "score": 0.9,
41 "certainty": 0.995,
42 "certainty (%)": "99.5"
43 }
44 ]
45 }
46 ]
47 }
48 ]
49 },
50 "intelligence": {
51 "description": "Video contains an adult male speaker with confident tone...",
52 "created_at": "2024-01-15T10:30:10Z"
53 }
54 }
55}

Zero Retention Mode

When zero_retention_mode=true, the API enables a privacy lifecycle for the submitted media:

  • URL redaction: url and audio_url are set to null in all responses, both during processing and after completion.
  • Filename tokenization: The original filename is replaced with a tokenized value (e.g., redacted_abc123def4567890abcd1234.mp3).
  • Media deletion: After detection completes (including any downstream tasks like intelligence or source tracing), the uploaded file is permanently deleted from storage. The file_deleted_at timestamp is set once the purge succeeds.
  • Downstream records: Related records (intelligence, source tracing, identity) are still created but do not store copies of the media.

Zero Retention Mode is request-driven only — team-level or UI defaults are not applied to API requests. You must explicitly pass zero_retention_mode: true on each request.

Zero Retention Mode Request Example

$curl --request POST 'https://app.resemble.ai/api/v2/detect' \
> -H 'Authorization: Bearer YOUR_API_TOKEN' \
> -H 'Prefer: wait' \
> -H 'Content-Type: application/json' \
> --data '{
> "url": "https://example.com/media.mp4",
> "zero_retention_mode": true,
> "intelligence": true
> }'

Zero Retention Mode Response Example

1{
2 "success": true,
3 "item": {
4 "uuid": "DETECTION_UUID",
5 "zero_retention_mode": true,
6 "file_deleted_at": null,
7 "url": null,
8 "audio_url": null,
9 "filename": "redacted_abc123def4567890abcd1234.mp3",
10 "metrics": {
11 "label": "fake",
12 "score": ["0.9", "0.8", "0.7"],
13 "consistency": "0.85",
14 "aggregated_score": "0.80"
15 },
16 "media_type": "audio",
17 "created_at": "2024-01-15T10:30:00Z",
18 "updated_at": "2024-01-15T10:30:05Z"
19 }
20}

Once the media file has been purged, file_deleted_at is populated with the purge timestamp:

1{
2 "zero_retention_mode": true,
3 "file_deleted_at": "2024-01-15T10:31:00Z",
4 "url": null,
5 "audio_url": null,
6 "filename": "redacted_abc123def4567890abcd1234.mp3"
7}

Callback URL

If you provide a callback_url when submitting a media file, you will receive a POST request to that URL with the same payload structure as the synchronous response shown above. When intelligence analysis was requested, the callback payload will include the intelligence field with the analysis results.