Native PDF redaction removes text from the PDF's content stream rather than
drawing a black box on top of it. The distinction matters: overlaid
redactions leak the underlying text to any tool that reads the raw PDF —
copy-paste, pdftotext, and every search-engine crawler. ASHDOCS's
POST /api/tools/redact-pdf/run uses PyMuPDF's add_redact_annot +
apply_redactions to delete the glyphs, then re-serialises the document
so nothing recoverable remains.
Why do overlaid redactions leak?
A black box drawn over text only hides it on screen. The words are still in the PDF’s content stream, so anyone can select and copy them, search the file, run a text extractor, or delete the box in a PDF editor. Highlights set to black, and white text on a black background, fail the same way.
Native redaction removes the matched characters from the content stream and then rewrites the file, so nothing is left under the box to recover. That’s what redact-pdf does: it marks each match with a redaction annotation and applies it with PyMuPDF, which deletes the underlying text before the document is saved.
What data types does redact-pdf detect out of the box?
The endpoint accepts a types array in options. Each type maps to a
regex + validator. Credit-card matches are Luhn-validated so
non-checksummed 16-digit strings (order numbers, tracking IDs) don't
get erased.
| Type | Pattern | Validated? |
|---|---|---|
email | RFC 5322 subset | Yes — TLD check |
ssn | US SSN (9 digits, formatted) | Yes — no invalid area codes |
credit_card | 13–19 digits | Yes — Luhn |
phone | E.164 + common US formats | No |
iban | ISO 13616 | Yes — checksum |
What does a redaction request look like?
curl -X POST https://www.ashdocs.com/api/tools/redact-pdf/run \
-H "X-API-Key: ash_live_xxxxxxxx" \
-F "file=@contract.pdf" \
-F 'options={
"types": ["email", "ssn", "credit_card", "phone"]
}'
What does the response include?
{
"job_id": "job_01H...",
"status": "completed",
"output_files": [{ "url": "https://...redacted.pdf", "size_bytes": 84213 }],
"redaction_summary": {
"counts": { "email": 3, "ssn": 1, "credit_card": 0, "phone": 2 },
"pages_affected": [1, 2, 5]
}
}
The counts array tells you what was removed. The actual matched values are never returned — that would defeat the point.
Frequently asked questions
Does redact-pdf work on scanned PDFs?
Scanned PDFs run through OCR first to obtain a text layer, then the
redaction pass removes matched glyphs. Confidence is lower on
handwritten or heavily compressed scans — inspect the returned
redaction_summary.confidence_floor before shipping to production.
Can I supply my own regex patterns?
Not yet. The types array is currently limited to the built-in
detectors listed above. Custom pattern support is on the roadmap;
subscribe to release notes on our blog to hear when it lands.
Is redaction reversible?
No. Once apply_redactions runs, the glyphs are gone from the content
stream. That is the whole point — reversible redactions are the
overlaid-black-box failure mode we exist to avoid.
Does redact-pdf work inside a pipeline?
Yes. The visual pipeline builder in the dashboard offers a redact-pdf step. Chain it after any extraction or conversion tool to produce a redacted output alongside the structured JSON, then deliver both to your webhook or destination in one atomic pipeline run.