---
title: "Create transaction reports in Document Authoring"
canonical_url: "https://www.nutrient.io/guides/document-authoring/editing-content/transaction-reports/"
md_url: "https://www.nutrient.io/guides/document-authoring/editing-content/transaction-reports.md"
last_updated: "2026-08-31T00:00:00.000Z"
description: "Create a Document Authoring transaction report, verify the resulting document with its canonical SHA-256 digest, and inspect its typed change list for review."
---

# Create transaction reports

Use [`DocAuthDocument.transactionWithReport()`](https://www.nutrient.io/api/document-authoring/types/docauthdocument/#transactionwithreport) to verify document content before and after a transaction. The method returns the callback result and a [`TransactionReport`](https://www.nutrient.io/api/document-authoring/types/transactionreport/).

The report contains canonical content digests and a typed change list. It doesn’t replace the document or save it to storage.

## Create and verify a report

The following Node.js example imports `review.docx`, adds a paragraph, and verifies the report’s `afterDigest`. It hashes the exact string returned by [`saveDocumentJSONString({ canonical: true })`](https://www.nutrient.io/api/document-authoring/types/docauthdocument/#savedocumentjsonstring).

```js

import { createHash } from 'node:crypto';
import { readFile } from 'node:fs/promises';
import { createDocAuthSystem } from '@nutrient-sdk/document-authoring/node';

async function addReviewSummary() {
	const system = await createDocAuthSystem();

	try {
		const input = await readFile('review.docx');
		const document = await system.import(input, { format: 'docx' });

		const { result, report } = await document.transactionWithReport(async ({ draft }) => {
			const paragraph = draft.body().content().addParagraph();
			paragraph.asTextView().setText('Review completed.');

			return {
				commit: true,
				result: { addedParagraph: true },
			};
		});

		const canonical = await document.saveDocumentJSONString({ canonical: true });
		const actualDigest = createHash('sha256').update(canonical, 'utf8').digest('hex');

		if (actualDigest!== report.afterDigest) {
			throw new Error('The saved document does not match the transaction report.');
		}

		console.log(JSON.stringify({ result, report, verified: true }, null, 2));
		return { result, report };
	} catch (error) {
		console.error('Failed to create or verify the transaction report.', error);
		throw error;
	} finally {
		system.destroy();
	}
}

await addReviewSummary();

```

The command prints `verified: true` when the canonical document matches `report.afterDigest`. The report also includes these values:

- The `beforeDigest` value identifies the canonical document before the transaction.

- The `afterDigest` value identifies the canonical document after the transaction.

- The `changes` value lists revision, comment, and direct changes from the committed transaction.

- The `txId` value identifies the transaction within the current document session.

- The `authorLabel` value contains the author label supplied by the host.

## Use reports only when needed

Report generation is opt-in. [`transactionWithReport()`](https://www.nutrient.io/api/document-authoring/types/docauthdocument/#transactionwithreport) serializes and hashes canonical document content to produce before and after digests. For unchanged snapshots, it reuses the before digest as the after digest.

Use [`transaction()`](https://www.nutrient.io/api/document-authoring/types/docauthdocument/#transaction) when the workflow doesn’t need those digests. This method doesn’t create digests and returns only the callback result.

## Keep each report with its transaction

A report describes one transaction. It doesn’t compare arbitrary document versions or provide a complete history across sessions.

No-op and rolled-back transactions have matching `beforeDigest` and `afterDigest` values. A committed transaction can also have matching digests when it doesn’t change canonical content.

## Treat author labels as metadata

Transaction reports are unsigned. A digest verifies canonical document content, but it doesn’t prove who created or approved that content.

The host supplies `authorLabel`. To verify who made or approved a change, associate the label with an authenticated user and their permissions in your application.

## Learn more

Use these guides for related review and editing workflows:

- Refer to the [programmatic editing](https://www.nutrient.io/guides/document-authoring/editing-content/programmatic-editing.md) guide to run atomic document transactions and choose an editing operation.

- Refer to the [programmatic tracked changes](https://www.nutrient.io/guides/document-authoring/review-and-collaboration/programmatic-tracked-changes.md) guide to list, accept, reject, and withdraw revisions.
---

## Related pages

- [Use copy/paste and HTML interoperability](/guides/document-authoring/editing-content/copy-paste-and-html-interoperability.md)
- [Find and replace text](/guides/document-authoring/editing-content/find-and-replace.md)
- [Work with footnotes and endnotes](/guides/document-authoring/editing-content/footnotes-and-endnotes.md)
- [Work with images and shapes](/guides/document-authoring/editing-content/images-and-shapes.md)
- [Work with lists](/guides/document-authoring/editing-content/lists.md)
- [Edit documents programmatically](/guides/document-authoring/editing-content/programmatic-editing.md)
- [Work with tables](/guides/document-authoring/editing-content/tables.md)
- [Format text](/guides/document-authoring/editing-content/text-and-formatting.md)

