Downloading
doc.download() returns the complete PDF as bytes — including any annotation or
metadata edits that have landed on the document.
download(opts?: { mode?: PdfSaveMode }): AbortablePromise<Uint8Array>;Downloading bytes#
const bytes = await doc.download();
// Browser: trigger a save dialog
const blob = new Blob([bytes], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'document.pdf';
a.click();
URL.revokeObjectURL(url);// Node: write to disk
import { writeFile } from 'node:fs/promises';
await writeFile('document.pdf', await doc.download());Save modes#
mode controls how the PDF is serialized:
| Mode | Behavior |
|---|---|
'incremental' (default) | Appends changes as an incremental update, preserving the original bytes and the document’s revision history. Faster; smaller diffs. |
'rewrite' | Rewrites the whole file from scratch. Produces a clean, compact PDF without the incremental-update trail. |
const compact = await doc.download({ mode: 'rewrite' });‘incremental’ is the default because it’s cheaper and keeps the
original file intact. Reach for ‘rewrite’ when you want the
smallest possible output or a file without prior revisions.
Cancellation and errors#
Like every engine call, download() is an AbortablePromise and rejects with a
typed EngineError:
const pending = doc.download({ mode: 'rewrite' });
// pending.abort() to cancel
try {
const bytes = await pending;
} catch (err) {
if (EngineError.is(err, EngineErrorCode.Forbidden)) {
// caller's scope doesn't permit download
}
}Downloading the original bytes is gated by the caller’s scope on the cloud. If
the token doesn’t grant it, download() rejects with
Forbidden — check doc.security.effectiveScope before
showing a download button.