Rather have us handle this?We set this up for clients every day.
See the Service

Guides/Pipedrive

Pipedrive Webhooks: Setup, Payloads, Testing and Troubleshooting

Configuring Pipedrive webhooks for deal, person and activity events: v2 payloads, retries, testing and troubleshooting.

Last verified: October 2026

How Pipedrive Webhooks Work

A Pipedrive webhook sends an HTTP POST to a URL you choose whenever a record changes: a deal moves stages, a person is created, an activity is deleted. Unlike HubSpot or Zoho, Pipedrive has a straightforward webhook system. You register a URL, pick an object and an action, and Pipedrive starts sending JSON.

Two things to know up front:

  • New webhooks are version 2.0. Since March 17, 2025, webhooks created through the API default to v2, and Pipedrive has said v1 will be fully deprecated in 2026. If you have older integrations built on v1 payloads, plan the migration now. (Pipedrive changelog)
  • Webhooks follow user permissions. A regular user’s webhook only covers what that user can see. Admins can create webhooks covering everyone in the company.

Step-by-Step Setup

Option A: In the Pipedrive UI

  1. Go to Settings > Tools and apps > Webhooks
  2. Click to create a new webhook
  3. Choose the event object (deal, person, organization, activity, etc.) and event action (create, change, delete, or all)
  4. Paste the endpoint URL we provide. It must be a public HTTPS address; self-signed certificates aren’t supported
  5. Optionally add an HTTP Basic auth username and password. Pipedrive sends them with every request, and we use them to reject anything that didn’t come from your account
  6. Save

Regular webhooks are available on every Pipedrive plan. Webhook actions inside Pipedrive Automations are a different feature and need the Advanced plan or higher.

Option B: Through the API

This is how we usually do it: faster, repeatable, and it lets us create exactly the subscriptions the integration needs.

curl -X POST "https://api.pipedrive.com/v1/webhooks?api_token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription_url": "https://hooks.example.com/pipedrive",
    "event_action": "change",
    "event_object": "deal",
    "name": "Deal changes to integration",
    "http_auth_user": "pipedrive",
    "http_auth_password": "a-long-random-secret"
  }'

version defaults to "2.0". A successful call returns 201. GET /v1/webhooks lists your webhooks and DELETE /v1/webhooks/{id} removes one. (API reference)

Events You Can Subscribe To

Every webhook is one object plus one action.

ActionFires when
createA record is added
changeAny field on a record changes
deleteA record is deleted
*Any of the above

Objects include deal, person, organization, activity, lead, note, product, pipeline, stage and user, plus newer ones such as deal products and deal installments. * subscribes to every object.

Integration needSubscribe to
New lead synccreate + person (or lead)
Deal stage trackingchange + deal
Activity loggingcreate + activity
Contact updateschange + person
Organization synccreate and change + organization

One edit triggers one change webhook in v2, so you no longer get the duplicate deliveries v1 sometimes produced.

What the Payload Looks Like (v2)

Here’s a trimmed example of a v2 change event for a deal. The meta block describes the event, data is the record’s current state, and previous holds only the fields that changed.

{
  "meta": {
    "action": "change",
    "entity": "deal",
    "entity_id": "4821",
    "id": "8c1f1b2e-…",
    "correlation_id": "f3a0c9d4-…",
    "company_id": "1234567",
    "user_id": "987654",
    "timestamp": "2026-10-01T15:04:22.000Z",
    "change_source": "app",
    "is_bulk_edit": false,
    "attempt": 1,
    "version": "2.0",
    "webhook_id": "512"
  },
  "data": {
    "id": 4821,
    "title": "Northside HVAC – service agreement",
    "value": 12000,
    "currency": "USD",
    "stage_id": 3,
    "status": "open",
    "person_id": 1192,
    "org_id": 377,
    "custom_fields": { "…": "…" }
  },
  "previous": {
    "stage_id": 2
  }
}

What that tells you without any extra API calls: deal 4821 moved from stage 2 to stage 3, someone made the change in the app (not a bulk edit), and this is the first delivery attempt.

Details that matter when you build on it:

  • previous is null on create and contains the last state on delete.
  • Custom fields arrive inside data.custom_fields, keyed by Pipedrive’s field keys rather than the labels you see in the app.
  • Merges arrive as two events: a delete (with merged_to_id) and a change (with merged_from_id).
  • meta.attempt counts from 1 to 4, so you can tell a retry from a first delivery.

Migrating from v1? current became data, object became entity, retry became attempt, timestamps changed from Unix seconds to ISO 8601, previous now only lists changed fields, and the added/updated/deleted actions are now create/change/delete. (Migration guide)

Ready to get your systems connected?No pitch. Just a conversation about what's possible.
Start a conversation

Delivery Rules: Timeouts, Retries and Bans

This is where most Pipedrive webhook problems come from, so it’s worth knowing exactly how delivery works. (Webhooks v2 guide)

  • 10-second timeout. Your endpoint has to answer with a 2xx within 10 seconds.
  • Three retries. If the first attempt fails or times out, Pipedrive retries after 3 seconds, 30 seconds and 150 seconds.
  • Temporary ban. Ten failed first attempts get the webhook banned for 30 minutes. Events that happen during a ban are not delivered.
  • Deletion. A webhook with no successful deliveries for 3 consecutive days is deleted.
  • Limit. Each user can have up to 40 webhooks.

The practical rule: acknowledge fast, process later. Your endpoint should check the credentials, store the payload, return 200, and do the real work (CRM updates, lookups, notifications) in the background. An endpoint that calls three other APIs before responding will eventually hit the 10-second limit.

# Minimal receiver: authenticate, queue, acknowledge. The work happens in a background worker.
@app.post("/pipedrive")
def pipedrive_webhook(request):
    if not basic_auth_ok(request, user="pipedrive", password=SECRET):
        return Response(status=401)
    queue.enqueue(process_pipedrive_event, request.json())  # retries, logging, dedup live in the worker
    return Response(status=200)

Testing Your Webhooks

  1. Point a temporary webhook at a request inspector (webhook.site or similar) before you build anything. Trigger the event and look at the real payload, especially your custom field keys.
  2. Trigger each event type you subscribed to. A change webhook won’t fire when you create a record, and vice versa.
  3. Test a bulk edit. Update several deals at once and confirm your endpoint handles the burst.
  4. Test a failure. Make your endpoint return a 500 once and watch for the retry (meta.attempt: 2).
  5. Use a sandbox for anything destructive. A Pipedrive developer sandbox lets you delete and merge test records safely.
  6. Switch to the production URL only after the payloads look right.

Troubleshooting

Webhook Not Firing

  • Check Settings > Tools and apps > Webhooks: is the webhook still there? It’s deleted after 3 days without a successful delivery.
  • Check the object and action match what you did. change + deal won’t fire for a new deal.
  • Check permissions: a regular user’s webhook doesn’t cover records that user can’t see.

Events Missing for 30 Minutes at a Time

That’s the ban. Ten failed first attempts trigger a 30-minute pause, and events in that window are not resent. Fix the endpoint’s errors or timeouts first, then backfill the gap through the API (for example, deals updated since the last event you received).

Payload Doesn’t Have the Field You Need

In v2, previous only lists changed fields, and custom fields use field keys. Look up the key once through the API’s field endpoints and map it in your integration instead of matching on labels.

Getting 401s or Unexpected Requests

If you set Basic auth, reject anything without the right credentials. Pipedrive doesn’t sign webhook requests, so Basic auth over HTTPS is the main protection. Use a long random password.

Integration Broke After Recreating a Webhook

A webhook created through the API after March 2025 is v2 unless you asked for v1. If your code expects current and event, that’s the cause. Update the parser to the v2 shape.

Next Steps

Rather Have Us Handle It?

We set this up for clients every day. Tell us what you're connecting and we'll take it from here.