pandadoc-exporter

Get all your data out of PandaDoc — documents, templates, and contacts — as PDF, DOCX, and JSON.

This repo is two things at once:

🤖 A Claude skill — just tell Claude "export my PandaDoc account" and it runs the whole thing for you. 🐍 A Python CLIpandadoc-export … if you'd rather run it yourself.

The skill simply drives the Python CLI under the hood, so both paths do exactly the same work. Pick whichever you prefer.


🤖 Use it as a Claude skill (easiest)

If you use Claude Code (or another client that supports skills), this is the simplest path — no commands to memorize.

Install the skill (either way):

You still need the Python tool installed (see below) and an Org-Admin API key in .env — the skill checks for these and walks you through it.

Then just ask Claude, in plain language. The skill knows these options:

Ask Claude… What it does
"Export everything from my PandaDoc" Full API export: all documents (PDF+JSON), templates (JSON), contacts
"…and also get templates as PDF and Word" Adds the headless-browser layer: each template as PDF + DOCX
"Just back up my documents" Documents only
"Export my PandaDoc templates as PDF and DOCX" Template PDF/DOCX only (opens a browser to log in once)
"List my PandaDoc workspaces" Discovery only — no downloads
"Skip voided/draft documents" Export but exclude chosen statuses
"Resume my PandaDoc export" Picks up where an interrupted run stopped

The skill handles the order of operations, the one-time browser login, resuming after interruptions, and verifying the output — so you don't have to think about the commands.


🐍 Use it as a Python CLI

git clone https://github.com/josevitorls/pandadoc.git
cd pandadoc
pip install -e .
playwright install chromium

cp .env.example .env          # then put your Org-Admin API key in it
pandadoc-export all           # full API export
pandadoc-export all --with-templates   # also export template PDF + DOCX

Python 3.10+ required.


What you get

Layer 1 — Official API (unattended, just needs the API key)

  • Lists every workspace in the organization and mints a per-workspace key automatically (your own admin workspace is detected and its key reused, never regenerated)
  • Documents → PDF + JSON, grouped by status, with the PandaDoc folder structure replicated
  • Templates → JSON
  • Contacts → JSON
  • Resilient (rate limits, retries, pagination), idempotent, and resumable

Layer 2 — Headless browser (Playwright)

  • Each template → PDF + DOCX (formats the API cannot produce)
  • Log in once in a browser window; the session is saved and reused headlessly
  • Auto-recovers across passes; if the session expires it stops cleanly and asks you to log in again

Configuration

Copy .env.example to .env and set your key:

Variable Required Description
PANDADOC_ADMIN_KEY Yes Org-Admin production API key (a regular workspace key cannot list workspaces or mint per-workspace keys)
OUTPUT_DIR No Where to write output (default: ./output)

CLI reference

Command What it does
pandadoc-export discover List all workspaces → state/workspaces.json
pandadoc-export keys Generate/reuse a production key per workspace → state/keys.json
pandadoc-export inventory Count docs/templates/contacts per workspace → state/inventory/<id>.json
pandadoc-export extract Download documents (PDF+JSON), templates (JSON), contacts (JSON)
pandadoc-export extract --exclude-status voided,draft …skipping chosen statuses
pandadoc-export login Open a browser to log in once (for the template layer)
pandadoc-export templates Export each template as PDF + DOCX (headless)
pandadoc-export all discover → keys → inventory → extract
pandadoc-export all --with-templates …and the template PDF/DOCX layer too

Output structure

Workspace folders are keyed by name + id (ids guarantee uniqueness across duplicate names):

output/
└── {workspace_name}__{workspace_id}/
    ├── _workspace.json
    ├── _manifest.json                 # expected vs. obtained counts
    ├── contacts/contacts.json
    ├── templates/
    │   ├── {template_name}__{id}.json
    │   ├── {template_name}__{id}.pdf    # browser layer
    │   └── {template_name}__{id}.docx   # browser layer
    └── documents/
        └── {status}/{replicated_folders}/
            ├── {doc_name}__{id}.json
            └── {doc_name}__{id}.pdf

The three template formats share the same {name}__{id} stem, so .docx, .json, and .pdf sort together.

Resumability

Every command is safe to re-run: it skips files already on disk and never regenerates an existing workspace key. If a run is interrupted, just run the same command again. Recoverable failures are logged to state/errors.jsonl.

Requirements

  • Python 3.10+
  • playwright (pip install -e . then playwright install chromium)
  • A PandaDoc Org-Admin production API key

License

MIT — see LICENSE.