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 the requested Detect work completes, including watermark analysis when detect_watermark=true.

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 'detect_watermark=true' \
> -F 'wait_for_intelligence=true' \
> -F 'infer_from_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.
Maximum size with detect_watermark=true25 MB for audio/image and 100 MB for video. Secure uploads do not bypass these Watermark decoder limits.
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,
> "detect_watermark": true,
> "wait_for_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",
> "detect_watermark": true
> }'

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.
wait_for_intelligenceAllBoolean. Controls callback timing when callback_url and intelligence=true are provided. Set true to wait until both Detect and Intelligence are finished, or false to send after Detect finishes without waiting for Intelligence. When omitted, callbacks use the standard wait of up to 10 minutes.
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.
modalityVideoaudio, video, or all (default). Selects which components of a video to analyze — see Selecting which modality to analyze. Ignored for audio and image inputs.
face_onlyVideoBoolean. Focus visual detection on faces by masking non-face regions. Effective with modality=all or modality=video. Default: false.
intelligenceAllBoolean. Run multimodal intelligence analysis on the media. Returns speaker info, transcription, emotion, abnormalities, misinformation, and anti-cheating indicators. Default: false.
detect_watermarkAudio, Video & ImageBoolean. Run Resemble watermark detection and SynthID. Adds one Watermark detection charge. Uses source limits of 25 MB for audio/image and 100 MB for video. Single-file requests only; default: false.
infer_from_intelligenceAllBoolean. Opt in to let a strong intelligence finding escalate an otherwise non-fake verdict to Likely Fake. Has no effect unless intelligence is also true. Default: false.
audio_source_tracingAudioBoolean. Enable audio source tracing to identify the origin of synthetic audio (e.g., Resemble AI, ElevenLabs). Default: false.
signalAudio, Video & ImageBoolean. Run Signal content analysis after detection completes, classifying the media against fraud and abuse categories. Requires Signal access on your plan and cannot be combined with zero_retention_mode. Not supported for batch. 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.

Selecting which modality to analyze (video)

A video file contains both an audio track and visual frames, and by default both are analyzed independently — the response carries an audio verdict in metrics and a visual verdict in video_metrics. Use the modality parameter to run only one of them:

modalityWhat runsPopulated metrics
all (default)Audio and video analysismetrics and video_metrics
audioAudio track onlymetrics only (video_metrics is absent)
videoVisual frames onlyvideo_metrics only (metrics is absent)

Notes:

  • modality applies to video inputs only. It is accepted but ignored for audio and image files (those always run their single modality).
  • The skipped modality is not analyzed and not billed. A single-modality detect reaches status: "completed" as soon as the requested modality finishes, unless requested watermark analysis is still processing. Watermark analysis follows the media container type, so a video always uses the video watermark detector regardless of this setting.
  • Omitting modality preserves the previous behavior (both modalities run).
  • An invalid value is rejected with HTTP 400 before any analysis or billing runs.
$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 'modality=audio'

Focusing visual analysis on faces (video)

Set face_only=true to focus the visual model on faces by masking non-face regions before analysis. It is effective only for video inputs when visual analysis runs (modality=all or modality=video). It does not disable or modify audio analysis.

Audio, image, and modality=audio video requests may include the parameter, but the effective value returned by the API is false. The parameter does not change billing, the selected modality, or the detection report structure.

$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 'modality=all' \
> -F 'face_only=true'

The same boolean field is supported in JSON requests that use a public url or a secure-upload media_token. Create, Get, List, and individual-detection webhook payloads expose face_only as the effective value applied to the detection.

Adding Watermark Analysis

Set detect_watermark=true to run watermark decoding alongside deepfake detection. This is detection-only; the Detect API does not expose watermark application, strength, or custom-message parameters.

Media typeWatermark checks
AudioResemble Perth v1, Resemble Perth v2, and SynthID
ImageResemble image watermark detector and SynthID
VideoResemble video watermark detector and SynthID

The nested watermark.metrics.overall_status and watermark.metrics.has_watermark fields summarize the Resemble detector result. watermark.metrics.synthid, when present, is the boolean returned by SynthID. These signals are independent: neither one changes the deepfake score or verdict. If SynthID is unavailable, synthid is omitted rather than returned as false.

The option requires Watermark detection access and adds the existing Watermark detection charge to the Detect request. SynthID is included in that operation and is not charged separately. Requests without the option preserve the existing Detect cost and response shape.

Use the JSON boolean true/false, or the exact form-data value true/false. Other values return HTTP 400. If the API key does not have Watermark detection access, the request returns HTTP 403 before creating the Detect or Watermark job.

Watermark analysis is limited to single-file audio, image, and video requests. POST /detect/batch rejects detect_watermark=true with HTTP 400. The source limit is 25 MB for audio/image and 100 MB for video, including when the source is referenced by URL or media_token.

Known oversized uploads and secure-upload tokens are rejected before provider work. If a remote source’s size is only discovered while it is being resolved, the nested Watermark analysis can fail while the core deepfake detection continues normally.

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 "status": "processing",
6 "metrics": {},
7 "created_at": "2024-01-15T10:30:00Z",
8 "updated_at": "2024-01-15T10:30:00Z",
9 "media_type": "audio",
10 "face_only": false,
11 "intelligence": null,
12 "watermark": {
13 "status": "pending"
14 }
15 }
16}

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

When detect_watermark=true, an otherwise successful Detect remains processing until Watermark analysis is terminal. A core detection failure still reports failed. A Watermark failure is terminal and appears inside item.watermark; it does not fail an otherwise successful deepfake detection. Intelligence remains a separate processing stage and may still be processing after item.status becomes completed. Use the nested item.intelligence fields—or GET /detect/{uuid}?experts=true for all successfully completed Intelligence results—to monitor Intelligence separately.

Completed audio, image, and video responses can include c2pa_manifest after Content Credentials verification runs. validation_state: "Valid" includes the manifest details returned by C2PA tooling, NotPresent means no embedded Content Credentials were found, and Unavailable means C2PA verification could not complete. C2PA verification failures do not fail the detect job.

Synchronous Response (with Prefer: wait header)

When using the Prefer: wait header, the API returns after the requested Detect work is terminal. If detect_watermark=true, the response waits for both core detection and watermark analysis:

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 "face_only": false,
17 "c2pa_manifest": {
18 "validation_state": "NotPresent"
19 },
20 "watermark": {
21 "status": "completed",
22 "metrics": {
23 "overall_status": "absent",
24 "detected_model_versions": [],
25 "coverage_complete": true,
26 "has_watermark": {
27 "channel_0": false
28 },
29 "confidence": 0.0,
30 "model_results": [
31 {
32 "model_version": "perth_v1",
33 "status": "succeeded",
34 "detected": false,
35 "has_watermark": {
36 "channel_0": false
37 },
38 "confidence": 0.0
39 },
40 {
41 "model_version": "perth_v2",
42 "status": "succeeded",
43 "detected": false,
44 "has_watermark": {
45 "channel_0": false
46 },
47 "confidence": 0.0
48 }
49 ],
50 "synthid": false
51 }
52 },
53 "intelligence": {
54 "uuid": "INTELLIGENCE_UUID",
55 "status": "completed",
56 "error_message": null,
57 "description": "Adult male speaker with confident tone...",
58 "created_at": "2024-01-15T10:30:05Z",
59 "detect_uuid": "DETECTION_UUID"
60 }
61 }
62}

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 "face_only": false,
12 "image_metrics": {
13 "ifl": {
14 "score": 1,
15 "heatmap": "https://..."
16 },
17 "type": "FinalResult",
18 "image": "https://...",
19 "label": "Fake",
20 "score": 1,
21 "children": []
22 },
23 "intelligence": {
24 "uuid": "INTELLIGENCE_UUID",
25 "status": "completed",
26 "error_message": null,
27 "description": "...",
28 "created_at": "2024-01-15T10:30:02Z",
29 "detect_uuid": "DETECTION_UUID"
30 },
31 "visualize": false,
32 "audio_source_tracing_enabled": false,
33 "use_ood_detector": false,
34 "filename": "image.jpg",
35 "extra_params": {
36 "search_identity_requested": false
37 },
38 "status": "completed",
39 "audio_url": "https://example.com/image.jpg",
40 "zero_retention_mode": false,
41 "file_deleted_at": null
42 }
43}

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 "face_only": false,
12 "image_metrics": {
13 "ifl": {
14 "score": 1,
15 "heatmap": "https://..."
16 },
17 "type": "FinalResult",
18 "image": "https://...",
19 "label": "Fake",
20 "score": 1,
21 "children": [],
22 "reverse_image_search_sources": [
23 {
24 "url": "https://example-stock-site.com/ai-generated-images/",
25 "title": "example-stock-site.com",
26 "reason": "This exact image is hosted on a stock photography site and labeled as a 'Premium AI-generated image'.",
27 "verdict": "known_fake",
28 "similarity": 1
29 },
30 {
31 "url": "https://another-stock-site.com/search/ai-art",
32 "title": "another-stock-site.com",
33 "reason": "The site lists near-identical variations of this image, explicitly labeling them as AI generated.",
34 "verdict": "known_fake",
35 "similarity": 0.9
36 }
37 ]
38 },
39 "intelligence": {
40 "uuid": "INTELLIGENCE_UUID",
41 "description": "...",
42 "created_at": "2024-01-15T10:30:12Z",
43 "detect_uuid": "DETECTION_UUID"
44 },
45 "visualize": false,
46 "audio_source_tracing_enabled": false,
47 "use_ood_detector": false,
48 "filename": "image.jpg",
49 "extra_params": {
50 "use_reverse_search": true,
51 "search_identity_requested": false
52 },
53 "status": "completed",
54 "audio_url": "https://example.com/image.jpg",
55 "zero_retention_mode": false,
56 "file_deleted_at": null
57 }
58}

Video File Response

This example shows a video detection submitted with face_only=true and the default modality=all:

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 "modality": "all",
17 "face_only": true,
18 "video_metrics": {
19 "label": "Fake",
20 "score": 0.95,
21 "certainty": 0.93,
22 "treeview": "...",
23 "children": [
24 {
25 "type": "VideoResult",
26 "conclusion": "Fake",
27 "score": 0.99,
28 "certainty": 0.9,
29 "certainty (%)": "90.0",
30 "children": [
31 {
32 "type": "ImageResult",
33 "conclusion": "Fake",
34 "score": 0.9,
35 "certainty": 0.95,
36 "certainty (%)": "95.0",
37 "timestamp": 0.23,
38 "children": [
39 {
40 "type": "Segment",
41 "conclusion": "Fake",
42 "score": 0.9,
43 "certainty": 0.995,
44 "certainty (%)": "99.5"
45 }
46 ]
47 }
48 ]
49 }
50 ]
51 },
52 "intelligence": {
53 "description": "Video contains an adult male speaker with confident tone...",
54 "created_at": "2024-01-15T10:30:10Z"
55 }
56 }
57}

Video File Response (audio-only modality)

When modality=audio, only the audio track is analyzed. The response carries metrics and the requested modality, while video_metrics is absent. The detect is completed even though no video analysis ran:

1{
2 "success": true,
3 "item": {
4 "uuid": "DETECTION_UUID",
5 "metrics": {
6 "label": "fake",
7 "score": ["0.9", "0.8", "0.7"],
8 "consistency": "0.85",
9 "aggregated_score": "0.80"
10 },
11 "created_at": "2024-01-15T10:30:00Z",
12 "updated_at": "2024-01-15T10:30:05Z",
13 "duration": "10.5",
14 "media_type": "video",
15 "modality": "audio",
16 "face_only": false,
17 "status": "completed"
18 }
19}

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).
  • C2PA results: c2pa_manifest can still be returned after verification, with media references sanitized from stored metadata.
  • Watermark results: Requested watermark analysis reaches a terminal state before cleanup. Its metrics and status remain available after the source reference is removed.
  • Media deletion: After detection completes (including requested downstream tasks such as watermark analysis, 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,
> "detect_watermark": 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 "face_only": false,
18 "c2pa_manifest": {
19 "validation_state": "NotPresent"
20 },
21 "created_at": "2024-01-15T10:30:00Z",
22 "updated_at": "2024-01-15T10:30:05Z"
23 }
24}

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, a callback is sent after detection completes. The payload has the same structure as the synchronous response shown above, including the effective face_only value and the conditional watermark object.

When detect_watermark=true, callback delivery always waits until the Watermark analysis is completed or failed. This is independent of wait_for_intelligence. A failed Watermark analysis is included as a nested failure and does not suppress the callback or change a successful deepfake verdict.

When intelligence=true, the callback includes one Intelligence result in item.intelligence. Use wait_for_intelligence to control when it is delivered:

  • Set wait_for_intelligence=true to receive the callback only after both Detect and Intelligence have finished. The Intelligence status will be completed or failed. This mode has no forced timeout, so the callback remains pending while Intelligence is still processing.
  • Set wait_for_intelligence=false to receive the callback as soon as Detect finishes. Intelligence continues separately, and item.intelligence may be absent, processing, completed, or failed when the callback is sent.
  • Omit wait_for_intelligence to use the standard behavior. The callback waits up to 10 minutes for Intelligence and then sends with the result state available at that time.

Callbacks include one Intelligence result and never return the array available from GET /detect/{uuid}?experts=true. Intelligence failure does not suppress the callback or change top-level success: when detection succeeded, success remains true. A Detect callback is sent once and is not sent again if Intelligence finishes after an early or timed callback.

Delivery is retried when the callback endpoint fails or returns an ambiguous response, so your endpoint should handle repeated HTTP deliveries idempotently. Completed audio, image, and video callback payloads can also include c2pa_manifest.

Watermark Analysis Errors and Billing

StatusMeaning
400detect_watermark was not a valid true/false value, or a known source exceeded the 25 MB audio/image or 100 MB video Watermark limit.
402The account cannot cover the combined Detect and Watermark cost. details.watermark_cost_cents is included when watermark analysis was requested.
403The API key does not have Watermark detection access.

Once a request has been accepted, a provider-side Watermark failure is returned in item.watermark.status: "failed" with error_message. It does not rewrite the core deepfake result or change top-level success for an otherwise successful Detect.