Skip to main content
A webhook endpoint is a URL of yours that LeadVector calls when an event happens: a lead replies, a campaign completes, an email goes out. Each call carries one event, signed so you can check it came from LeadVector. Webhooks come with every paid plan. Endpoints belong to the team: each one receives the events of every member’s work. The team’s owner, and members allowed to manage the team, can create and change them.

Create an endpoint

Give the URL and the event types it should receive (["*"] for every type):
The answer holds the endpoint’s signing secret (whsec_…). It is shown only this once: store it, and use it to verify each delivery. To receive only some campaigns’ events, add "filters": { "campaignIds": ["…"] }. The campaign, lead and email events of other campaigns are then left out; events of other kinds are not affected. Then send it a test event: POST /v1/webhooks/{id}/test delivers webhook.test to that endpoint alone, and answers with what your receiver said.

What a delivery looks like

Each delivery is a POST with a JSON body, and these headers:
  • id is the event’s id, the same as the webhook-id header and the same on every attempt.
  • type says what happened; data is that type’s payload, described on each event’s page in the API reference.
  • timestamp is when it happened, not when it was delivered: a retry carries the same one.
  • team is your team. actor is the member whose action or campaign caused the event, or null when nobody did.
  • Ids are the same public ids the API uses: a campaign’s id is the uuid of /v1/campaigns/{uuid}.

Where deliveries come from

If your firewall lets callers in by address, allow LeadVector’s: Deliveries come from this address, over IPv4:
  • Allowing it is optional. The signature is what proves a delivery came from LeadVector: verify it whether or not your firewall checks the address.
  • A change is announced at least 30 days ahead. The new address is listed here beside the old one until the move is done, and the owner of every team with an endpoint is emailed.
  • Your endpoint needs an IPv4 address. A URL whose host has only IPv6 addresses is refused, with the reason NO_IPV4_ADDRESS.

Store it, answer, then do the work

Check the signature, store the event somewhere durable (a queue, a database table), then answer with any 2xx, and do the work from what you stored:
  • A 2xx means you have it. The delivery counts as succeeded, and LeadVector won’t send it again. If you can’t store it, answer an error (503, say), and it comes again on the retry schedule.
  • Answer quickly. An answer that takes too long counts as a failure, and the event comes again.
  • An event you lost after answering can still be fetched: GET /v1/events lists your team’s events of the last 30 days, in the shape a delivery has, and GET /v1/events/{id} gets one.
The same event can arrive more than once, and events can arrive out of order (a retry of an older one after a newer one). Store each webhook-id you have handled and skip one you have seen, and use timestamp when order matters.

Retries and failures

A delivery that fails is tried again, on this schedule:
  • Success: any 2xx answer within 15 seconds (5 seconds to connect). Redirects are not followed: a 3xx is retried.
  • Gone: a 410 answer disables the endpoint at once, and what waited for it is cancelled.
  • Waits vary by up to 20% either way, so retries spread out. A Retry-After header asking for longer is honored, up to 1 day.
  • After 10 failed attempts a delivery fails for good. You can retry it, or replay every failed delivery since a time, for 30 days.
  • At most 5 deliveries are in flight to one endpoint at once.
  • A failing endpoint: once every delivery to it has failed for 1 day, the team’s owner is emailed; after 5 days, the endpoint is disabled. Enable it again to receive what waited.
  • Events are kept 30 days, and can be listed (GET /v1/events) and delivered again in that time.
  • A team has up to 50 endpoints. A rotated secret can keep signing beside the new one for up to 1 day.
  • Payload version: an endpoint is pinned to the version it was created with, now 2026-11. Within a version fields are only added, never renamed, removed or retyped.
Every endpoint’s deliveries are listed with GET /v1/webhooks/{id}/deliveries, with each attempt’s status code and the start of the answer. POST /v1/webhooks/{id}/deliveries/{deliveryId}/retry sends one again now; POST /v1/webhooks/{id}/replay sends again every failed or cancelled delivery since a time.

Event types

GET /v1/webhooks/event-types lists them too, each sent one with its JSON Schema and a sample, and the API reference has a page for each.

Rotating a secret

POST /v1/webhooks/{id}/rotate-secret makes a new secret and answers with it. With overlapHours, the old one keeps signing beside it for that long, so you can switch without dropping an event: while both sign, webhook-signature holds two signatures, and either one is valid.