This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/dotnet/csharp/editor/add-annotations-to-pdf.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Adding annotations to a PDF document | Nutrient .NET SDK

Adding PDF annotations programmatically enables teams to automate document review workflows, build collaboration tools, and implement markup systems. Whether you’re building document approval systems, implementing automated feedback tools, or creating document annotation platforms, the annotations API provides complete control over annotation types, enabling you to add sticky notes, text markup, stamps, and links, and manage existing annotations without manual PDF editing.

Download sample

How Nutrient helps you achieve this

Nutrient .NET SDK handles PDF annotation structures and appearance stream generation. With the SDK, you don’t need to worry about:

  • Parsing annotation dictionaries and appearance streams
  • Managing annotation flags and border styles
  • Handling coordinate transformations and bounding box calculations
  • Complex annotation state management and reply chains

Instead, Nutrient provides an API that handles all the complexity behind the scenes, letting you focus on your business logic.

Complete implementation

Below is a complete working example that demonstrates adding various annotation types to a PDF. The following line sets up the C# application by importing the Nutrient namespace:

using Nutrient;

The Document.Open() call opens the PDF document. The using statement(opens in a new tab) ensures the document and editor are automatically closed when you’re done, preventing resource leaks. The following code creates a PDF editor, accesses the page collection, and ensures at least one page exists by adding a letter-size page (612×792 points) if the document is empty:

try
{
using Document document = Document.Open("input.pdf");
using PdfEditor editor = PdfEditor.Edit(document);
PdfPageCollection pages = editor.PageCollection;
if (pages.Count == 0)
{
pages.Add(612.0f, 792.0f);
}
PdfPage page = pages.First ?? throw new InvalidOperationException("The document has no pages.");
PdfAnnotationCollection annotations = page.AnnotationCollection;

annotations is bound to pages.First, so all annotations added through this collection are created on that first page.

The following code adds a sticky note annotation at coordinates (100, 700) with author metadata, subject, and comment text. After creation, the color is set to yellow using ARGB values (alpha, red, green, blue). Sticky notes are useful for adding comments and review feedback to documents:

PdfTextAnnotation stickyNote = annotations.AddStickyNote(
100.0f, 700.0f,
"Test Author",
"Test Subject",
"This is a sticky note comment"
);
// Customize the color
stickyNote.Color = Color.FromArgb(255, 255, 255, 0);

The following code blocks add four text markup annotation types: highlight, underline, strikeout, and squiggly. Each annotation is positioned using x, y, width, and height coordinates to define the markup area. The methods accept author and contents parameters for metadata. Colors are customized after creation using ARGB values. These annotations are commonly used for document review workflows to mark text for emphasis, correction, or deletion:

PdfHighlightAnnotation highlight = annotations.AddHighlight(
50.0f, 600.0f, 150.0f, 20.0f, // x, y, width, height
"Highlighter",
"Highlighted text area"
);
highlight.Color = Color.FromArgb(128, 255, 255, 0);
PdfUnderlineAnnotation underline = annotations.AddUnderline(
50.0f, 550.0f, 150.0f, 20.0f, // x, y, width, height
"Underliner",
"Underlined text area"
);
underline.Color = Color.FromArgb(255, 0, 0, 255);
PdfStrikeOutAnnotation strikeOut = annotations.AddStrikeOut(
50.0f, 500.0f, 150.0f, 20.0f, // x, y, width, height
"Striker",
"Struck out text area"
);
strikeOut.Color = Color.FromArgb(255, 255, 0, 0);
PdfSquigglyAnnotation squiggly = annotations.AddSquiggly(
50.0f, 450.0f, 150.0f, 20.0f, // x, y, width, height
"Squiggler",
"Squiggly underlined area"
);
squiggly.Color = Color.FromArgb(255, 0, 128, 0);

The following code adds a rubber stamp annotation at coordinates (300, 600) with dimensions 100×50 points. Stamps are created with a default “Draft” style and can be customized with title and contents text. The color is set to purple using ARGB values. Stamp annotations are typically used for approval workflows to indicate document status:

PdfStampAnnotation stamp = annotations.AddStamp(
300.0f, 600.0f, 100.0f, 50.0f, // x, y, width, height
"Stamp Title",
"Stamp contents"
);
// Customize the color
stamp.Color = Color.FromArgb(255, 128, 0, 128);

The following code adds a new page to the document and creates an internal link annotation at coordinates (300, 500) with dimensions 200×20 points. The SetDestination() method configures the link to navigate to page 2 at coordinates (0, 792). Note that annotations still points to the first page (pages.First), so this link annotation is created on the original first page, not on the newly added page. Link annotations enable navigation within documents and to external resources:

pages.Add(612.0f, 792.0f);
PdfLinkAnnotation pageLink = annotations.AddLink(300.0f, 500.0f, 200.0f, 20.0f);
pageLink.SetDestination(2, 0.0f, 792.0f);

The annotation collection reports how many annotations exist on the page through Count, enabling you to verify additions or drive processing logic. The count includes both pre-existing annotations and the ones added in this sample, so it can be higher than the number of newly created annotations alone. The RemoveAt() method removes the annotation at the specified zero-based index; RemoveAt(0) removes whichever annotation is currently first on that page, which may be an existing annotation if the input already contains annotations. The following code prints the annotation count, removes the first annotation, and saves the changes. The try-catch block handles potential errors using NutrientException:

Console.WriteLine($"Annotations on first page: {annotations.Count}");
annotations.RemoveAt(0);
editor.SaveAs("output.pdf");
Console.WriteLine("Successfully saved output.pdf");
}
catch (NutrientException e)
{
Console.Error.WriteLine($"Error: {e.Message}");
Environment.Exit(1);
}

Error handling

Nutrient .NET SDK handles errors with exception handling. The methods presented in this guide throw a NutrientException if a failure occurs. The using statements release the editor and document handles even when a step fails.

Conclusion

The annotation creation workflow consists of several key operations:

  1. Open the document and create an editor.
  2. Access the page collection and ensure at least one page exists.
  3. Retrieve the annotation collection for the target page.
  4. Add sticky note annotations with author and comment metadata.
  5. Add text markup annotations (highlight, underline, strikeout, squiggly) with positioning and colors.
  6. Add stamp annotations for document status indication.
  7. Add link annotations for internal page navigation.
  8. Inspect the annotation count for processing or verification.
  9. Remove annotations by index position.
  10. Save the document — the using statements release the native handles.

Nutrient handles annotation dictionary structures and appearance stream generation so you don’t need to understand PDF annotation specifications or manage coordinate transformations manually.