DEV Community

Cover image for Text Stamps vs. Watermarks: Same Visual Result, Two Different API Calls
PDF4me
PDF4me

Posted on

Text Stamps vs. Watermarks: Same Visual Result, Two Different API Calls

Ask a developer to add a "watermark" to a PDF and they picture gray text on a diagonal, something like CONFIDENTIAL bleeding through the page. Ask for a "stamp" and they picture a logo in the corner. PDF4me's own docs use both words for both things, sometimes on the same page. That's not sloppy naming. It reflects a real split under the hood: two separate REST endpoints for what looks, on screen, like one feature.

Send an image file to the endpoint built for text, or a hex color code to the one built for images, and you'll get a 500 that has nothing to do with your API key. Here's exactly where the line sits between the two, verified against the live docs and the official sample repo, plus what happens to the naming once you leave raw REST for Power Automate, Make, Zapier, or n8n.

Authentication, once, for both endpoints

Every PDF4me REST call needs a Base64-encoded API key in the Authorization header. Full details, including how to get a key and encode it, live in Connect to the PDF4me V2 API. Get that working once and both endpoints below are ready.

Add Text Stamp to PDF: POST /api/v2/Stamp

Add Text Stamp to PDF renders a string onto a page and gives you granular control over how it looks. Required fields: docName, docContent (Base64 source PDF), pages, text, alignX, alignY. The optional fields are where the control lives: fontName (Arial, Times New Roman, Helvetica, Courier New), fontSize (8-72), fontColor as hex, isBold/isItalics/underline, rotate (0, 45, 90, or -45), opacity (0-100), isBackground to push it behind existing content, showOnlyInPrint, and fitTextOverPage to auto-scale the text to the page.

Verified live against the official Python sample (MIT licensed), the core request looks like this:

import base64
import requests

api_key = "get the API key from https://dev.pdf4me.com/dashboard/#/api-keys"
url = "https://api.pdf4me.com/api/v2/Stamp"

with open("sample.pdf", "rb") as f:
    pdf_base64 = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "docContent": pdf_base64,
    "docName": "output.pdf",
    "pages": "all",
    "text": "CONFIDENTIAL - PDF4me Watermark",
    "alignX": "center",          # lowercase: left, center, right
    "alignY": "middle",          # lowercase: top, middle, bottom
    "opacity": "30",
    "fontName": "Arial",
    "fontSize": 24,
    "fontColor": "#FF0000",
    "isBold": True,
    "rotate": 45,
    "isBackground": True,
    "async": True
}

headers = {
    "Authorization": f"Basic {api_key}",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)
Enter fullscreen mode Exit fullscreen mode

A 200 returns docName and docContent (the stamped PDF, Base64) directly. A 202 means async processing kicked in: pull the Location header and poll it until you get a 200 with the same JSON shape. That polling loop is fully worked out in the sample repo linked above, worth reading before you write your own.

Add Image Stamp to PDF: POST /api/v2/ImageStamp

Add Image Stamp to PDF is a different endpoint entirely, and the required fields make that obvious immediately: docName, docContent, imageName, imageFile (your logo, also Base64), alignX, alignY. No text field. No fontColor. In their place: heightInMM/widthInMM (10-200mm) or heightInPx/widthInPx (20-600px) for sizing, and support for JPG, PNG, GIF, and other standard formats.

import base64
import requests

api_key = "get the API key from https://dev.pdf4me.com/dashboard/#/api-keys"
url = "https://api.pdf4me.com/api/v2/ImageStamp"

with open("sample.pdf", "rb") as f:
    pdf_base64 = base64.b64encode(f.read()).decode("utf-8")
with open("logo.png", "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "docContent": pdf_base64,
    "docName": "output.pdf",
    "imageFile": image_base64,
    "imageName": "logo.png",
    "alignX": "Center",          # capitalized here: Left, Center, Right
    "alignY": "Middle",          # capitalized here: Top, Middle, Bottom
    "heightInMM": "30",
    "widthInMM": "30",
    "opacity": 50,
    "isBackground": True,
    "async": True
}

headers = {
    "Authorization": f"Basic {api_key}",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)
Enter fullscreen mode Exit fullscreen mode

Notice the alignX/alignY values flip capitalization between the two endpoints, lowercase on Stamp, capitalized on ImageStamp. That inconsistency is real and confirmed directly against both live docs pages, not a typo in this article. It's the kind of thing that passes code review and fails at runtime.

The other tell: there's no rotate parameter anywhere on the image endpoint. Need a rotated logo? Rotate the source image before you send it. This API call won't do it for you.

Picking the right one

The rule: a string of characters goes through /api/v2/Stamp. A graphic, logo, scanned signature, seal, goes through /api/v2/ImageStamp. Plenty of real documents need both in sequence, a signed contract might carry an image stamp of a signature in one corner and a text stamp reading EXECUTED diagonally across the page. Chain the calls: the docContent one endpoint returns is valid input to the next.

Neither endpoint is an "upgrade" of the other. fitTextOverPage will never produce a logo no matter how you tune it, and ImageStamp has no text field to put a dynamic invoice number in. If your watermark needs to vary per document, that's the text endpoint. If it needs to stay pixel-identical across every file, that's the image endpoint.

The naming shifts again outside raw REST

Cross into PDF4me's no-code integrations and the labels don't hold. Power Automate and n8n keep "Stamp" as separate Text Stamp and Image Stamp actions. Make drops "Stamp" entirely for Text Watermark and Image Watermark. Zapier follows Make's convention with Add Text Watermark to PDF and Add Image Watermark to PDF.

Same Stamp/ImageStamp behavior under all four, different search term depending on where you're building. Search "stamp" in Make and you'll come up empty. Search "watermark" in Power Automate and same problem, reversed.

Confirm the shape before it hits production

Rather than debug a live workflow over a flipped capitalization or a missing field, run either endpoint through the API Tester first: text stamp tester or image stamp tester. See the exact request and response before it touches a document that matters.

Two endpoints, two request shapes, at least four labels for the same idea depending on which product surface you're standing in. Know which word your platform uses, know which field set your content needs, and the rest is filling in a form.

Website: pdf4me.com
Documentation: docs.pdf4me.com
Developer portal: dev.pdf4me.com

Top comments (0)