Skip to content

Request an integration

Tell us which system you want to connect. We review every request weekly and publish a step-by-step guide or build the connection.

Pipedrive integration

Create TimeTracking clients and placements from won Pipedrive deals using Pipedrive webhooks and idempotent external-ID upserts.

Last updated: · Markdown version

1. Summary

Status: Recipe (no native connector).

Direction: Pipedrive to TimeTracking (clients, placements). Optional: approved totals back to a deal field.

2. Mechanism

  • Pipedrive side. Webhook updated.deal (v1) or change.deal (v2); filter on status changed to won. Read organization and person via /v1/organizations/{id}, /v1/persons/{id}. Custom fields are keyed by hash ids.
  • Glue. Receiver or iPaaS (Zapier, Make, n8n).
  • TimeTracking side. PUT /clients/by-external/pipedrive/{orgId}, PUT /people/by-external/pipedrive/{personId}, PUT /placements/by-external/pipedrive/{dealId}.
  • Totals back (optional). GET /days?from&to&placement_id=…&status=approved.

Assumption — verify with your Pipedrive admin: which custom fields hold start date, end date, worker and employee number.

3. Prerequisites

  • Pipedrive API token and admin rights for webhooks.
  • Custom deal fields: start date, end date, job title.
  • TimeTracking API key (write).

4. Entity mapping

Pipedrive object.field TimeTracking field Notes
Organization id client external ref
Organization name client name
Person (worker) id person external ref Only if workers are Pipedrive persons.
first_name, last_name, email[0].value, phone[0].value person fields
Person custom "Employee number" employeeNumber
Deal id placement external ref; ref PD-<id>
Deal custom start / end startsOn / endsOn
Deal title / custom job title roleTitle
Deal lost/closed after start DELETE /placements/{id} (deactivate)

External-ID strategy. source = pipedrive. No ids need to be written back to Pipedrive: the deal id is the key. Upserts are full replaces.

5. Step-by-step setup

  1. Add the Pipedrive webhook (updated.deal) to your receiver; protect it with HTTP basic auth.
  2. Ignore events unless current.status == "won" and previous.status != "won" (or the date fields changed on a won deal).
  3. Upsert:
curl -s -X PUT "$TT/clients/by-external/pipedrive/311" -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"name":"Logistiek Parkstad","externalRef":"311"}'
curl -s -X PUT "$TT/people/by-external/pipedrive/9001" -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"employeeNumber":"1002","firstName":"Fatima","lastName":"El Amrani","email":"fatima@example.com"}'
curl -s -X PUT "$TT/placements/by-external/pipedrive/4410" -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -H "Idempotency-Key: pd-deal-4410-won" \
  -d '{"personExternalRef":"9001","clientExternalRef":"311","ref":"PD-4410","roleTitle":"Orderpicker","startsOn":"2026-11-02","endsOn":"2027-01-29"}'

6. Sync schedule and triggering events

Trigger Action
updated.deal to won Upsert client, person, placement.
Date fields changed on a won deal Upsert placement again (full replace).
timesheet.approved (optional) GET /days?placement_id=…&status=approved&from&to, write the sum to a deal field.

7. Corrections, conflicts and locked periods

TimeTracking owns hours, conflicts and locks. Recompute totals from GET /days (never increment). Ending a placement before existing hours returns 409.

8. Testing checklist

  • Winning a test deal returns created: true; re-saving returns created: false.
  • Changing the end date updates endsOn.
  • Losing or reopening a deal creates nothing.

9. Troubleshooting

Error Fix
422 "Person and client must exist …" Upsert person and client first (same source).
422 on dates Empty custom date field; skip or default.
409 Placement shortened before existing hours.
429 Wait Retry-After.

10. Limits and known gaps

No client-contact API. Native Pipedrive marketplace app (OAuth2): Planned.

11. Build it with Claude

Build a Make (or n8n) scenario: Pipedrive webhook updated.deal → filter status changed to won → get organization
and person → TimeTracking PUT /clients/by-external/pipedrive/{orgId} {name} →
PUT /people/by-external/pipedrive/{personId} {firstName, lastName, email, employeeNumber} →
PUT /placements/by-external/pipedrive/{dealId} {personExternalRef, clientExternalRef, ref "PD-<id>", roleTitle,
startsOn, endsOn}. Base https://app.timetracking.tech/api/v1, Bearer key, responses { data } / { error }.
Ask me for my custom field hashes. Error route for 409/422/429.