Skip to main content

Pipedrive API access (developer / agent lookups)

Audience: developers & AI agents · Scope: how to query a Beta-Calco Pipedrive account directly for debugging, testing, and field/deal lookups — outside the app's sync flows · Last reviewed: 2026-08-06

TL;DR: Use the tools/pd helper. It curls the Pipedrive REST API with the same credential the chosen environment uses — API token or app access token, read at call-time from the local ConfigBox DB and sent as a header, never pasted, persisted or put in a URL. It is read-only (GET only). PD_ENV=dev points it at whatever the dev row is wired to; the default is live.

Why this exists

When debugging the quotes ↔ Pipedrive sync you constantly need to see the live side: what a deal actually looks like, which custom-field key maps to which field, whether a serial matched a deal. The PHP integration can do all this, but for ad-hoc questions a direct REST call is faster. tools/pd gives that without ever handling the token by hand.

Which credential it uses

tools/pd resolves the credential the way the app does, for whichever environment row you point it at (PD_ENV, default live):

That row's pipedrive_auth_modeWhat pd sends
tokenx-api-token: <pipedrive_api_token> from that row
oauthAuthorization: Bearer …, via cli/cb_pipedrive_print_access_token.php, which refreshes if needed
$PIPEDRIVE_API_TOKEN, if set, always wins
tools/pd me # the live row's account
PD_ENV=dev tools/pd me # whatever dev is wired to — the sandbox, if it has been repointed

The environment override is what makes the sandbox usable for ad-hoc lookups, and it is the quickest way to answer "which account is this environment actually talking to?".

The credential is a header now, not ?api_token=. It used to go in the querystring, which put it in shell history and in any proxy or server log along the way.

The mode lookup deliberately tolerates a database that has not run migration 0.5.93 — the tool keeps working against an older dump or another checkout, treating it as token mode.

The production token belongs to the ConfigBox API User (pipe@betacalco.com), an admin user on company domain betacalco2. The daily budget is per company and shared with every other token and app on it (~720k token-cost/day on production); normal lookups won't come close, but a sandbox on a smaller plan is a different matter.

⚠️ Reads only — by design

tools/pd issues GET requests only; it has no write path. This is deliberate: a direct API write bypasses BOTH of the app's guards — the DEV-org rule in BcPipedriveApi::assertOrgWriteAllowed() and, more importantly, the cross-account check in BcPipedriveAuth::assertCompanyAllowed(). Neither lives in Pipedrive, so neither protects a raw curl. There is no undo. To exercise a write flow, use the app's capture mode (PIPEDRIVE_TEST=capture, see testing.md), which records the payload and sends nothing. If a real production change is ever genuinely needed, make it deliberately through the app or the Pipedrive UI — not through this helper.

Usage

tools/pd me # who the token is (sanity check the account)
tools/pd fields # deal custom-field key <-> name/id/options map ← most useful
tools/pd deal 12345 # full detail of one deal
tools/pd serial BC-12345 # find deal(s) carrying that quote serial (exact custom-field search)
tools/pd get /deals limit=5 # arbitrary GET; params as querystring …
tools/pd get /deals '{"limit":5}'# … or as a JSON object
tools/pd get /organizations/6034 # e.g. the DEV org used by the app's write guard

PD_ENV=dev tools/pd fields # the SANDBOX's field keys — different from live's, by design

Output is pretty-printed JSON (PD_RAW=1 for raw bytes). tools/pd fields answers "which field key is X?" for the account you are pointed at — and since field keys are per account, the answer differs between live and the sandbox. For the configured mapping, prefer the local field registry: cb_pipedrive_import_fields.php imports every field and prints which configured setting no longer resolves, which is the question you usually actually have.

Postman (alternative)

Not needed for agent lookups (tools/pd is more direct), but if you want Postman: create an environment variable api_token, set the base URL to https://api.pipedrive.com/v1, and send it as an x-api-token header. Same token as above. Keep it read-only for the same reason.