Python API Reference

This reference documents the dynamic Python API exposed by pdftl. All operations return an pdftl.core.types.OpResult object.

Note

These functions are generated dynamically at runtime via pdftl.api.

pdftl.api.add_bookmarks(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Add one or more top-level bookmarks to a PDF outline.

pdftl.api.add_text(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Applies all parsed add_text rules to a PDF in-place.

This function coordinates the parser and the TextDrawer to apply text overlays to the input PDF.

pdftl.api.attach_files(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Attach files to a PDF document, according to the specified options

pdftl.api.background(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply overlay or underlay with optional OCG layering and page-range filtering.

pdftl.api.booklet(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Imposes pages into a booklet sequence.

pdftl.api.burst(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Split one or more PDFs into multiple files, single-page files by default.

Args:

opened_pdfs (list): A list of opened PDF files to burst

operation_args (list): User-supplied arguments

output_pattern (str): A C-style format string for the output

filenames, e.g., “page_%03d.pdf”.

Return: the first input pdf (for pipeline chainability)

Note: Uses the hook side-effect to actually burst

Bugs:

  • Discards various parts of the PDF file that may still be relevant to single-page files, e.g., internal links

pdftl.api.cat(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Concatenates pages from input PDFs into a new PDF, then rebuilds all links and named destinations, including transforming link target coordinates.

pdftl.api.chop(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Chops specified pages of a PDF into multiple smaller pages.

BUG FIXME: currently does strange things with page rotation (pages out of order?)

pdftl.api.clip(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Crop or clip pages in a PDF using specs like ‘1-3(10pt,5%)’.

pdftl.api.crop(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Crop or clip pages in a PDF using specs like ‘1-3(10pt,5%)’.

pdftl.api.delete(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Deletes pages from input PDF, and otherwise leaves the PDF structure essentially unchanged.

pdftl.api.delete_annots(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Delete annotations from a PDF, optionally filtered by selector specs. Without selectors, deletes all annotations from all pages.

pdftl.api.delete_attachments(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Deletes attachments matching criteria from the document NameTree and scrubs corresponding page annotations.

pdftl.api.delete_blank(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Delete pages that are blank or visually uniform.

Each spec is evaluated independently. A page is deleted if any spec marks it as blank. Deletion happens in reverse page order so indices remain valid throughout.

pdftl.api.delete_bookmarks(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Delete bookmarks from a PDF outline, optionally filtered by page spec.

pdftl.api.delete_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Overwrites images matching criteria with 1x1 transparent stubs. Defaults to global search if no page range is provided.

pdftl.api.dump_annots(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dumps all annotations from a PDF in JSON format, with compact arrays. Optionally filtered by selector specs using the same syntax as modify_annots.

pdftl.api.dump_bookmarks(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extracts the document’s Table of Contents (bookmarks) into a highly readable and editable YAML format (or JSON).

This faithful extraction preserves both the hierarchical structure and the complex properties of your bookmarks. The resulting file can be easily edited in any text editor and applied back to the same (or a different) PDF using the update_bookmarks operation.

### Supported Bookmark Properties Each bookmark node is represented as a dictionary (key-value mapping). The extractor natively supports and outputs the following properties:

  • `title`: The display text of the bookmark.

  • `page`: The 1-indexed target page number.

  • `children`: A nested list of sub-bookmarks to maintain outline hierarchy.

  • `color`: An RGB array for the bookmark text color (e.g., [1.0, 0.0, 0.0] for red).

  • `bold` / `italic`: Boolean flags for text styling (true or false).

  • `uri`: An external web link (used if the bookmark points to a URL rather than a page).

  • `dest`: A string reference to a Named Destination embedded inside the PDF.

  • `view`: The precise zoom/viewport array (e.g., [“XYZ”, 0, 700, 2.5], [“FitH”, 500]).

### Format Example ```yaml - title: Chapter 1

page: 1 bold: true children:

  • title: Sub-section A page: 2 view: [“FitH”, 800]

  • title: Important Chart page: 3 color: [1.0, 0.0, 0.0]

```

### Dependency note

YAML extraction requires the pyyaml library. If it is not installed, you can install it via pip install pdftl[yaml-bookmarks], or simply use the json flag to extract using Python’s standard JSON library instead.

pdftl.api.dump_colorspaces(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Report color spaces used throughout a PDF document.

pdftl.api.dump_data(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Imitate pdftk’s dump_data output, writing to a file or stdout.

pdftl.api.dump_data_annots(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dumps annotation data from a PDF in pdftk style

pdftl.api.dump_data_fields(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extracts form field data from the PDF using a Hybrid Tree Walk.

pdftl.api.dump_data_fields_utf8(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extracts form field data from the PDF using a Hybrid Tree Walk.

pdftl.api.dump_data_utf8(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Imitate pdftk’s dump_data output, writing to a file or stdout.

pdftl.api.dump_dests(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Traverses the /Dests name tree of a PDF using pikepdf.NameTree. This provides a robust, iterable interface to the destinations.

pdftl.api.dump_encryption(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dumps comprehensive encryption and permission data from a PDF.

pdftl.api.dump_files(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

List files attached to the PDF. Returns a list of dicts: {‘name’: str, ‘size’: int, ‘location’: str}.

pdftl.api.dump_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dump embedded image metadata of a PDF file.

pdftl.api.dump_layers(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extract OCG (Layer) data and write as JSON.

pdftl.api.dump_signatures(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Validate PDF signatures and returns a list of validation results.

pdftl.api.dump_text(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dump text content of a PDF file.

pdftl.api.fill_form(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Fill in a form, treating the first argument as a filename (or similar) for data

pdftl.api.filter(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Return the given PDF.

pdftl.api.generate_fdf(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Output FDF data for the given PDF

pdftl.api.highlight(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Applies all parsed highlight rules to a PDF in-place.

pdftl.api.inject(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Injects code at the start and/or end of page content streams.

pdftl.api.insert(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Insert blank pages into the PDF.

pdftl.api.modify_annots(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Modifies properties of existing annotations in a PDF.

pdftl.api.modify_layers(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The modify_layers operation allows you to alter Optional Content Groups (layers) in a PDF. You can permanently merge/strip them, or change their default visibility and behavior.

The command reads a sequence of action-target pairs. If no target is provided after an action, it defaults to affecting “all” layers.

### Available Actions

Structural (Permanent): * merge: The visual content of the layer is permanently baked into the

page. The layer is removed from the PDF’s layer menu.

  • strip: The visual content of the layer is completely deleted from the document, and the layer is removed from the PDF’s layer menu.

State & Behavior (Non-destructive): * show / hide: Sets the default visibility when the document is opened. * lock / unlock: Prevents/allows the user from toggling the layer in viewers. * print / noprint: Overrides behavior to force layer visibility ON or OFF when printing. * screen / noscreen:

Overrides behavior to force layer visibility ON or OFF on digital displays.

Utility: * keep: Used primarily to exclude a specific layer when targeting “all” others.

Note on State vs. Usage: Layer visibility on screen (`show`/`hide`) is independent of its visibility when printing. Modifying a usage state (like `noprint`) without changing its base state will leave its on-screen visibility unchanged.

### Target Specifications

  • name=<string>: Sloppy match. Applies the action to all layers with this name.

  • id=<integer>: Strict match. Applies the action to the exact underlying PDF object.

  • all: Explicitly targets all layers.

  • <string>: If no key= prefix is provided, it defaults to a name= match.

pdftl.api.montage(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Imposes pages onto new canvas pages based on a grid or layout strategy.

pdftl.api.move(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

CLI Adapter for move: Parses string arguments into a spec, then runs logic.

pdftl.api.multibackground(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply overlay or underlay with optional OCG layering and page-range filtering.

pdftl.api.multistamp(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply overlay or underlay with optional OCG layering and page-range filtering.

pdftl.api.mutate_content(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The mutate_content operation allows you to run custom Python logic against the raw instruction streams of a PDF. You can specify your own Python script, and the function from that script to run. The default function search for if no function is specified is mutate.

### The Context Dictionary Your function receives a context dictionary with the following keys:

  • pdf: The current pikepdf.Pdf object.

  • page_num: The current page number (1-indexed) or None for XObjects.

  • is_xobject: Boolean, True if mutating a Form XObject.

  • object: the pikepdf.Object (either a page or an XObject) containing the content stream.

  • args: A list of extra arguments passed via CLI after the script name.

### Passing Arguments You can pass custom parameters to your script: pdftl in.pdf mutate_content script.py 1.5 2.0 output out.pdf In this case, context[‘args’] would be [‘1.5’, ‘2.0’].

pdftl.api.normalize(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Normalize page content streams.

pdftl.api.optimize_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Optimize images in the given PDF.

pdftl.api.place(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Applies geometric transformations (direct similarities) to the content of selected pages.

`<spec>` syntax:

[<pages>](<operation>…)

Operations:
  • shift=dx, dy Moves content by the specified x and y distances. Supports units (pt, in, cm, mm) and percentages relative to page size. Example: shift=1in, 50%

  • scale=factor[:anchor] Scales content by a multiplier (e.g., 0.5 for half size). Optional anchor determines the fixed point (default: center).

  • spin=angle[:anchor] Rotates content by degrees clockwise. Optional anchor determines the pivot point (default: center).

More than one operation can be given. They should be separated by semicolons, ‘;’. Operations are applied in the order they appear, from left to right.

Anchors:

Anchors define the center of scaling or rotation. * Named: center (default), top-left, top, top-right,

left, right, bottom-left, bottom, bottom-right.

  • Coordinate: x,y (e.g., 0,0 for bottom-left corner).

pdftl.api.render(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The render operation converts PDF pages into raster images or a single PDF. It respects page rotation, cropping, and current pipeline modifications.

You can specify a page range using standard page specifications (e.g., 1-5, even). If no pages are specified, all pages are rendered.

The dpi=<val> argument sets the raster image resolution, in dots per inch (default: 150). It must be a positive number.

The default <template> is page_%d.png. The parameter %d is replaced with the output page counter value, starting at 1. Standard formatting directives like %03d are supported.

Single PDF Output: If the output template ends with .pdf and contains no % directive (e.g., output out.pdf), all rendered pages will be combined into a single PDF file. Note: This keeps all page images in memory until saved.

Image Output: If rendering to images, the output format is guessed from the <template> extension (e.g., .png, .jpg). If no extension is given, PNG is used.

pdftl.api.replace(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Replace in page content streams.

pdftl.api.rotate(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Applies rotations and/or scaling to specified pages of a PDF.

pdftl.api.set(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Orchestrates setting various document-level metadata and preferences.

pdftl.api.shuffle(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Shuffles (interleaves) pages from multiple PDFs, applying transformations like rotation and scaling.

pdftl.api.stamp(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply overlay or underlay with optional OCG layering and page-range filtering.

pdftl.api.unpack_files(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Unpacks attachments from a single PDF file. Returns a generator yielding (filename, bytes).

pdftl.api.unpause(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The unpause operation removes intermediate animation frames from PDF slide decks, such as those produced by LaTeX Beamer with pause or uncover directives.

The algorithm renders each page at low resolution and checks whether all ink pixels from the previous page are still present on the current page. If they are, the previous page is considered an intermediate animation frame and is discarded. Only pages where ink disappears or moves are kept, plus the final page.

The dpi=<val> argument controls render resolution for comparison (default: 72). Higher values are slower but more accurate for fine detail.

The ink=<val> argument is the pixel darkness threshold (0-255) below which a pixel is considered ink (default: auto). In auto mode, Otsu’s method is used per page.

The survival=<val> argument is the minimum fraction (0.0-1.0) of ink pixels from the previous page that must survive on the current page for it to be considered a continuation (default: 0.98). Genuine Beamer transitions produce survival=1.00; new slides typically produce <0.20.

pdftl.api.update_bookmarks(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Replaces the document’s Table of Contents (bookmarks) entirely using a specified YAML or JSON file, or YAML data on stdin if bookmarks_file is set to “-“.

This operation consumes the structured format generated by the dump_bookmarks command. It applies strict validation to prevent broken PDFs: it validates page boundaries, catches typos in property names, and ensures the hierarchical tree structure is sound.

### Important Rules & Behaviors * Full Replacement: This command does not merge or append bookmarks. It completely

overwrites the existing Table of Contents with the contents of your file.

  • Page Indexing: Target page numbers must be 1-indexed (e.g., page: 1 points to the very first physical page of the document).

  • Boundary Checking: If a bookmark points to a page number that exceeds the total number of pages in the PDF, the operation will fail safely to prevent document corruption.

  • Strict Validation: Unrecognized properties (such as a typoed pagee instead of page) will trigger an error rather than being silently ignored. This ensures your routing logic always behaves as expected.

### Clearing Bookmarks If you want to completely remove the Table of Contents from a PDF, you can provide a file containing just an empty list. * YAML file content: [] * JSON file content: []

### Dependency note Loading YAML files requires the pyyaml library. If it is not installed, you can install it via pip install pdftl[yaml-bookmarks], or simply use .json files natively.

pdftl.api.update_info(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

CLI Adapter for update_info: parses string arguments into a spec, then runs logic.

Expects op_args to have valid operation arguments (see pdftl help update_info).

xml_strings controls whether to XML-decode string fields in the input.

pdftl.api.update_info_utf8(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

CLI Adapter for update_info: parses string arguments into a spec, then runs logic.

Expects op_args to have valid operation arguments (see pdftl help update_info).

xml_strings controls whether to XML-decode string fields in the input.

pdftl.api.zoom(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The zoom operation rescales entire pages (including the MediaBox) to fit a specified target dimension. Unlike place, which only moves content within existing boundaries, zoom physically transforms the page size.

This is an in-place operation: unspecified pages are left unchanged.

Syntax:

zoom “<pages>(<target>[,<options>])”

Target Formats:
  • Relative/Percentage: (50%) or (200%). Resizes the page relative to its current dimensions.

  • Single Value/Paper: (A4) or (100mm). Scales the page uniformly so that it fits inside a bounding box of that size (aspect ratio preserved).

  • Explicit Box: (100mm,200mm). Scales the page uniformly to fit inside the specified width and height.

  • Axis Specific: (width=A4) or (height=11in). Scales the page proportionally based only on the specified dimension.

Options:
  • shrink: Only scale pages down. If the page is already smaller than the target, it remains unchanged.

  • grow: Only scale pages up. If the page is already larger than the target, it remains unchanged.

Note: Scaling is always uniform. If a target rectangle is provided, the operation uses the limiting dimension to ensure the entire page fits inside the “envelope”.