EmbedPDF

Redaction

Redaction removes content from a document for good: the text, images and drawings under an area are taken out of the file, not just covered. It takes two steps. First you mark what to remove, then you apply the marks:

// 1. Mark: a redact annotation over the area
const { annotation } = await page.annotations.create({
  subtype: 'redact',
  rect: { x: 72, y: 132, width: 248, height: 20 },
  interiorColor: '#000000',
});
 
// 2. Apply: remove what's under it
await doc.redaction.apply({ annotations: [annotation.ref] });
 
// 3. Save a file without the removed content
const bytes = await doc.download({ mode: 'rewrite' });

Mark what to remove#

A mark is a redact annotation. It removes nothing yet: it shows as an outline, the text under it can still be read and copied, and you can change or delete it like any other annotation. That lets someone review the marks before anything is gone.

Mark an area with rect, in points. To mark text exactly, as it runs across lines or at an angle, give its quadPoints instead, the same corners a highlight takes. Search results have them:

const { matches } = await doc.search.query({ text: 'Jane Doe', wholeWord: true });
 
for (const match of matches) {
  await doc.page(match.page).annotations.create({
    subtype: 'redact',
    quadPoints: match.segments.map((segment) => segment.quad),
    interiorColor: '#000000',
  });
}

With quadPoints, the quads decide what’s removed, and rect (the box around them) is worked out for you. A text selection gives you the same quads; see Selection & geometry.

Choose what’s left in its place#

After the content is removed, the engine paints the area. These fields say what it paints:

FieldWhat it isDefault
interiorColorThe fill, '#rrggbb'no fill
overlayTextText on top of the fill, such as 'REDACTED'none
repeatRepeat overlayText to fill the whole areafalse
fontFamilyThe font of overlayText, such as 'times-roman'; see Fonts'helvetica'
fontSizeIts size in points; 0 fits the text to the area12
fontColorIts colorblack
textAlign'left', 'center' or 'right''left'
colorThe outline shown while the area is only markedred

Without a fill or text, the area is left blank: the content is gone and the page shows through. In PDF apps that support it, hovering a mark previews the fill and text it will leave.

Apply#

apply() removes the content under marks. Pass the marks to apply:

await doc.redaction.apply({ annotations: [markA.ref, markB.ref] });

Or apply every mark on some pages:

const { pages } = await doc.pages.list();
await doc.redaction.apply({ pages: pages.map((page) => page.ref) });

The result says what happened on each page:

const { results, removedAnnotationCount } = await doc.redaction.apply({ pages: [page.ref] });
// results: [{ page, status: 'applied', removedAnnotationCount: 1 }]

A page’s status is 'applied', or 'unchanged' when it had no marks. The marks you applied are removed from the page. Other annotations that overlap a marked area are removed too, because they could reveal what was there; removedAnnotationCount counts those, so you can tell the user.

Passing a ref that isn’t a redact annotation fails with InvalidArg before anything changes.

What gets removed#

Under each marked area, applying removes:

  • Text: the characters themselves, so they can’t be searched, selected or copied anymore. Text next to the area stays.
  • Images: the pixels inside the area are erased from the image. For a slanted mark, that’s the box around it.
  • Drawings: the parts of lines, shapes and fills inside the area.
  • Annotations and form fields that overlap the area, even in part, with their popups. For a mark with quadPoints, the quads count, not the box around them.

This includes content the page draws from shared parts of the file, not only what the page draws itself. There’s no undo: once applied, the content is gone from the document. Applying also ends undo for every change made before it; see Changes & undo.

Save the redacted file#

Apply changes the document as it is now, but an incremental save still holds the version you opened, with everything you removed. Anyone with a PDF tool can recover it. For a file you share, save with mode: 'rewrite':

const bytes = await doc.download({ mode: 'rewrite' });

A rewrite writes the document as it is now and nothing else. See Saving.

Permissions#

Marking is annotation work: creating a redact annotation needs the permission to create annotations. Applying needs all three of doc.redact, doc.pages.modify and doc.annotate.modify, because it changes the page and removes annotations. Without them, apply() fails with Forbidden. See Permissions.

Give doc.redact to the people who decide what goes; others can still mark areas for them.

Good to know#

Marks from other apps#

A redact annotation made by another app (Acrobat, for example) applies the same way. When it carries its own finished overlay, the engine paints that; otherwise it paints the fill and text from the fields above.

When a page fails#

Apply is all or nothing. When a page fails, or the call is cancelled, no page changes and the call rejects with the error. Apply again to retry.

Events#

Other code can follow redactions with the redaction.applied event. See Events.

Was this page helpful?

Your feedback goes directly to the documentation team.