Create Webhook
/v2/webhooksSubscribes an https URL on a public host to event types. Answers 201 with the signing secret, shown only here; subscribing the same URL to the same events again, with the same credential, answers 200 with that webhook and its secret, so a retried create never makes a second one. At most 25 active webhooks per workspace. Free: no credits.
How are credits spent?
Webhooks are free. Creating one, the events it receives and test events consume no credits, and an event never reveals a field that a People Search by your workspace would mask.
Event types
A webhook receives a JSON POST at its url for each event type listed in
its events:
person.saved- a person entered your workspace's saved people, from the app, the browser extension, a CSV enrichment or Save People. Sent once per person; again only after the person was removed and saved anew.person.email_found- a saved person has a valid email your workspace owns, at save time or later when an email is found.company.saved- a company entered your workspace's saved companies (Save Companies).webhook.test- sent only by Send Test Event.
Only changes after the webhook was created are sent. Nothing is replayed from before, so subscribing never floods your receiver with history.
Event body
{
"id": "evt_6702a1b2c3d4e5f607182931",
"type": "person.saved",
"api_version": "2026-10",
"created_at": "2026-10-08T12:00:40.000Z",
"webhook_id": "6702a1b2c3d4e5f607182930",
"data": {
"person": { "id": "64f1a2b3c4d5e6f7a8b9c0d1", "...": "..." },
"saved_at": "2026-10-08T12:00:00.000Z",
"list_ids": ["64f1a2b3c4d5e6f7a8b9c0f1"]
}
}For person events data.person is the Person object
as People Search returns it for your workspace. For
company.saved it is { "company", "saved_at", "list_ids" } with the
Company object. Deliveries are at least once and
id stays the same across retries, so dedupe on it. A change of shape ships
as a new api_version; a webhook keeps the version it was created with.
Verify the signature
Every delivery carries these headers:
X-GetProspect-Event-IdandX-GetProspect-Event-TypeUser-Agent: GetProspect-Webhooks/1.0X-GetProspect-Signature: t=<unix seconds>,v1=<hex>
v1 is an HMAC-SHA256 over <t>.<raw body> with the webhook secret. The
secret is in the answer of this endpoint only, so store it when you create
the webhook. Check the signature on the raw body, before parsing it, and
refuse an old t:
const crypto = require("crypto");
function isValid(header, rawBody, secret) {
const [t, v1] = header.split(",").map((part) => part.split("=")[1]);
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
return (
v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(v1, "hex"), Buffer.from(expected, "hex")) &&
Math.abs(Date.now() / 1000 - Number(t)) < 300
);
}Delivery and retries
Answer 2xx within 10 seconds. Redirects are not followed. A transport
error, 408, 429 or 5xx is retried after 1 minute, 5 minutes, 30 minutes,
2 hours, 6 hours and 24 hours; after that the event is failed. Any other
answer is final. A retry is signed again with a new t.
A webhook is turned off (status: disabled) when your receiver answers
410, when deliveries did nothing but fail for 3 days, after 20 timeouts in
a row, or when the member or API key that created it is gone. Once your
receiver is fixed, re-activate it with
Update Webhook; a webhook whose creator is gone
cannot be re-activated, so create a new one. See what happened to each event
in List Webhook Deliveries.
Limits
The url must be https on a public host. A workspace can have 25 active
webhooks. Each webhook has one delivery in flight at a time, and a workspace
gets at most 10 deliveries per second. Creating a webhook with the same
url and events as one of your active webhooks returns that webhook, so a
retried request never creates a duplicate.
Body parameters
urlstringrequiredmax length: 2048Where events are POSTed: an https URL on a public host.
Example
{ "url": "https://hooks.zapier.com/hooks/standard/1/abc/", "events": [ "person.saved" ] }eventsenum[]requiredA webhook event type:
person.saved(a person entered the saved set),person.email_found(a saved person has a valid email the workspace owns),company.saved(a company entered the saved set). A webhook takes 1-10, no repeats.Allowed values:
person.savedperson.email_foundcompany.savedExample
{ "url": "https://hooks.zapier.com/hooks/standard/1/abc/", "events": [ "person.saved" ] }descriptionstringoptionalmax length: 200A note for people reading the webhook list.
api_versionenumoptionalThe payload version of the events (
2026-10); defaults to the current one.Allowed values:
2026-10
Responses
For error handling see Errors. Response objects are described in Person object and Company object.
