---
title: "Building an audit trail for AI-edited documents"
canonical_url: "https://www.nutrient.io/blog/document-authoring-audit-trail/"
md_url: "https://www.nutrient.io/blog/document-authoring-audit-trail.md"
last_updated: "2026-09-18T16:20:04.301Z"
description: "Document Authoring 1.20 adds revision APIs, transaction reports, and participant roles to help applications record and verify AI-assisted document changes."
---

**TL;DR**

- Document Authoring 1.20 lets applications query, accept, and reject tracked changes through the API; generate transaction reports with document hashes; and control editing permissions with participant roles.

- Each transaction report includes hashes of the document before and after the transaction, plus metadata about the changes. Applications can use the hashes to check whether a saved document matches the reported state.

- Reports are unsigned, and author names are supplied by the host application. The host application must authenticate users and securely retain the reports and associated document versions.

**Call to Action**

Explore Nutrient Document Authoring

[Learn More](https://www.nutrient.io/sdk/document-authoring/)

Nutrient Document Authoring enables AI models to propose edits to a document, landing them as tracked changes with comments explaining each one. In Review mode, a human reviewer accepts or rejects those changes with that context in hand. But inspecting the decision later takes more than the tracked change itself: An application also needs to record the outcome, tie it to an authenticated user, and retain the document state it applied to.

[Document Authoring 1.20](https://www.nutrient.io/guides/document-authoring/release-notes/1-20-0.md) adds three capabilities on top of the existing tracked-changes model: Document access can be scoped to roles instead of an all-or-nothing editor, a transaction can produce a report with hashes to check whether a saved document matches its recorded state, and revisions become queryable and decidable through the API.

## Separate proposed edits from approval

Tracked changes already answer “what changed,” but not whether the person who accepted a change was allowed to. Every reviewer with access to a document could accept or reject any revision in it. That works for a two-person workflow. It works less well once contract redlining, discharge-summary drafting, or RFP assembly all run through the same editor, sometimes with an AI agent proposing half the changes.

[Participant roles](https://www.nutrient.io/guides/document-authoring/review-and-collaboration/permissions.md) fix the “who” side. Loading a document now takes a `participant`, made up of an author label and a role of `owner`, `reviewer`, or `reader`:

```typescript

const document = await system.loadDocument(input, {
  participant: { author: 'Dana Reviewer', role: 'reviewer' },
});

```

An owner edits content and can accept or reject revisions. A reviewer can propose tracked changes and comments and withdraw their own pending suggestions, but they can’t approve revisions. A reader can’t change the document at all. These permissions apply to editor clicks and programmatic transactions alike, so a script that opens a document as a `reviewer` is held to the same limit a human reviewer would be. A programmatic transaction made as a reviewer must also include a `review.author` value matching the participant’s author label.

In the interactive editor, a second, independent check applies. `canPerformTrackedChange` is a callback the host supplies when creating the editor, and it can deny a specific create, accept, or reject operation for reasons the role system doesn’t know about: a legal hold on one clause, or a reviewer who’s recused from one specific contract. It only governs edits made through the editor UI; a programmatic transaction, like the script above, doesn’t call it. Both checks have to pass wherever both apply.

One caveat, straight from the [permissions guide](https://www.nutrient.io/guides/document-authoring/review-and-collaboration/permissions.md): The participant `author` is a label the host application supplies. It isn’t authentication, and Document Authoring doesn’t verify it. Proving a name is who it claims to be is the application’s job. Bind it to an authenticated user before the label means anything in an audit.

## A digest isn’t a signature

The second gap is about content rather than identity: proving a document is exactly what a transaction claims it produced without rediffing the whole file by eye.

[`transactionWithReport()`](https://www.nutrient.io/guides/document-authoring/editing-content/transaction-reports/) is an opt-in variant of the same transaction API Document Authoring has always used. It returns the callback’s result alongside a report: a `beforeDigest` and `afterDigest` (SHA-256 hashes of the document’s canonical JSON representation), plus a typed list of every revision, comment, and direct edit the transaction touched:

```typescript

const { result, report } = await document.transactionWithReport(async ({ draft }) => {
  const paragraph = draft.body().content().addParagraph();
  paragraph.asTextView().setText('Applied redline.');
  return { commit: true, result: { summary: 'Applied redline' } };
});

```

Hash the same canonical export independently later, and a mismatch against `report.afterDigest` means the document changed after the fact. Nothing about the check depends on visual inspection.

That’s as far as the guarantee goes, and the [transaction reports guide](https://www.nutrient.io/guides/document-authoring/editing-content/transaction-reports.md) is explicit about the boundary: A transaction report is unsigned. The digest verifies what the document contains, but not who produced it or whether they were allowed to. That’s what the participant role is for.

## Revisions, queried like data instead of clicked one at a time

The third addition is what makes the other two practical at volume. Revisions can now be listed, filtered, and decided through the API instead of only through the tracked-changes UI:

```typescript

await document.transaction(async ({ draft }) => {
  const revisions = draft.revisions();
  const insertions = revisions.all({ author, type: 'insertion' });
  return { commit: true, result: revisions.accept({ ids: insertions.map((r) => r.id) }) };
});

```

[`RevisionCollection.all()`](https://www.nutrient.io/guides/document-authoring/review-and-collaboration/programmatic-tracked-changes/) queries revisions by author or type instead of scrolling through the review pane by hand. Accept or reject the matching set in one call — by ID, by author, or by a text range — inside the same transaction that can also produce a verifiable report.

Withdrawal works differently: It’s an item-level operation, one revision at a time, and only the revision’s own author can withdraw it.

[Review events](https://www.nutrient.io/guides/document-authoring/review-and-collaboration/review-events.md) report activity to anything watching from outside the editor: lifecycle events for attempted, completed, and denied operations in the interactive UI, and committed-change events (`revision.accepted`, `comment.resolved`, and the rest) for both editor input and programmatic transactions. That’s the difference between an audit trail someone has to go looking for and one a compliance system can watch continuously.

## Why this is the right layer to build now

None of this is a new editing surface. [Document Authoring AI](https://www.nutrient.io/blog/introducing-document-authoring-ai/) already lets a model draft a redline against a compliance playbook and apply it as a [tracked change with a comment explaining the fix](https://www.nutrient.io/blog/ai-contract-redlining-compliance-playbook.md). What 1.20 adds is the layer underneath it: a record that has to hold up in legal, healthcare, and financial workflows long after everyone who touched the document has moved on to the next contract.

The three additions don’t replace what shipped before — they compose: Gate the whole thing behind a participant role, wrap the decision in a transaction that reports a verifiable hash, and query revisions by author.

## Getting started

Programmatic tracked changes, transaction reports, review permissions, and review events each have their own guide, with full code:

- [Programmatic tracked changes](https://www.nutrient.io/guides/document-authoring/review-and-collaboration/programmatic-tracked-changes.md) — List, filter, accept, reject, and withdraw revisions through the API.

- [Transaction reports](https://www.nutrient.io/guides/document-authoring/editing-content/transaction-reports.md) — Generate and verify a before-and-after document digest.

- [Review permissions](https://www.nutrient.io/guides/document-authoring/review-and-collaboration/permissions.md) — Assign participant roles and restrict editor-originated decisions.

- [Review events](https://www.nutrient.io/guides/document-authoring/review-and-collaboration/review-events.md) — Observe tracked-change and comment activity from outside the editor.

For a working AI-editing pipeline that already lands changes as tracked changes with reasoning comments, see [building an AI legal assistant](https://www.nutrient.io/blog/ai-legal-assistant-document-authoring.md) and [AI contract redlining against a compliance playbook](https://www.nutrient.io/blog/ai-contract-redlining-compliance-playbook.md). The 1.20 audit layer sits directly underneath both.

**Call to Action**

Get started with Nutrient Document Authoring

[Learn More](https://www.nutrient.io/sdk/document-authoring/getting-started.md)

## FAQ

#### Does a transaction report prove who made a change?

No. A transaction report is unsigned. Its digest verifies the document’s content, not the identity of who produced it. The participant `author` label is metadata the host application supplies; proving it belongs to a specific person means binding it to an authenticated user in the application, which isn’t something Document Authoring does on its own.

#### Do participant roles replace <code>canPerformTrackedChange</code>?

No. They’re independent checks that both have to pass. A participant role (owner, reviewer, reader) is a document-wide policy that also applies to programmatic transactions. `canPerformTrackedChange` is an editor-only callback for finer-grained, host-defined rules (a legal hold, a recusal) that a role alone can’t express.

#### Can revisions be queried and decided outside the tracked-changes UI?

Yes. `draft.revisions()` lists pending revisions in document order and can be filtered by author or type. Matching revisions can be accepted or rejected in one call, inside the same transaction that can also produce a verifiable report. Withdrawing a revision is a separate, one-at-a-time operation, and only its own author can withdraw it.

#### Is this a new review UI?

No. Tracked changes, comments, and the Edit, Review, and View editor modes are unchanged. 1.20 adds API-level auditability and access control on top of that existing review surface. It doesn’t add a second one.
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [How to build an AI agent for contract redlining against a compliance playbook](/blog/ai-contract-redlining-compliance-playbook.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Document Workflows Ocr Compliance Heavy Teams](/blog/ai-document-workflows-ocr-compliance-heavy-teams.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Amazon Textract Alternatives](/blog/amazon-textract-alternatives.md)
- [Start (clears any prior buffer), navigate the document, then stop into a file.](/blog/android-faster-pdf-rendering.md)
- [Android Pdf Out Of Memory Handling](/blog/android-pdf-out-of-memory-handling.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Approval Workflow Software](/blog/approval-workflow-software.md)
- [Approvals Matrix](/blog/approvals-matrix.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Simple PII redaction.](/blog/automated-pii-removal.md)
- [Azure Document Intelligence Alternatives](/blog/azure-document-intelligence-alternatives.md)
- [Best Ai Document Workflow Platforms](/blog/best-ai-document-workflow-platforms.md)
- [Best Document Ai Platforms](/blog/best-document-ai-platforms.md)
- [Best Document Classification Platforms](/blog/best-document-classification-platforms.md)
- [Best document parser for RAG: LlamaParse vs. Unstructured vs. Reducto vs. Nutrient](/blog/best-document-parser-llamaparse-unstructured-reducto.md)
- [Best Document Parsing Apis](/blog/best-document-parsing-apis.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [Best Llm Document Understanding Platforms](/blog/best-llm-document-understanding-platforms.md)
- [Best Multilingual Ocr Software](/blog/best-multilingual-ocr-software.md)
- [Best Pdf Parsers For Rag](/blog/best-pdf-parsers-for-rag.md)
- [Best Salesforce Document Generation Apps](/blog/best-salesforce-document-generation-apps.md)
- [Best Secure Document Collaboration Platforms](/blog/best-secure-document-collaboration-platforms.md)
- [Bpm Guide](/blog/bpm-guide.md)
- [Bpm Tools](/blog/bpm-tools.md)
- [Build Vs Buy Document Extraction](/blog/build-vs-buy-document-extraction.md)
- [Business Automation](/blog/business-automation.md)
- [Capex Vs Opex](/blog/capex-vs-opex.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [1. Extract and chunk the PDF.](/blog/chat-with-pdf.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Docling Alternatives](/blog/docling-alternatives.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Extraction Confidence Scores](/blog/document-extraction-confidence-scores.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [Extend Alternatives](/blog/extend-alternatives.md)
- [Extract Patient Data On Premises](/blog/extract-patient-data-on-premises.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [Fillable Pdf](/blog/fillable-pdf.md)
- [Google Document Ai Alternatives](/blog/google-document-ai-alternatives.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Dotnet Maui Pdf Viewer](/blog/how-to-build-a-dotnet-maui-pdf-viewer.md)
- [How To Build A Flutter Pdf Viewer](/blog/how-to-build-a-flutter-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [How To Build A Nextjs Pdf Viewer](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [or](/blog/how-to-convert-html-to-pdf-using-react.md)
- [How To Convert Html To Pdf Using Wkhtmltopdf And Csharp](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-csharp.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Html To Pptx](/blog/how-to-convert-html-to-pptx.md)
- [Quarterly report](/blog/how-to-convert-pdf-to-markdown-using-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [or](/blog/how-to-create-a-react-js-signature-pad.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Extract Tables From Pdf And Images](/blog/how-to-extract-tables-from-pdf-and-images.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [How To Merge Pdfs Using Javascript](/blog/how-to-merge-pdfs-using-javascript.md)
- [How To Ocr Pdfs In Linux](/blog/how-to-ocr-pdfs-in-linux.md)
- [How To Print Pdf In Csharp](/blog/how-to-print-pdf-in-csharp.md)
- [How To Programmatically Create And Fill Pdf Form In Angular](/blog/how-to-programmatically-create-and-fill-pdf-form-in-angular.md)
- [Open an image.](/blog/how-to-use-tesseract-ocr-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Html To Pdf In Javascript](/blog/html-to-pdf-in-javascript.md)
- [Intelligent Data Extraction](/blog/intelligent-data-extraction.md)
- [Invoice Approval Software](/blog/invoice-approval-software.md)
- [Javascript Document Editor](/blog/javascript-document-editor.md)
- [Javascript Pdf Editors](/blog/javascript-pdf-editors.md)
- [Javascript Pdf Libraries](/blog/javascript-pdf-libraries.md)
- [Landing Ai Alternatives](/blog/landing-ai-alternatives.md)
- [Langextract Vs Llamaindex Extraction Comparison](/blog/langextract-vs-llamaindex-extraction-comparison.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [Uses OpenAI by default — set OPENAI_API_KEY.](/blog/llamaindex-vs-langchain-rag.md)
- [Llamaindex Workflows Vs Langgraph](/blog/llamaindex-workflows-vs-langgraph.md)
- [Llamaparse Alternatives](/blog/llamaparse-alternatives.md)
- [Low Code No Code Document Integrations](/blog/low-code-no-code-document-integrations.md)
- [Material Requisition](/blog/material-requisition.md)
- [or](/blog/merge-pdfs.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Nutrient Flutter 6 Bindings Api](/blog/nutrient-flutter-6-bindings-api.md)
- [Nutrient Flutter Bindings Architecture](/blog/nutrient-flutter-bindings-architecture.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [PDF accessibility for developers: Meeting WCAG 2.2, Section 508, and PDF/UA with an SDK](/blog/pdf-accessibility.md)
- [Extract data from PDF files: A developer guide to structured data from PDFs and scans](/blog/pdf-data-extraction-developer-guide.md)
- [Pdf Extraction Benchmark Opendataloader Bench](/blog/pdf-extraction-benchmark-opendataloader-bench.md)
- [Pdf Extraction Document Case Studies](/blog/pdf-extraction-document-case-studies.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdf Ua Validation](/blog/pdf-ua-validation.md)
- [Pdfjs Accessibility Structtree Printing](/blog/pdfjs-accessibility-structtree-printing.md)
- [Pdfjs Advanced Loading Streaming Workers](/blog/pdfjs-advanced-loading-streaming-workers.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Document Outline Bookmarks Metadata](/blog/pdfjs-document-outline-bookmarks-metadata.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [macOS](/blog/pdfjs-file-format-conversion-to-pdf.md)
- [macOS](/blog/pdfjs-generating-pdf-thumbnails-pdf2pic.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [People Process Tools](/blog/people-process-tools.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [React Pdf Annotation Layer Forms](/blog/react-pdf-annotation-layer-forms.md)
- [React Pdf Custom Rendering Hooks](/blog/react-pdf-custom-rendering-hooks.md)
- [Using Yarn](/blog/react-pdf-editor.md)
- [React Pdf Loading States Errors Passwords](/blog/react-pdf-loading-states-errors-passwords.md)
- [React Pdf Non Latin Fonts Special Pdfs](/blog/react-pdf-non-latin-fonts-special-pdfs.md)
- [React Pdf Outline Table Of Contents](/blog/react-pdf-outline-table-of-contents.md)
- [React Pdf Performance Optimization](/blog/react-pdf-performance-optimization.md)
- [React Pdf Setup Basic Rendering](/blog/react-pdf-setup-basic-rendering.md)
- [React Pdf Text Layer Custom Renderer](/blog/react-pdf-text-layer-custom-renderer.md)
- [React Pdf Thumbnails Page Navigation](/blog/react-pdf-thumbnails-page-navigation.md)
- [Reducto Alternatives](/blog/reducto-alternatives.md)
- [Requisition System](/blog/requisition-system.md)
- [labels.py](/blog/route-documents-automatically-classify-api.md)
- [or](/blog/sample-blog-updated.md)
- [Sdk Product Updates Q2 2026](/blog/sdk-product-updates-q2-2026.md)
- [System Of Record Vs Source Of Truth](/blog/system-of-record-vs-source-of-truth.md)
- [Add DWS MCP Server to your Claude Code project.](/blog/teaching-llms-to-read-pdfs.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [The Six Best Pdf Generator Apis](/blog/the-six-best-pdf-generator-apis.md)
- [Define the HTML part of the document.](/blog/top-10-ways-to-generate-pdfs-in-python.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [or](/blog/top-js-pdf-libraries.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Unstructured Alternatives](/blog/unstructured-alternatives.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Business Logic](/blog/what-is-business-logic.md)
- [What Is Document Processing](/blog/what-is-document-processing.md)
- [What Is Intelligent Document Processing](/blog/what-is-intelligent-document-processing.md)
- [What Is Ocr Invoice Processing](/blog/what-is-ocr-invoice-processing.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

