Add Watermarks to PDFs

Watermarking is the process of applying an irremovable, transparent annotation to a document’s pages. PSPDFKit Document Engine lets you watermark documents using the watermark action.

Adding a watermark requires options that describe the look and position of the watermark. You can use any kind of annotation.

To effectively make a watermark irremovable, flatten the document’s annotations after applying the watermark.

Before you get started, make sure Document Engine is up and running.

You can download and use either of the following sample documents for the examples in this guide:

You’ll be sending multipart POST requests with instructions to Document Engine’s /api/build endpoint. To learn more about multipart requests, refer to our blog post on the topic, A Brief Tour of Multipart Requests.

Check out the API Reference to learn more about the /api/build endpoint and all the actions you can perform on PDFs with PSPDFKit Document Engine.

You can specify both text and image watermarks.

Watermarking a File on Disk

To add a TOP SECRET text watermark to a document, send a request to the /api/build endpoint, attaching an input file and the instructions JSON:

curl -X POST http://localhost:5000/api/build \
  -H "Authorization: Token token=<API token>" \
  -F document=@/path/to/example-document.pdf \
  -F instructions='{
  "parts": [
    {
      "file": "document",
      "actions": [
        {
          "type": "watermark",
          "text": "TOP SECRET",
          "width": 100,
          "height": 200
        },
        {
          "type": "flatten"
        }
      ]
    }
  ]
}' \
  -o result.pdf
POST /api/build HTTP/1.1
Content-Type: multipart/form-data; boundary=customboundary
Authorization: Token token=<API token>

--customboundary
Content-Disposition: form-data; name="document"; filename="example-document.pdf"
Content-Type: application/pdf

<PDF data>
--customboundary
Content-Disposition: form-data; name="instructions"
Content-Type: application/json

{
  "parts": [
    {
      "file": "document",
      "actions": [
        {
          "type": "watermark",
          "text": "TOP SECRET",
          "width": 100,
          "height": 200
        },
        {
          "type": "flatten"
        }
      ]
    }
  ]
}
--customboundary--

The following example adds an image watermark to the first page of a four-page document and a text annotation to the last page of the same document before flattening the annotations on the final output PDF so that the watermark can’t be erased:

curl -X POST http://localhost:5000/api/build \
  -H "Authorization: Token token=<API token>" \
  -F document=@/path/to/example-document.pdf \
  -F image-local=@/path/to/image-watermark.png \
  -F instructions='{
  "parts": [
    {
      "file": "document",
      "pages": {
        "start": 0,
        "end": 0
      },
      "actions": {
        "type": "watermark",
        "image": "image-local",
        "width": 100
      }
    },
    {
      "file": "document",
      "pages": {
        "start": 1,
        "end": 2
      }
    },
    {
      "file": "document",
      "pages": {
        "start": 3,
        "end": 3
      },
      "actions": {
        "type": "watermark",
        "text": "TOP SECRET",
        "width": 100,
        "height": 200
      }
    }
  ],
  "actions": [
    {
      "type": "flatten"
    }
  ]
}' \
  -o result.pdf
POST /api/build HTTP/1.1
Content-Type: multipart/form-data; boundary=customboundary
Authorization: Token token=<API token>

--customboundary
Content-Disposition: form-data; name="document"; filename="example-document.pdf"
Content-Type: application/pdf

<PDF data>
--customboundary
Content-Disposition: form-data; name="image-local"; filename="image-watermark.png"
Content-Type: application/pdf

<PDF data>
--customboundary
Content-Disposition: form-data; name="instructions"
Content-Type: application/json

{
  "parts": [
    {
      "file": "document",
      "pages": {
        "start": 0,
        "end": 0
      },
      "actions": {
        "type": "watermark",
        "image": "image-local",
        "width": 100
      }
    },
    {
      "file": "document",
      "pages": {
        "start": 1,
        "end": 2
      }
    },
    {
      "file": "document",
      "pages": {
        "start": 3,
        "end": 3
      },
      "actions": {
        "type": "watermark",
        "text": "TOP SECRET",
        "width": 100,
        "height": 200
      }
    }
  ],
  "actions": [
    {
      "type": "flatten"
    }
  ]
}
--customboundary--

Watermarking a File from URL

Instead of paths to local files, you can use URLs to specify both the documents to be watermarked in the file parts and the images to use for image watermarks.

The following example adds an image annotation to all pages of a document and flattens them so that the watermark can’t be erased. This request to the /api/build endpoint attaches two URLs, which point to the input file and the image, respectively:

curl -X POST http://localhost:5000/api/build \
  -H "Authorization: Token token=<API token>" \
  -F instructions='{
  "parts": [
    {
      "file": {
        "url": "https://pspdfkit.com/downloads/examples/paper.pdf"
      },
      "pages": {
        "start": 0,
        "end": 0
      },
      "actions": {
        "type": "watermark",
        "image": {
          "url": "https://image-url.com/path-to-image-on-internet.png"
        },
        "width": 100
      }
    }
  ],
  "actions": [
    {
      "type": "flatten"
    }
  ]
}' \
  -o result.pdf
POST /api/build HTTP/1.1
Content-Type: multipart/form-data; boundary=customboundary
Authorization: Token token=<API token>

--customboundary
Content-Disposition: form-data; name="instructions"
Content-Type: application/json

{
  "parts": [
    {
      "file": {
        "url": "https://pspdfkit.com/downloads/examples/paper.pdf"
      },
      "pages": {
        "start": 0,
        "end": 0
      },
      "actions": {
        "type": "watermark",
        "image": {
          "url": "https://image-url.com/path-to-image-on-internet.png"
        },
        "width": 100
      }
    }
  ],
  "actions": [
    {
      "type": "flatten"
    }
  ]
}
--customboundary--

When using a URL to specify the path for an image annotation, the MIME type of the image needs to be a part of the image’s URL. In the example above, the MIME type of the image is png.