> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/annotation/annotation-types/redactionannotation.md).

# Redaction Annotations

Discover how redaction annotations can be used to mark and redact sensitive content in PDFs. Learn about text selection, rectangle redactions, and the two-step process for creating and applying redact

Redaction annotations are annotations that mark areas of the PDF for redaction. They can exist as a text selection or rectangle to redact text or an area of a page respectively. Redaction occurs in two steps: creating the redaction and applying the redaction. The redaction application button will only appear when the full API is enabled.

Redaction annotations support both fill and stroke colors. They appear as empty rectangles with a border by default until you hover over them. Then the fill color and overlay text will appear, giving a preview of the redaction result.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-0cc13e819c14a4fb008c0b25ca0eebae08d002c3%2Fcbff22172c81b2bad35486c184bcd355201e50b5-243x155.png?alt=media)

## Instantiation

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, annotationManager, Annotations } = instance.Core;

    let debounce = null;

    // Automatically create redaction annotations on text selection
    documentViewer.addEventListener('textSelected', (quads, text, pageNumber) => {
      // Add some debouncing to prevent constant triggering during selection
      if (debounce) {
        clearTimeout(debounce);
      }
      debounce = setTimeout(() => {
        // Create annotation with object initializer
        const annot = new Annotations.RedactionAnnotation({
          PageNumber: pageNumber,
          Quads: quads,
          StrokeColor: new Annotations.Color(255, 0, 0, 1),
          IsText: true, // Create either a text or rectangular redaction
        });

        // Set annotation preview text to appear in the Redaction Panel
        annot.setCustomData('trn-annot-preview', text);
        annot.Author = annotationManager.getCurrentUser();

        annotationManager.addAnnotation(annot);
        annotationManager.redrawAnnotation(annot);

        debounce = null;
      }, 1000);
    });
  });
```

{% endcode %}

[DocumentViewer#textSelected](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:textSelected) [RedactionAnnotation](https://sdk.apryse.com/api/web/Core.Annotations.RedactionAnnotation.html) [Color](https://sdk.apryse.com/api/web/Core.Annotations.Color.html) [AnnotationManager.addAnnotation](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#addAnnotation) [AnnotationManager.redrawAnnotation](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#redrawAnnotation)
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { docViewer, annotManager, Annotations } = instance;

    let debounce = null;

    // Automatically create redaction annotations on text selection
    docViewer.on('textSelected', (quads, text, pageNumber) => {
      // Add some debouncing to prevent constant triggering during selection
      if (debounce) {
        clearTimeout(debounce);
      }
      debounce = setTimeout(() => {
        // Create annotation
        const annot = new Annotations.RedactionAnnotation();
        annot.PageNumber = pageNumber;
        annot.Quads = quads;
        annot.StrokeColor = new Annotations.Color(255, 0, 0, 1);
        annot.IsText = true; // Create either a text or rectangular redaction

        annotManager.addAnnotation(annot);
        annotManager.redrawAnnotation(annot);

        debounce = null;
      }, 1000);
    });
  });
```

{% endcode %}

[DocumentViewer#textSelected](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:textSelected) [RedactionAnnotation](https://sdk.apryse.com/api/web/Core.Annotations.RedactionAnnotation.html) [Color](https://sdk.apryse.com/api/web/Core.Annotations.Color.html) [AnnotationManager.addAnnotation](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#addAnnotation) [AnnotationManager.redrawAnnotation](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#redrawAnnotation)
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Redaction annotations can be initialized with either the **Quads** property or the **Rect** property. The annotation will automatically determine whether it should be a text or rectangular redaction based on which property was used if **IsText** was not provided. When **IsText** is provided, the user-defined type is respected and the annotation will automatically initialize the right properties.
{% endhint %}

## XFDF

Element name: `redact`

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
<redact page="0" rect="50,692,100,742" color="#FF0000" flags="print" name="80e33e9b-8ecd-82e7-e4dc-a67ac0281877" subject="Redact" date="D:20220727150859-07'00'" interior-color="#000000" width="1.5" creationdate="D:20220727150859-07'00'">
  <trn-custom-data bytes="{"trn-annot-no-move":"false"}"/>
  <defaultappearance>1 0 0 RG /Helvetica 18 Tf</defaultappearance>
</redact>
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Required properties

### PageNumber

Gets or sets the page number of a document that the annotation appears on.

### Quads

Gets of sets the text quads of the annotation. Since text annotations can span multiple lines of text, the lines of text are represented with an array of quads.

If the redaction is rectangular, only the first quad will be used.

### IsText

Gets or sets whether the redaction will be treated as a text redaction or rectangular area redaction. If this is not provided, then the annotation will try to make an assumption based on the number of quads provided.

## Notable properties

For the full list of properties, please visit the annotation's [API docs](https://sdk.apryse.com/api/web/Core.Annotations.RedactionAnnotation.html).

### OverlayText

Text to show after redaction has been applied. You can see a preview when hovering over the annotation.

### FontSize

Gets or sets the size of the overlay text. It accepts a string and defaults to `18pt`.

### TextAlign

The horizontal alignment of the annotation's text.

Values:

* left
* center
* right
* justify

This affects the redaction text.

### TextColor

The color of the redaction overlay text. The default is red.

### StrokeColor

Gets or sets the color of the annotation's stroke.

### FillColor

Gets or sets the color of the annotation's interior.

### FillDisplayColor

Gets or sets the color shown when mouse is not hovering over the annotation.

### StrokeThickness

Gets or sets the width of the annotation's stroke outline.

### IsHovering

Gets or sets whether the cursor is hovering over the annotation.

### Author

The author of the annotation.

### Color

Gets or sets the annotation's stroke color.

### Hidden

Gets or sets whether the annotation is hidden.

### Invisible

Gets or sets whether the annotation is invisible, only if it is an unknown annotation type. Generally for hiding annotations you should use "Hidden".

### Listable

Gets or sets whether the annotation should be listed in annotation lists. If set to false, the annotation will also become unselectable.

### Locked

Gets or sets whether the annotation is locked or not. If it's locked it can't be edited or deleted, but the note can be edited.

### LockedContents

Gets or sets whether the annotation contents are locked or not. If the contents are locked then note can't be edited but the annotation can be edited or deleted.

### NoDelete

Gets or sets if this annotation can be deleted.

### NoView

Gets or sets whether the annotation is visible on the screen. Differs from Hidden in that it can still be printed if the print flag is set.

### Opacity

Gets or sets the opacity of the annotation.

### Printable

Gets or sets whether the annotation should be displayed when printing the page.

### ReadOnly

Gets or sets whether the annotation is readonly or not. If it's readonly both the annotation itself and its note can't be edited or deleted.

### ToggleNoView

Gets or sets whether the ToggleNoView flag is set on the annotation.

## Useful methods

### getQuads

Although it is possible to get the quads using the `Quads` property, there is also a `getQuads` method on the annotation to get its quads.

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
console.log(redaction.getQuads());
[
   { // First quad of the first line
      "x1":58.24,
      "y1":98.97,
      "x2":265.13,
      "y2":98.97,
      "x3":265.13,
      "y3":87.47,
      "x4":58.25,
      "y4":87.47
   },
   ... // Second quad of the second line and so on
]
```

{% endcode %}
{% endtab %}
{% endtabs %}

### setQuads

Using the `setQuads` API can be used to set the quads for the annotation as well.

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotationManager, Annotations } = instance.Core;

    annotationManager.addEventListener('annotationChanged', (annotations, action) => {
      if (annotations.length > 0 && action === 'add') {
        annotations.forEach(annot => {
          if (annot instanceof Annotations.RedactionAnnotation) {
            const quads = annot.getQuads();
            quads.forEach(quad => {
              quad.x1 = Math.round(quad.x1 * 100) / 100;
              quad.y1 = Math.round(quad.y1 * 100) / 100;
            });
            annot.setQuads(quads);
          }
        });
      }
    });
  });
```

{% endcode %}

[RedactionAnnotation.setQuads](https://sdk.apryse.com/api/web/Core.Annotations.RedactionAnnotation.html#setQuads)
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { annotManager, Annotations } = instance;

    annotManager.on('annotationChanged', (annotations, action) => {
      if (annotations.length > 0 && action === 'add') {
        annotations.forEach(annot => {
          if (annot instanceof Annotations.RedactionAnnotation) {
            const quads = annot.getQuads();
            quads.forEach(quad => {
              quad.x1 = Math.round(quad.x1 * 100) / 100;
              quad.y1 = Math.round(quad.y1 * 100) / 100;
            });
            annot.setQuads(quads);
          }
        });
      }
    });
  });
```

{% endcode %}

[RedactionAnnotation.setQuads](https://sdk.apryse.com/api/web/Core.Annotations.RedactionAnnotation.html#setQuads)
{% endtab %}
{% endtabs %}

## Other notes

Applying redactions are not done through the annotation but through the [`applyRedactions`](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#applyRedactions) API on the AnnotationManager. You can provide a subset of redactions to apply to avoid redacting all redactions before they are ready.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/annotation/annotation-types/redactionannotation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
