> 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.

# Watermarking

The Resemble Watermark API applies and detects durable watermarks in audio, image, and video files. Provide a public HTTPS URL and the API automatically determines the media type from the file content.

## Model behavior

All newly encoded media is reported as `perth_v2`. Detection behavior depends on the media type:

| Operation | Audio                                                        | Image and video                                                       |
| --------- | ------------------------------------------------------------ | --------------------------------------------------------------------- |
| Apply     | Encodes with Perth v2                                        | Encodes with Perth v2                                                 |
| Detect    | Runs Perth v1 and Perth v2 concurrently, then checks SynthID | Runs one Resemble detector, reported as Perth v2, then checks SynthID |

For audio, the response includes an overall verdict and a separate result for each Perth version. This lets you identify older Perth v1 watermarks while continuing to detect content encoded with Perth v2.

Completed detect metrics can also include `synthid: true | false` for audio, image, and video. This is the literal auxiliary verdict returned by SynthID and does not alter the Resemble watermark fields. If SynthID is unavailable, the field is omitted rather than converted to `false`.

## Supported media

| Media type | Common formats                                 | Maximum source size | Additional parameters        |
| ---------- | ---------------------------------------------- | ------------------- | ---------------------------- |
| Audio      | WAV, MP3, and other audio formats              | 200 MB              | —                            |
| Image      | PNG, JPEG, WebP, AVIF, and other image formats | 200 MB              | `strength`, `custom_message` |
| Video      | MP4, MOV, and other video formats              | 200 MB              | `strength`, `custom_message` |

The source URL must be publicly fetchable over HTTPS. Signed URLs are supported as long as they remain valid while the job is processing.

## Output format

By default, apply returns the watermarked file as WAV (audio), PNG (image), or MP4 (video), whatever the source format. Set `output_format` to `source` to get the watermarked file back in the source's format instead:

| Source                                                   | Output with `output_format: "source"` |
| -------------------------------------------------------- | ------------------------------------- |
| WAV, MP3, M4A, OGG/Opus, FLAC, AAC                       | Same format                           |
| PNG, JPEG, WebP, AVIF, BMP, TIFF                         | Same format                           |
| MP4, MOV, M4V, MKV, AVI, 3GP, WebM                       | Same format                           |
| Other formats, such as WMA, GIF, SVG, HEIC, WMV, and FLV | WAV, PNG, or MP4                      |

The file extension of `watermarked_media` shows which format was written. Encoded audio is mono, and image metadata such as EXIF and ICC profiles is not preserved. Jobs created before `output_format` was available keep their original WAV, PNG, or MP4 output.

## Asynchronous and synchronous processing

Processing is asynchronous by default. The initial response contains a job UUID and a `status`; poll the corresponding result endpoint until the status is `completed` or `failed`.

To wait for completion in the initial request, include `Prefer: wait`. Model cold starts and video processing can make synchronous requests take longer, so asynchronous processing is recommended when your HTTP client has a short request timeout.

```ts
type WatermarkStatus = "pending" | "processing" | "completed" | "failed";

interface ApplyRequest {
  url: string;
  output_format?: "default" | "source"; // default: "default" (WAV/PNG/MP4)
  strength?: number;       // Image/video only; 0.0-1.0, default: 0.2
  custom_message?: string; // Image/video only; default: "resembleai"
}

interface DetectRequest {
  url: string;
  custom_message?: string; // Image/video only; default: "resembleai"
}

interface WatermarkJob {
  uuid: string;
  media_type: "audio" | "image" | "video";
  operation_type: "apply" | "detect";
  status: WatermarkStatus;
  model_version?: "perth_v2";
  source_media_url: string;
  watermarked_media: string | null;
  metrics: object | null;
  created_at: string;
  updated_at: string;
}
```

`model_version` is returned for all apply jobs and for image/video detect jobs. Audio detect jobs instead report every checked version in `metrics.model_results`.

See [Apply Watermark](/detect/watermark/apply) and [Detect Watermark](/detect/watermark/detect) for complete requests and response schemas.