Guides

Pipedrive webhooks v2: events, retries and how merges show up

By Tomi · Last updated

Pipedrive webhooks v2 are the default format since March 17, 2025: every event has three keys, meta, data and previous, and the action is create, change or delete. If your endpoint doesn't answer 2xx within 10 seconds, Pipedrive retries 3 times, after 3, 30 and 150 seconds, then drops the event. There is no merged event in v2: a merge arrives as a delete of the absorbed record with meta.merged_to_id, plus a change of the kept record with meta.merged_from_id. In our tests, that change only came when the kept record actually changed, and every event of one merge shared a correlation_id (the moved notes, activities and deals with -0 added).

Tested in a Pipedrive sandbox, October 2026: 40 webhook deliveries, 7 merges (5 people through the API, 1 person by hand, 1 lead). Last checked: November 2, 2026. What we couldn't verify.

Webhooks v2 at a glance

Question Answer Source
Payload meta, data, previous Webhooks v2 guide, updated July 28, 2026
Actions create, change, delete, or * List of webhooks v2
Timeout 10 seconds Webhooks v2 guide
Retries 3, after 3, 30 and 150 seconds (meta.attempt 1 to 4) Webhooks v2 guide. We measured the first retry about 3.3 seconds later
Limit 40 webhooks per user. No documented limit per company Webhooks v2 guide
Authentication Optional basic auth. No signature Webhooks v2 guide
Counts against API rate limit No Webhooks v2 guide
Merge delete with merged_to_id + change with merged_from_id Migration guide, updated May 22, 2026

How to create a webhook v2

In the app: go to Tools and apps > Webhooks and add one (Pipedrive help, updated September 3, 2026). Webhooks created there are v2: v1 can only be created through the API (v1 guide).

Through the API: POST /v1/webhooks with subscription_url, event_action, event_object and, optionally, user_id, http_auth_user and http_auth_password. version defaults to 2.0 (API reference). There is no /v2/webhooks endpoint. Creating or listing a webhook costs 10 API tokens and deleting one costs 6, per the same reference.

Who can create one (webhooks v2 guide and API reference):

  • Regular users can create webhooks only within their own permissions.
  • Admins can create them for any user in the company.
  • user_id decides whose permissions filter the events. If that user can't see a record, no event is sent for it. To get everything, use an admin.

Each user can have up to 40 webhooks. Use * as action or object to subscribe to more with fewer webhooks; * in both sends everything.

Objects you can subscribe to in v2 include activity, deal, deal_product, lead, note, organization, person, pipeline, product, project, stage, task and user, plus field definitions such as person_field and deal_field (list). The API reference still lists only 10 objects. We created deal_product without problems; dealProduct and file returned 400.

The URL has to be public and complete, with no self-signed certificate (v1 guide), and it must not redirect (API reference). In 2025 a developer saw deliveries fail because his Google Apps Script answered with a 302.

What a v2 payload looks like

  • meta: who, what and when. action, entity, entity_id, id (unique per event), attempt, change_source, is_bulk_edit, correlation_id, timestamp, user_id, webhook_id, version and, on merges, merged_to_id or merged_from_id.
  • data: the record as it is now. null on delete.
  • previous: null on create. On change, only the fields that changed. On delete, the last state of the record.

Custom fields come in data.custom_fields, typed, and option fields come only as option IDs (migration guide).

This is the delete a person merge sent us, trimmed, with test IDs and names:

{
  "meta": {
    "action": "delete",
    "entity": "person",
    "entity_id": "1002",
    "merged_to_id": "1001",
    "id": "5b0e7c1a-0d3f-4a52-9c1e-2f6a0b7d4e01",
    "correlation_id": "c41f2e8b-7a90-4d16-b3c5-81e0d9a6f702",
    "attempt": 1,
    "change_source": "api",
    "is_bulk_edit": false,
    "timestamp": "2026-10-14T15:00:00.000Z",
    "type": "general",
    "version": "2.0"
  },
  "data": null,
  "previous": {
    "id": 1002,
    "name": "Test Person",
    "first_name": "Test",
    "last_name": "Person",
    "phones": [{ "label": "work", "value": "555-0100", "primary": true }],
    "owner_id": 11,
    "org_id": null,
    "visible_to": "3",
    "custom_fields": {}
  }
}

Note the types: meta.entity_id and meta.merged_to_id arrived as strings, while previous.id was a number for people (a lead's ID is a string UUID).

Retries, bans and deletion

Pipedrive's policy, from the webhooks v2 guide (updated July 28, 2026):

What happens Rule
A delivery fails Any response that isn't 2xx, or no response within 10 seconds
Retries 3 more attempts, after 3, 30 and 150 seconds. meta.attempt goes from 1 to 4
All 4 attempts fail The event is lost
First attempts keep failing Each failed first attempt adds 1 to a counter. Failed retries don't count
The counter reaches 10 The webhook is banned for 30 minutes. Events in that window are lost, not queued
After the ban The webhook works again and the counter goes back to 0
No successful delivery for 3 consecutive days The webhook is deleted

The policy doesn't say the 10 failures have to be in a row, or that a success resets the counter.

So you lose events in three ways: an event whose 4 attempts fail (about 3 minutes), every event during a 30-minute ban, and everything after the webhook is deleted. Pipedrive gives you no failure log and no way to request a redelivery through the API. A developer asked in 2018 and the answer was to contact support; we found nothing newer.

Deliveries don't spend your daily API budget. Creating, listing and deleting webhooks does (how the budget works).

Deduplicate by meta.id

Pipedrive's migration guide says "You don't have to implement deduplication in webhooks v2" (source). Read in context, it's about one edit sending one change event. It doesn't mean you never get the same event twice.

We tested it. Our endpoint answered one event with a 500. About 3.3 seconds later the same event came back, with the same meta.id and meta.attempt = 2. That's a second delivery of the same event, and your handler sees it twice.

The same happens if your handler does the work but takes more than 10 seconds to answer. Pipedrive counts it as a failure and retries. That was the cause in a 2024 thread about the same webhook arriving 2 or 3 times.

What to do:

  1. Store meta.id with a unique constraint. Skip any event whose id you've already seen.
  2. Save the event, answer 2xx right away and do the work later, outside the request.
  3. Log meta.attempt. Anything above 1 means your endpoint failed or was slow.

How a merge shows up in webhooks v2

v1 had a merged action. In v2 it's gone: the migration guide says the v1 merged action "is unavailable in v2". What Pipedrive documents is the pair of events: delete with merged_to_id and change with merged_from_id.

Here is everything one person merge sent us when the absorbed person had a note and an activity:

Event Key fields change_source is_bulk_edit correlation_id
person delete (the absorbed one) meta.merged_to_id = the kept person. previous = the full record, 14 fields api false X
person change (the kept one) meta.merged_from_id = the absorbed person. previous = only what changed api false X
activity change previous.person_id = the absorbed person app true X with -0 added
note change previous.person_id = the absorbed person app true X with -0 added

What we measured that Pipedrive's docs don't say:

The delete carries the whole record. previous had all 14 fields of the person, custom fields included. For a merged lead it had 20. That's enough to rebuild the absorbed record, which matters because the merged lead itself was gone right away (404), and an absorbed person is deleted for good after 30 days (what you can't undo).

No change for the kept record if nothing on it changed. In a merge made by hand in the Pipedrive app, we got the person delete with merged_to_id and a deal change with previous.person_id = the absorbed person, but no event with merged_from_id. The same happened in one of our API merges. If you wait for both events to confirm a merge, you'll miss some. Treat delete with merged_to_id as the merge.

Moved records share the merge's correlation_id with -0 at the end. Notes, activities and deals reassigned by the merge arrived as change events with previous.person_id pointing at the absorbed person. Pipedrive documents correlation_id only as being "for internal troubleshooting", so it could change, but it's the only link we found between a merge and its side effects.

change_source doesn't tell you who merged. The main events said api for our API merges and app for the one made by hand. But in an API merge, the moved note and activity said app with is_bulk_edit = true. A lead merge through PUT /v1/leads/{id}/merge sent its delete marked app. And in 2021 a developer reported the opposite, a merge made by hand marked api, with no answer from Pipedrive. To tell your own changes from others, use correlation_id.

Your own API response gives you the correlation_id. The x-correlation-id header in the response to our merge call matched meta.correlation_id in the webhooks it caused. Store it when you write, and you can recognize the echo of your own change exactly.

Lead merges send the same delete (how to merge leads).

What webhooks won't tell you

  • Events lost to failures or bans. Nothing tells you they happened.
  • Delivery order. Pipedrive doesn't document it. In our merges the delete arrived first, but the note and the activity of one merge arrived in the opposite order of their meta.timestamp. Sort by meta.timestamp when order matters.
  • Which records a missed merge touched. If you lose a merge delete, a later read shows a record that's inactive or gone, with nothing saying it was merged or into what. A developer asked for a list of merged people in 2021. The only reply pointed to the change history endpoints, and no one confirmed it solved merges.

Cover the gaps with a periodic reconciliation: re-read the records you care about through the API and compare them with what you stored from webhooks. It's cheap. In our sandbox, a v2 list of 500 records cost 10 API tokens, so 10,000 people cost about 200. Run it daily, and after any outage of your endpoint.

Webhooks v1 vs v2

Milestone Date and source
v2 launched in beta, API only February 22, 2023 (changelog)
v2 default when created by API March 17, 2025, announced December 17, 2024 (changelog)
v1 today Only through the API, as a legacy fallback (v1 guide, updated May 21, 2026)
v1 shutdown The changelog says v1 will be deprecated completely in 2026, with no day. We found no shutdown notice

Don't confuse webhooks v1 with API v1. Pipedrive moved many API v1 endpoints out of support on August 1, 2026 (changelog). That's about endpoints, not the webhook payload format.

What changed in the payload (migration guide):

v1 v2
current data
retry (0 to 3) meta.attempt (1 to 4)
meta.object meta.entity
added, updated, merged, deleted create, change (including merges), delete
is_bulk_update is_bulk_edit
permitted_user_ids as numbers array of strings
previous with the full record previous with only the changed fields on change

To move an existing v1 webhook, create a v2 one for the same events, deduplicate while both run, then delete the v1 one.

Webhooks, OAuth and scopes

  • Your app managing a user's webhooks: the webhooks:read and webhooks:full OAuth scopes, effective January 26, 2024, let an app list, create and delete webhooks on a user's behalf (changelog).
  • App-specific webhooks: only for Marketplace apps, with the admin scope and type = application. They don't show in the Pipedrive UI, count 40 per app user and are deleted when the app is uninstalled (webhooks for apps). The page doesn't mention webhooks:full.

Common mistakes

  • Skipping deduplication because the migration guide says v2 doesn't need it. Retries reuse meta.id.
  • Waiting for the change with merged_from_id to confirm a merge. It doesn't always come.
  • Using change_source to filter out your own changes. Side effects of your merges can say app.
  • Comparing meta.entity_id with data.id as the same type. For people, one was a string and the other a number.
  • Trusting webhooks as your only source. Lost events leave no trace. Reconcile.
  • Creating the webhook with a non-admin user_id and missing events for records that user can't see.

What we couldn't verify

  • The ban. We didn't force 10 failures, and we didn't wait 3 days to see a webhook deleted. Those rules are Pipedrive's, not measured.
  • Merges of organizations and deals. Our webhook data covers people and leads only.
  • Whether v1 webhooks still send merged today, and the exact day v1 stops working. Pipedrive's changelog says 2026; a copy of the same post on its community forum said end of 2025.
  • Whether /v1/webhooks is covered by the API v1 end of support. There's no v2 endpoint to replace it, so we assume it stays.
  • Creating a webhook with an OAuth token. Our test app asked for webhooks:full, but our records don't show whether the webhook we tested was created with OAuth or an API token.
  • Webhooks for projects and field definitions. Not tested.

Where Pipehand fits

Pipehand is planned to launch in April 2027 as a replacement for Pipedrive's MCP. It is designed to use these webhooks to keep a history of every change in your Pipedrive, including merges someone made by hand, with the full copy of the absorbed record. On the Growth plan and above, that copy is what will let you undo a merge made in Pipedrive. A nightly reconciliation will catch the changes webhooks miss.

If you want an undo for merges made by hand in Pipedrive, join the waitlist on pipehand.com.

FAQ

What's the difference between Pipedrive webhooks v1 and v2?

v2 sends meta, data and previous, uses create, change and delete, and on a change sends only the changed fields in previous. v1 used current, added, updated, merged and deleted. v2 is the default since March 17, 2025, and v1 can only be created through the API.

How many times does Pipedrive retry a webhook?

3 times, after 3, 30 and 150 seconds, if your endpoint doesn't answer 2xx within 10 seconds. After the fourth failed attempt the event is lost. We measured the first retry about 3.3 seconds after a 500.

How do I detect a merge with Pipedrive webhooks?

Listen for delete events with meta.merged_to_id. That's the absorbed record, and previous holds its full last state. A change with meta.merged_from_id may follow for the kept record, but in our tests it only came when the kept record changed.

Why do I get the same Pipedrive webhook twice?

Because your endpoint failed or took more than 10 seconds, and Pipedrive retried. The retry has the same meta.id and a higher meta.attempt. Answer 2xx right away and skip any meta.id you've already processed.

Do Pipedrive webhooks count against the API rate limit?

Deliveries don't. Creating, listing and deleting webhooks through the API do: 10, 10 and 6 tokens.

Are Pipedrive webhooks signed?

No. Pipedrive documents optional basic auth (http_auth_user and http_auth_password) and no signature. In the test run where we set it, all 14 deliveries carried the basic auth header.

For developers

A minimal handler and the merge endpoints we used
  • Handler shape: check auth, save, answer, process later.

    const EXPECTED_AUTH =
      'Basic ' +
      Buffer.from(`${process.env.PD_HOOK_USER}:${process.env.PD_HOOK_PASS}`).toString('base64');
    
    app.post('/pipedrive', express.json(), async (req, res) => {
      if (req.get('authorization') !== EXPECTED_AUTH) return res.sendStatus(401);
      const { meta, data, previous } = req.body;
      // Insert with a unique constraint on meta.id: a retry of the same event does nothing.
      await saveEventIfNew(meta.id, { meta, data, previous });
      res.sendStatus(200);
    });
    

    Answer only after the event is stored, so a crash means Pipedrive retries instead of the event being lost. A worker reads the stored events. In the worker, a merge is meta.action === 'delete' && meta.merged_to_id.

  • Linking a merge to its side effects: strip a trailing -0 from meta.correlation_id and group by the result.

  • Linking your own writes: save the x-correlation-id response header of each write. It matched meta.correlation_id of the webhooks it caused in our tests.

  • Merge endpoints and costs: see merging through the API. The lead merge we used, PUT /v1/leads/{id}/merge, isn't in the public docs we checked.

  • Official SDKs: pipedrive/client-nodejs and client-php cover webhook management only. As of November 2, 2026 they had no types for the payload and no mention of merged_to_id.