Skip to main content

Watermark PDF API

Stamp text diagonally across every page. Put the text in "option".

EndpointPOST https://astralpdf.com/api/v1/watermark-pdf
AuthBearer token, free
Sendsinput: base64
Returnsresult: base64
PriceFree. 1,000 calls a day, 60 a minute.

When to call it

Marking a document DRAFT, CONFIDENTIAL or with a client name is a policy, and policies applied by hand are applied unevenly. Stamping in the generation step means every copy that leaves carries the mark, including the one somebody forwards.

For a one-off, the browser version needs no token and never sends your data anywhere: it runs on your own machine.

Example

curl
curl -X POST https://astralpdf.com/api/v1/watermark-pdf \
  -H "Authorization: Bearer ast_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"input": "JVBERi0xLjcKJYGBgYEK...", "option": "CONFIDENTIAL"}'
response
{
  "tool": "watermark-pdf",
  "result": "JVBERi0xLjcKJWDjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2c...",
  "chars": 5310,
  "ms": 74
}

In your language

JavaScript
const res = await fetch("https://astralpdf.com/api/v1/watermark-pdf", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ASTRAL_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"input": "JVBERi0xLjcKJYGBgYEK...", "option": "CONFIDENTIAL"}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const { result } = await res.json();
Python
import os, requests

res = requests.post(
    "https://astralpdf.com/api/v1/watermark-pdf",
    headers={"Authorization": f"Bearer {os.environ['ASTRAL_TOKEN']}"},
    json={"input": "JVBERi0xLjcKJYGBgYEK...", "option": "CONFIDENTIAL"},
    timeout=30,
)
res.raise_for_status()
result = res.json()["result"]

Parameters

FieldTypeNotes
inputstringRequired. The file, base64 encoded. A data: URL is accepted too. Up to 6,000,000 characters per call.
optionstringSee the example above.

Errors

Errors are RFC 7807 problem documents with a stable type you can branch on.

missing-token401No Authorization header.
bad-request400input missing or the wrong type.
tool-failed422The input could not be processed. detail says why.
quota-exceeded429Past 1,000 calls today.

Questions

Where does the text go?
In "option". It is drawn diagonally across the middle of every page, in grey at about a third opacity so the content underneath stays readable.
Is the size fixed?
No. It is derived from the page dimensions and the length of the text, so the same call looks right on A4 and on a poster.
Can it be removed?
It is drawn into the page content, so removing it means editing the page. It is a visible mark, not a security control.

Other endpoints

A token takes thirty seconds

Free, no card, 1,000 calls a day, and the same token works on astraltext.com, astralpdf.com, astraljson.com and astralbatch.com.

Get a free token