True redaction
POST /v1/pdf/redact — content is really removed, not covered.
Most "redaction" tools draw a black box over the text — the words are
still in the file, one copy-paste away. POST /v1/pdf/redact physically
removes the text objects under each region from the file, then draws the
box. What was redacted cannot be recovered.
Request
Regions are normalized 0..1, origin top-left, per 1-based page:
PDF=$(base64 -w0 contract.pdf) # macOS: base64 -i contract.pdf
curl -X POST https://api.pdf-forge.dev/v1/pdf/redact \
-H "Authorization: Bearer $PDFFORGE_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"pdf\": \"$PDF\",
\"regions\": [
{ \"page\": 1, \"x\": 0.1, \"y\": 0.22, \"width\": 0.35, \"height\": 0.03 }
]
}" \
--output redacted.pdfconst redacted = await client.pdf.redact(pdfBytes, [
{ page: 1, x: 0.1, y: 0.22, width: 0.35, height: 0.03 },
]);The response is the redacted PDF; the X-Redacted-Objects header counts the
text objects that were removed.
Find the coordinates with perceive
Don't compute coordinates by hand. POST /v1/pdf/perceive returns every text
element with its bbox in the exact frame redact accepts, plus semantic
labels (email, phone, iban, amount...):
const doc = await client.pdf.perceive(pdfBytes, { detail: "full" });
// Redact every element labelled as an email address
const regions = doc.pages.flatMap((p) =>
p.elements
.filter((el) => el.semantic === "email")
.map((el) => ({
page: p.page,
x: el.bbox[0], y: el.bbox[1],
width: el.bbox[2], height: el.bbox[3],
})),
);
const redacted = await client.pdf.redact(pdfBytes, regions);See Inspect for the full perception layer, and the
MCP server whose redact_pdf tool wraps this whole
loop (by id, regex pattern or semantic label) for AI agents.
Scanned PDFs: flatten after redacting
On a scanned page the text is pixels inside an image — the box is painted
over it, but the pixels underneath survive in the image stream. Rasterize
the redacted file (to-image at 200 dpi, then from-images) to make the
removal irreversible. The MCP redact_pdf tool does this automatically
with flatten: true.
Strip an overlay watermark
The reverse operation — removing a big diagonal "DRAFT" without leaving a
white patch — is structural too. POST /v1/pdf/strip-watermark deletes the
large rotated text blocks:
curl -X POST https://api.pdf-forge.dev/v1/pdf/strip-watermark \
-H "Authorization: Bearer $PDFFORGE_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"pdf\": \"$PDF\", \"minFont\": 36}" \
--output clean.pdfminFont (points) is the font-size threshold above which rotated text is
considered a watermark.
const clean = await client.pdf.stripWatermark(pdfBytes, 36);Next steps
- Inspect — the perception layer that feeds redact its coordinates.
- MCP server — agent-grade redaction by pattern or semantic label.
- Secure — encrypt what remains.