Provenance answers “where does this page come from?” for a document that was assembled from several sources. The editor keeps it per page, so an export can tell the host which pages ended up where.
The simple case
When a PDF is imported — dropped, picked, fetched from Google Drive, scraped by the Chrome extension or handed over by the SDK — every page is recorded as:
{ "source": "contract.pdf", "page": 3 }
The name is the file name and the number is the page inside that file, not the page in the merged document.
Your own provenance
A source document may already be a merged PDF whose original provenance you know. Send one entry per page and the editor keeps it unchanged — any JSON is allowed, so nested structures work:
await editor.loadDocument({
name: 'case-2024-117.pdf',
content: file,
provenance: [
{ source: 'complaint.pdf', page: 1, origin: [{ source: 'scan-01.pdf', page: 1 }] },
{ source: 'exhibit-a.pdf', page: 4, received: '2024-03-02' },
],
});
Pass a single object instead of an array to copy it onto every page (the editor
sets page for you), or omit it to get the default above.
Reading it back
const pages = await editor.getPages();
// [{ id, page, rotate, partName, provenance }, …]
The order is the order on screen, so the list is also the page order of an
export. editing (reordering, rotating, splitting into parts, duplicating) keeps
the provenance attached to the page; deleting a page deletes its entry.
exportDocument returns the provenance of the exported pages as well:
const blob = await editor.exportDocument(0);
editor.on('export', ({ pages }) => {
// [{ page: 1, provenance: { source: 'complaint.pdf', page: 1 } }, …]
});
Writing it into the PDF
With provenance: { attach: true } every exported PDF carries a
provenance.json attachment with one entry per exported page:
{
"version": 1,
"generator": "RSJ PDF Merge",
"created": "2026-10-28T09:46:44.106Z",
"pages": [{ "page": 1, "provenance": { "source": "contract.pdf", "page": 1 } }]
}
Any PDF reader shows it under attachments, and importing such a PDF into the editor restores the provenance automatically — so a customer who re-uploads a merged document does not lose the trail. It is off by default because it makes the file slightly larger.