# Operations Operations run in order, top to bottom. Each is an object with a `type` and that operation's parameters; anything else is refused with `422`. The same catalog is served as JSON by `GET /v1/operations`, and with a picture of each example at https://api.watermark.ws/docs/operations. | Operation | Images | Videos | PDFs | What it does | | --- | --- | --- | --- | --- | | [`watermark`](#watermark) | yes | yes | yes | Place an image (a logo, usually a transparent PNG) over the file, at its own size. Resize the watermark image beforehand. | | [`border`](#border) | yes | yes | | Add a border of a color on each side. | | [`resize`](#resize) | yes | yes | | Resize to a width and height. | | [`crop`](#crop) | yes | yes | | Cut out a rectangle. | | [`thumbnail`](#thumbnail) | yes | | | Make a small, fast-loading copy, metadata stripped. | | [`rotate`](#rotate) | yes | yes | | Rotate by degrees, clockwise, and optionally mirror. | | [`flip`](#flip) | yes | yes | | Mirror the file. | | [`orient`](#orient) | yes | | | Turn the image upright from its EXIF orientation. | | [`grayscale`](#grayscale) | yes | yes | | Remove the color. | | [`sepia`](#sepia) | yes | | | Give the image a sepia tone. | | [`exposure`](#exposure) | yes | | | Adjust brightness and contrast. | | [`filter`](#filter) | yes | | | Apply a photo filter. | | [`remove_background`](#remove_background) | yes | | | Make the background color transparent (output PNG or WebP to keep it). | | [`compress`](#compress) | yes | | | Re-encode at a quality, 1-100. | Output formats: images `jpg`, `png`, `webp`, `gif`, `tif` (the first is the default); videos `mp4`; PDFs `pdf`. ## Brand it Put your mark on a photo, a video or every page of a PDF. ### watermark Place your logo, usually a transparent PNG, over a photo, every frame of a video or every page of a PDF. It goes on at the logo's own size, so resize the logo first. `x` and `y` count pixels from the top-left corner. Works on: Images, Videos, PDFs. Tip: To use another corner, read the file first: for the bottom right, x is the image width minus the logo width minus a margin (900 − 316 − 32 = 552). Tile spacing is the step from one copy to the next, so make it wider than the logo. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `image_url` | an http(s) URL | yes | | URL of the watermark image (JPEG, PNG, GIF or WebP). | | `x` | a whole number, -20000 to 20000 | yes | | The x position in pixels, from the top left. | | `y` | a whole number, -20000 to 20000 | yes | | The y position in pixels, from the top left. | | `tile_spacing_x` | a number, 0 to 20000 | no | | Repeat the watermark across the file: the step in pixels from one copy's left edge to the next (with tile_spacing_y). | | `tile_spacing_y` | a number, 0 to 20000 | no | | When tiling, the step in pixels from one copy's top edge to the next. | | `diagonal_lines_color` | a hex color | no | | Also draw two diagonal lines corner to corner in this color. A hex color, such as "#ffffff". | | `diagonal_lines_opacity` | a whole number, 0 to 100 | no | | Opacity of the diagonal lines, 0-100. | A logo in the bottom-right corner (`POST /v1/images/process`; the result is 900 × 600 · JPG · 96 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "watermark", "image_url": "https://example.com/logo.png", "x": 552, "y": 524} ] } ``` Repeated across the whole photo (`POST /v1/images/process`; the result is 900 × 600 · JPG · 110 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "watermark", "image_url": "https://example.com/logo.png", "x": 40, "y": 36, "tile_spacing_x": 440, "tile_spacing_y": 140} ] } ``` On every page of a PDF, with diagonal lines (`POST /v1/documents/process`; the result is PDF · 100 KB): ```json { "source": "https://example.com/contract.pdf", "operations": [ {"type": "watermark", "image_url": "https://example.com/logo.png", "x": 148, "y": 712, "diagonal_lines_color": "#c0392b", "diagonal_lines_opacity": 35} ] } ``` ### border Add a frame of one color, as wide as you like on each side. The file grows by the border. Works on: Images, Videos. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `top` | a whole number, 0 to 2000 | yes | | Top border in pixels. | | `bottom` | a whole number, 0 to 2000 | yes | | Bottom border in pixels. | | `left` | a whole number, 0 to 2000 | yes | | Left border in pixels. | | `right` | a whole number, 0 to 2000 | yes | | Right border in pixels. | | `color` | a hex color | yes | | The border color. A hex color, such as "#ffffff". | A white frame, wider at the bottom (`POST /v1/images/process`; the result is 948 × 696 · JPG · 96 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "border", "top": 24, "bottom": 72, "left": 24, "right": 24, "color": "#ffffff"} ] } ``` ## Size and shape Fit a file to where it is going: a size, a square, the right way up. ### resize Make the file a new size. By default it fits inside the width and height you give and keeps its shape; `crop_center` fills the box instead and trims what overflows. Works on: Images, Videos. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `width` | a whole number, 1 to 20000 | yes | | The width in pixels. | | `height` | a whole number, 1 to 20000 | yes | | The height in pixels. | | `preserve_aspect_ratio` | true or false | no | `true` | Fit inside the box instead of stretching to it. | | `crop_center` | true or false | no | `false` | Fill the box and crop what overflows, centered. | Fit inside 450 × 450 (`POST /v1/images/process`; the result is 450 × 300 · JPG · 26 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "resize", "width": 450, "height": 450} ] } ``` Fill a 400 × 400 square (`POST /v1/images/process`; the result is 400 × 400 · JPG · 29 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "resize", "width": 400, "height": 400, "crop_center": true} ] } ``` ### crop Cut out a rectangle: its top-left corner at `x`, `y`, and its width and height, all in pixels. Works on: Images, Videos. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `x` | a whole number, 0 to 20000 | yes | | Left edge in pixels. | | `y` | a whole number, 0 to 20000 | yes | | Top edge in pixels. | | `width` | a whole number, 1 to 20000 | yes | | The width in pixels. | | `height` | a whole number, 1 to 20000 | yes | | The height in pixels. | A 400 × 400 square from the right side (`POST /v1/images/process`; the result is 400 × 400 · JPG · 42 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "crop", "x": 470, "y": 130, "width": 400, "height": 400} ] } ``` ### thumbnail A small, fast-loading copy for previews and lists: resized, compressed and stripped of metadata in one step. Leave out the height to keep the shape. Works on: Images. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `width` | a whole number, 1 to 4000 | yes | | The width in pixels. | | `height` | a whole number, 1 to 4000 | no | | The height in pixels; kept in proportion when left out. | | `quality` | a whole number, 1 to 100 | no | | Compression quality, 1-100. | 300 pixels wide, quality 70 (`POST /v1/images/process`; the result is 300 × 200 · JPG · 8 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "thumbnail", "width": 300, "quality": 70} ] } ``` ### rotate Turn the file clockwise by any number of degrees (negative turns it the other way), and mirror it at the same time if you need to. Works on: Images, Videos. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `degrees` | a whole number, -360 to 360 | yes | | Degrees clockwise. | | `flip_horizontal` | true or false | no | `false` | Mirror left to right. | | `flip_vertical` | true or false | no | `false` | Mirror top to bottom. | A quarter turn clockwise (`POST /v1/images/process`; the result is 600 × 900 · JPG · 95 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "rotate", "degrees": 90} ] } ``` ### flip Mirror the file left to right, top to bottom, or both. Works on: Images, Videos. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `horizontal` | true or false | no | `false` | Mirror left to right. | | `vertical` | true or false | no | `false` | Mirror top to bottom. | Mirrored left to right (`POST /v1/images/process`; the result is 900 × 600 · JPG · 96 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "flip", "horizontal": true} ] } ``` ### orient Phones often save a photo sideways and only note which way is up. This turns the pixels upright, so every app shows it the right way. Works on: Images. No parameters: `{"type": "orient"}` is the whole operation. A phone photo stored sideways, turned upright (`POST /v1/images/process`; the result is 900 × 600 · JPG · 96 KB): ```json { "source": "https://example.com/phone-photo.jpg", "operations": [ {"type": "orient"} ] } ``` ## Look and file size Change the colors, cut out a background, or make the file smaller. ### grayscale Remove the color. Works on: Images, Videos. No parameters: `{"type": "grayscale"}` is the whole operation. Black and white (`POST /v1/images/process`; the result is 900 × 600 · JPG · 88 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "grayscale"} ] } ``` ### sepia A warm, old-photo tone. `threshold` sets how strong it is. Works on: Images. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `threshold` | a whole number, 0 to 100 | yes | | How strong the tone is, 0-100. | Threshold 80 (`POST /v1/images/process`; the result is 900 × 600 · JPG · 98 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "sepia", "threshold": 80} ] } ``` ### exposure Brighten or darken, and add or take away contrast, each from -100 to 100. Works on: Images. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `brightness` | a whole number, -100 to 100 | no | `0` | From -100 to 100. | | `contrast` | a whole number, -100 to 100 | no | `0` | From -100 to 100. | Brighter, with more contrast (`POST /v1/images/process`; the result is 900 × 600 · JPG · 101 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "exposure", "brightness": 10, "contrast": 45} ] } ``` ### filter One of 18 photo filters, at full strength or blended in. `strength` 50 is half the look. Works on: Images. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `name` | one of amaro, apollo, brannan, earlybird, gotham, hefe, inkwell, kelvin, lomo, nashville, poprocket, rise, sierra, toaster, valencia, walden, willow, xpro2 | yes | | Which one to use. | | `strength` | a whole number, 0 to 100 | no | `100` | How much of the look, 0-100. | Toaster (`POST /v1/images/process`; the result is 900 × 600 · JPG · 91 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "filter", "name": "toaster"} ] } ``` Nashville at half strength (`POST /v1/images/process`; the result is 900 × 600 · JPG · 85 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "filter", "name": "nashville", "strength": 50} ] } ``` ### remove_background Make the background color transparent: the color in the corners, and everything close to it within `tolerance`. Ask for PNG or WebP output to keep the transparency. Made for logos, signatures and stamps on a plain background. Works on: Images. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `tolerance` | a whole number, 0 to 100 | yes | | How far from the background color still counts as background, 0-100. | | `blur` | a whole number, 0 to 10 | no | `0` | Soften the cut edge, 0-10. | A signature lifted off the paper (`POST /v1/images/process`; the result is 900 × 420 · PNG · 332 KB): ```json { "source": "https://example.com/signature.jpg", "operations": [ {"type": "remove_background", "tolerance": 20, "blur": 1} ], "output": {"format": "png"} } ``` ### compress Save at a lower quality to make the file smaller. Around 70 is hard to tell apart from the original. Works on: Images. | Parameter | Accepts | Required | Default | Description | | --- | --- | --- | --- | --- | | `quality` | a whole number, 1 to 100 | yes | | Compression quality, 1-100. | Quality 40 (`POST /v1/images/process`; the result is 900 × 600 · JPG · 39 KB): ```json { "source": "https://example.com/photo.jpg", "operations": [ {"type": "compress", "quality": 40} ] } ``` ## Other endpoints These take a file and one value instead of a list of operations. ### Screenshot a video Save one frame of a video as a JPEG or PNG: a poster, a preview, a cover. `POST /v1/videos/screenshot`: ```json { "source": "https://example.com/clip.mp4", "seconds": 3, "output": {"format": "jpg"} } ``` ### Snapshot a PDF page Render one page of a PDF as an image, to preview a document without a PDF viewer. `POST /v1/documents/snapshot`: ```json { "source": "https://example.com/contract.pdf", "page": 1, "output": {"format": "png"} } ``` ### Read a file Find out what a file is before you change it: its size and format, a video's duration, a PDF's pages. Use it to place a watermark in a corner. `POST /v1/images/read`: ```json { "source": "https://example.com/photo.jpg" } ``` `result.data`: ```json { "frames": 1, "orientation": "Undefined", "format": "JPEG", "colorspace": "sRGB", "width": 900, "height": 600, "size": 97451 } ```