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_mode | What pd sends |
|---|---|
token | x-api-token: <pipedrive_api_token> from that row |
oauth | Authorization: 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 astokenmode.
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.