---
title: "Adding text markup annotations to a PDF document | Nutrient Python SDK"
canonical_url: "https://www.nutrient.io/guides/python/editor/add-text-markup-annotations-to-pdf/"
md_url: "https://www.nutrient.io/guides/python/editor/add-text-markup-annotations-to-pdf.md"
last_updated: "2026-05-23T00:08:18.143Z"
description: "How to add text markup annotations to a PDF using Nutrient Python SDK."
---

# Adding text markup annotations to a PDF document

Use text markup annotations to add review feedback directly on text in PDF files.

Common use cases include:

- Proofreading workflows

- Collaborative document review

- Content highlighting and emphasis

- Revision and deletion tracking

In this guide, you’ll add:

- Highlight annotations

- Underline annotations

- Strikeout annotations

- Squiggly annotations

- Custom colors for each markup type

[Download sample](https://www.nutrient.io/downloads/samples/python/add-text-markup-annotations-to-pdf.zip)

## How Nutrient helps

Nutrient Python SDK handles text markup annotation structures and appearance generation.

The SDK handles:

- Text markup dictionaries and quadrilateral arrays

- Translucent overlays and blend modes

- Coordinate calculations and bounding box intersections

- Appearance streams and color transformations

## Complete implementation

This example adds several text markup annotations to a PDF file:

```python

from nutrient_sdk import Document
from nutrient_sdk import PdfEditor
from nutrient_sdk import Color
from nutrient_sdk import NutrientException

```

## Working with text markup annotations

Open the document in a [context manager](https://docs.python.org/3/reference/datamodel.html#context-managers) so resources are cleaned up after processing.

Then:

- Create a PDF editor.

- Get the page collection.

- Add a letter-size page (`612 × 792`) if the document is empty.

- Get the annotation collection from the first page.

```python

def main():
    try:
        with Document.open("input.pdf") as document:
            editor = PdfEditor.edit(document)
            pages = editor.get_page_collection()

            if pages.get_count() == 0:
                pages.add(612.0, 792.0)

            page = pages.get_first()
            annotations = page.get_annotation_collection()

```

## Adding a highlight annotation

Add a highlight with `add_highlight(x, y, width, height, author, contents)`.

In this sample:

- The position is `(50, 700)`.

- The size is `150 × 20`.

- The color is set to translucent yellow with `Color.from_argb(128, 255, 255, 0)`.

- The alpha value `128` gives 50 percent opacity.

```python

            highlight = annotations.add_highlight(
                50.0, 700.0, 150.0, 20.0,  # x, y, width, height

                "Highlighter",
                "Important information"
            )
            # Optionally customize the color

            highlight.color = Color.from_argb(128, 255, 255, 0)

```

## Adding an underline annotation

Add an underline with `add_underline(x, y, width, height, author, contents)`.

In this sample:

- The position is `(50, 650)`.

- The size is `150 × 20`.

- The color is set to blue with `Color.from_argb(255, 0, 0, 255)`.

```python

            underline = annotations.add_underline(
                50.0, 650.0, 150.0, 20.0,  # x, y, width, height

                "Underliner",
                "Emphasized text"
            )
            # Optionally customize the color.

            underline.color = Color.from_argb(255, 0, 0, 255)

```

## Adding a strikeout annotation

Add a strikeout with `add_strike_out(x, y, width, height, author, contents)`.

In this sample:

- The position is `(50, 600)`.

- The size is `150 × 20`.

- The default color is red (`ARGB 255, 255, 0, 0`).

- Use this style to mark text for removal.

```python

            strike_out = annotations.add_strike_out(
                50.0, 600.0, 150.0, 20.0,  # x, y, width, height

                "Reviewer",
                "This content should be removed"
            )

```

## Adding a squiggly annotation

Add a squiggly underline with `add_squiggly(x, y, width, height, author, contents)`.

In this sample:

- The position is `(50, 550)`.

- The size is `150 × 20`.

- The color is changed to green with `Color.from_argb(255, 0, 128, 0)`.

- Use this style to flag spelling or grammar issues.

```python

            squiggly = annotations.add_squiggly(
                50.0, 550.0, 150.0, 20.0,  # x, y, width, height

                "Proofreader",
                "Check spelling here"
            )
            # Optionally customize the color

            squiggly.color = Color.from_argb(255, 0, 128, 0)

```

## Saving the document

Save the output PDF and close the editor.

The `except` block catches `NutrientException` if processing fails:

```python

            editor.save_as("output.pdf")
            editor.close()
    except NutrientException as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()

```

## Conclusion

Use this workflow to add text markup annotations:

1. Open the document using a [context manager](https://docs.python.org/3/reference/datamodel.html#context-managers) for automatic resource cleanup.

2. Create an editor and access the page collection.

3. Ensure at least one page exists by adding a letter-size page if needed.

4. Retrieve the annotation collection from the target page.

5. Add highlight annotations with translucent overlays using `add_highlight()` for emphasizing content.

6. Customize highlight transparency using ARGB alpha values (128 = 50 percent transparency).

7. Add underline annotations with `add_underline()` for drawing attention beneath text.

8. Add strikeout annotations with `add_strike_out()` for marking deleted or outdated content.

9. Add squiggly annotations with `add_squiggly()` for indicating spelling or grammar issues.

10. Customize text markup colors using the `color` property with ARGB color values.

11. Position annotations with consistent vertical spacing to create organized markup sequences.

12. Save and close the editor.

For related annotation workflows, refer to the [Python SDK annotation guides](https://www.nutrient.io/guides/python/editor.md).
---

## Related pages

- [Adding a custom page to a PDF document](/guides/python/editor/add-custom-page-to-pdf.md)
- [Adding interactive form fields to a PDF document](/guides/python/editor/add-form-fields-to-pdf.md)
- [Adding redaction annotations to a PDF document](/guides/python/editor/add-redaction-annotations-to-pdf.md)
- [Adding invisible digital signatures to a PDF document](/guides/python/editor/add-invisible-signature-to-pdf.md)
- [Adding free text annotations to a PDF document](/guides/python/editor/add-freetext-annotations-to-pdf.md)
- [Adding shape annotations to a PDF document](/guides/python/editor/add-shape-annotations-to-pdf.md)
- [Adding sticky note annotations to a PDF document](/guides/python/editor/add-sticky-note-annotations-to-pdf.md)
- [Adding stamp annotations to a PDF document](/guides/python/editor/add-stamp-annotations-to-pdf.md)
- [Adding link annotations to a PDF document](/guides/python/editor/add-link-annotations-to-pdf.md)
- [Adding visible digital signatures to a PDF document](/guides/python/editor/add-visible-signature-to-pdf.md)
- [Editing PDF form fields](/guides/python/editor/editing-pdf-form-fields.md)
- [Editing PDF metadata with Nutrient Python SDK](/guides/python/editor/editing-pdf-metadata.md)
- [Advanced digital signature workflows](/guides/python/editor/advanced-digital-signatures.md)
- [Filling PDF form fields](/guides/python/editor/fill-pdf-form.md)
- [Managing PDF page order](/guides/python/editor/manage-pdf-page-order.md)
- [Adding annotations to a PDF document](/guides/python/editor/add-annotations-to-pdf.md)
- [Nutrient Python SDK editor guides](/guides/python/editor.md)
- [Merging PDFs](/guides/python/editor/merge-pdf-into-other-pdf.md)

