Skip to content
Retrieving Revision of a PDF Document

Retrieving Revision of a PDF Document

Signing appends rather than rewrites, so a document signed twice contains every version it had before plus one revision per signature. A PdfReader can hand you a reader over any of them, which is how you recover what a signature actually signed rather than what the file looks like now.

CallReturns
GetRevisionNumber()The revision the reader is currently on. The original file is 0.
GetPreviousRevision()A reader one revision back.
GetRevision(n)A reader on revision n, walking back from the current one.

Getting a revision

// Before signing.
inputRevision := pdfReader.GetRevisionNumber()

// ... sign twice, reopen the result as reader ...

prevReader, err := reader.GetRevision(inputRevision)
if err != nil {
    return err
}

appender, err := model.NewPdfAppender(prevReader)
if err != nil {
    return err
}
return appender.WriteToFile(outputPath)

Recording GetRevisionNumber before signing is what makes this work for any input. Revision 0 is the document before any incremental update, which is the unsigned original only when the input had never been updated. An input that already carries a signature, or any other incremental update, has a higher number, and asking for 0 would discard those revisions too. GetRevision(reader.GetRevisionNumber()) returns the same reader you passed in, not a copy.

Writing the revision out through an appender that has nothing appended keeps the revision’s bytes unchanged at the start of the file and adds a small update after them with a new /Info dictionary and catalog. A PdfWriter obtained from prevReader.ToWriter would work too, but it rebuilds the file and so does not preserve the byte ranges any signature in that revision depends on.

Limitations

Revision numbers are absolute, not relative. GetRevision rejects anything outside 0..GetRevisionNumber() with wrong revision number, and GetPreviousRevision on the original returns previous version is not exist.

Revisions are only visible where the document was built by incremental update. A file that was signed, then rewritten by another tool, is one revision as far as the parser is concerned, whatever its history.

Each revision is a full PdfReader over the truncated byte range, and they are cached on the reader, so walking back through a heavily updated document holds every intermediate revision in memory until the reader is released.

GetRevision walks backwards one revision at a time, so asking for revision 0 of a document with fifty revisions parses fifty of them.

Run the example

The example records the input’s revision number, signs the input twice with generated keys, then calls retrieveSpecificRevision with the recorded number to write the document as it was before signing. For an input with no incremental updates that is revision 0; for an input that was already signed once it is revision 1. retrievePreviousRevision, which writes the state before the last change (here, the document with only the first new signature), is in the source with the call commented out in main.

git clone https://github.com/unidoc/unipdf-examples.git
cd unipdf-examples/signatures/signing
go run pdf_sign_get_revision.go <INPUT_PDF_PATH> <OUTPUT_PDF_PATH>

If this is your first time using UniPDF, follow the getting started guide to create an API key and set up your development environment.

View the full source

Sample output

2026/10/21 13:08:52 PDF file successfully signed
2026/10/21 13:08:52 PDF file successfully signed
2026/10/21 13:08:52 Revision 0 written to output path: signed_and_get_revision.pdf
Done

Retrieved revision of the signed document

Last updated on