Developers

Webhook v2: signed, retried, and built on Standard Webhooks

Webhook v2 signs every request, retries failed deliveries for up to 3 days and follows the open Standard Webhooks spec. Webhook v1 shuts down 30 Nov 2027.

Onur Ozgur OZKAN Onur Ozgur OZKAN
· 6 min read

Webhook v2 is live. It sends call, contact, company, deal, and task events to your server like before, but now every request is signed and a failed delivery doesn’t just disappear. We keep trying for up to 3 days. The format follows Standard Webhooks, an open spec, so there’s probably already a library for your language.

If you use our webhooks today, you’re on what we now call Webhook v1. It keeps working until 30 November 2027. You can’t create new v1 webhooks anymore, though, so new integrations should start on v2.

Software developer working on code using a computer in a modern workspace.

What’s new in Webhook v2

Every request carries 3 headers: webhook-id, webhook-timestamp, and webhook-signature. The signature is an HMAC-SHA256 of the ID, the timestamp, and the raw body. Check it, and you know the request came from Hipcall and nobody changed or replayed it on the way.

If your server is down or returns an error, we retry: 10 attempts over about 3 days. Any 2xx counts as delivered.

Each webhook has a Deliveries tab with every event from the last 30 days and every attempt we made for it. When an attempt fails, we keep your server’s response there too, which makes “why did this fail?” a lot quicker to answer. Once you’ve fixed the problem, you can resend one delivery or all failed deliveries in a time range.

Send test event fires a signed webhook.test event at your endpoint, so you can check your code before real traffic shows up.

v1 never told anyone when it stopped delivering. v2 does. If an endpoint gets turned off, or a delivery runs out of retries, the people who manage developer settings get an email. You’ll get at most 1 per webhook per day.

When you rotate the signing secret, the old one keeps working for 24 hours, so you have time to update your server without losing events. If the secret leaked, revoke the old one immediately instead.

You’ll find all of this under Settings › Developer › Webhooks, next to your API keys. Each account can have up to 3 webhooks by default. If you need more, get in touch.

One event format for everything

Every request body has the same 4 fields:

{
  "id": "evt_2nb7kq4xyc8vfr1tlm0pzab3cd",
  "type": "call.ended",
  "timestamp": "2026-10-21T11:02:09Z",
  "data": { "...": "..." }
}

data is the same object our API returns for that record. A contact in a webhook looks exactly like a contact from /api/v3, so if you already parse API responses, you can reuse that code.

contact.created and company.created also fire in more places now. In v1 they only fired when someone created the record in the panel. In v2 they fire for API calls, imports, lead forms, and campaigns too.

Why we didn’t just update v1

Most of what Standard Webhooks asks for could have gone into v1 without breaking anyone. Signature headers, a type field, treating any 2xx as success: all of that is additive. Retries are the exception.

v1 sends each event once. If your server returns an error, that event is lost. v2 can send the same event more than once. Imagine a server that writes the record, then crashes before it answers. From our side that looks like a failure, so we send the event again, and now the record exists twice.

That’s a change in the delivery guarantee, from “at most once” to “at least once”. If we’d added retries to v1 quietly, integrations that never expected a repeat would have started creating duplicates, and nobody would have known why. So v2 is a separate webhook, and you decide when to switch.

What your server needs to do

  1. Verify the signature before you parse the body. The official Standard Webhooks libraries (Node.js, Python, PHP, Go, and others) do it in a few lines.
  2. Store the webhook-id of every event you process, and skip any ID you’ve already seen. Retries and manual resends keep the same ID.
  3. Don’t assume events arrive in order. Sort by timestamp, which is when the event happened, not when we sent it.
  4. Reply fast. Return a 2xx as soon as you’ve stored the event and do the slow work afterwards. We wait up to 30 seconds.
  5. Use an HTTPS address that’s reachable from the public internet. v2 won’t send anywhere else.

If your server is overloaded, return 429 with a retry-after header and we’ll back off. If the endpoint is gone for good, return 410 and we’ll turn the webhook off.

Recording links are off by default. You can turn them on per webhook, but only if you’re allowed to see communication content, the same rule our API applies.

Moving from v1 to v2

v1 and v2 can run at the same time, so you don’t need a cutover window:

  1. Update your server to verify signatures and skip repeated IDs.
  2. Create a webhook under Settings › Developer › Webhooks and pick the same events your v1 webhook uses.
  3. Run both for a while and compare. Every event now reaches you twice, once from each version, and v1 requests have no webhook-id to match them on. Act on only one of them. Keeping v1 in charge and just logging v2 until you switch works well.
  4. When you’re happy with v2, delete the v1 webhook.

The event names have changed:

Webhook v1Webhook v2
call_initcall.initiated
call_bridgedcall.connected
call_callbackcall.callback_requested
call_hangupcall.ended
contact_createcontact.created
contact_number_updatedcontact.number_updated
company_createcompany.created
company_number_updatedcompany.number_updated
deal_createdeal.created
task_createtask.created

contact_custom_url_updated, company_website_url_updated, and company_custom_url_updated don’t exist in v2. They go away with v1.

The Webhook v1 timeline

From today, you can’t create a new v1 webhook. The ones you have keep sending, and you can still edit them: change the URL, switch events on and off, or reactivate one that was marked as broken.

Until 30 November 2027, v1 and v2 run side by side. The v1 pages show the shutdown date and link to Webhook v2.

On 30 November 2027, v1 stops sending. We keep your v1 settings, but nothing goes out after that date.

None of this affects the Slack, Telegram, or Google Chat integrations in the Marketplace.

Where to start

Webhooks come with plans that include API access. Open Settings › Developer › Webhooks, add a webhook, and press Send test event. If your server answers with a 2xx, you’re ready. For the API reference and worked examples, see the developer hub.

Analyze the content of this post with

Written by

Onur Ozgur OZKAN

Onur Ozgur OZKAN

Co-founder & CEO

The Hipcall team builds an all-in-one communication platform for sales and support teams, combining business phone, call centre, CRM, and helpdesk into a single workspace.

Stay in the loop

Get the latest product updates, tips, and industry insights delivered to your inbox.

Try for Free