Cookbook
Each recipe is one command or pipeline. They assume you're authenticated (or have
PDCLI_COMPANY_DOMAIN + PDCLI_API_TOKEN set). Piped commands emit JSON automatically, so
--jq and jq work without --output json.
Stale open deals to CSV
Section titled “Stale open deals to CSV”pdcli audit --checks stale-deals --output json \ | jq -r '.[0].items[] | [.id, .title, .days] | @csv' > stale-deals.csvWrites one row per open deal untouched for more than 14 days, with the age in days.
Bulk stage-move via a saved filter
Section titled “Bulk stage-move via a saved filter”pdcli deal bulk-update --filter 9 --stage 5 --dry-run # preview targets firstpdcli deal bulk-update --filter 9 --stage 5 # confirms, then moves--dry-run lists every deal the saved filter selects without writing. Drop it (or add
--yes) to apply. Partial failures are reported per deal and exit 1.
Weekly pipeline-health JSON for a dashboard
Section titled “Weekly pipeline-health JSON for a dashboard”pdcli pipeline health --pipeline 1 --output json > health-$(date +%F).jsonPer-stage open count, total value, probability-weighted value, stale-deal count, and
deals with no next step. Pass --pipeline when the account has more than one pipeline.
Find a person by email
Section titled “Find a person by email”pdcli search "jane@acme.com" --item-types person --output json \ | jq '.[] | {id, name}'Add --exact for an exact match.
Scoped vs. multi-type search routing
Section titled “Scoped vs. multi-type search routing”search routes by how many item types you ask for:
- A single routable type —
--item-types deal,person,organization, orproduct— hits that entity's dedicated v2 search endpoint (e.g./api/v2/persons/search), which needs only that entity's OAuth scope and accepts entity-specific server-side filters. Its--limitis capped at 100 (the endpoint rejects more). - Anything else — no
--item-types, multiple types, or a non-routable type likelead,file, orproject— stays on the genericitemSearch. Both search endpoints cost the same 20 rate-limit tokens.
When the scope is a single deal search, three filters narrow it server-side: --status
(open/won/lost), --person (a person ID), and --org (an organization ID). These are
rejected (exit 64) with any other scope, since only /api/v2/deals/search accepts them:
pdcli search "renewal" --item-types deal --status open --org 7 --output jsonCreate a deal with custom fields in one line
Section titled “Create a deal with custom fields in one line”pdcli deal create --title "Acme renewal" --value 5000 --currency EUR \ --stage 3 --field "Deal Size=Large" --field "Score=4.5"Custom fields are given by human name; pdcli resolves the 40-char hash key and maps
option labels (like Large) to their IDs. See Custom fields.
Nightly cron backup
Section titled “Nightly cron backup”# crontab -e0 2 * * * PDCLI_COMPANY_DOMAIN=acme PDCLI_API_TOKEN=xxxx \ /usr/local/bin/pdcli backup --dir /backups/pipedrive --resumeFull-account export to a JSON tree. --resume skips resources finished in a prior run, so a
re-run after an interruption continues instead of restarting.
Duplicate-persons report
Section titled “Duplicate-persons report”pdcli audit --checks duplicate-persons --verboseLists every email shared by more than one person, with the person IDs, so you can merge
them. Output (table mode, --verbose):
Sev Check Findings● Persons sharing the same email 3
Persons sharing the same email {"email":"jane@acme.com","ids":[12,87]} …Export persons for a mail merge
Section titled “Export persons for a mail merge”pdcli person list --output csv --fields id,name,email > contacts.csv--fields selects columns; --output csv produces a header row plus one row per contact.
Scope it with --org <id> or --owner <id>.
Log an activity after a call
Section titled “Log an activity after a call”pdcli activity create --subject "Discovery call" --type call \ --due-date 2026-06-04 --done --deal 42 --note "Budget confirmed, sending quote"--done marks it complete on creation; --deal links it. On v2 activity writes --person
maps to a primary participant.
Won-deal report for the quarter
Section titled “Won-deal report for the quarter”pdcli deal list --status won --output json \ | jq '[.[] | select(.won_time >= "2026-04-01")] | {count: length, total: (map(.value) | add)}'Counts deals won since the quarter start and sums their value. For the full sales-velocity
breakdown over a trailing window, use pdcli metrics velocity --period 90d.