Skip to main content
Webhooks let your own systems hear about new leads and waitlist signups as they happen, without polling the API. You give us a URL, and every time one of these events happens in your project, we send a POST request to it with the details.

Events

A webhook listens to both events by default. You can pick just one when you register it. You’ll need an API token (see Authentication) for a user who can edit the project: the owner, an administrator or an editor.

Register a webhook

Send a POST to your project’s webhooks endpoint with your API token:
The response includes the webhook and its signing secret:
The secret is only shown once, in this response. Store it somewhere safe right away: you’ll need it to verify that requests really come from Planpoint. If you lose it, delete the webhook and create a new one.
A few rules for the URL:
  • It has to be https, and reachable from the internet. Internal and private addresses are rejected.
  • We don’t follow redirects, so point it at the final address.
  • Each project can have up to 10 webhooks.

What we send

Every delivery is a POST with a JSON body like this:
What goes in data depends on the fields of your form, so it can have more or fewer fields than this example. data.id is the lead’s id in Planpoint. It’s missing if your account is set up not to store leads. And these headers: Answer with any 2xx status within 5 seconds to let us know you got it. Anything else, or no answer in time, counts as a failure and we’ll retry.
The same event can occasionally reach you more than once (for example, if your server got it but answered too late). Use id to ignore repeats.

Verify the signature

Anyone could send a request to your URL, so check the signature before trusting it. The X-Planpoint-Signature header has two parts:
  • t: when we sent it, in Unix seconds.
  • v1: an HMAC-SHA256 of "<t>.<raw body>", using your webhook secret as the key, in hex.
To verify it, compute the same HMAC on your side and compare. Use the raw body exactly as it arrived: if you parse the JSON and stringify it again, the signature won’t match. Here’s a short example with Node and Express:

Retries

If a delivery fails, we try again with growing gaps between attempts: That’s one first attempt plus 5 retries, over about 15 hours. Every retry carries the same body, with the same id. If the last one also fails, we stop trying for that event.

Automatic pause

If a webhook fails 20 times in a row, we pause it so we don’t keep calling a server that’s down. While it’s paused, no events are sent to it. Once your server is back, turn it on again (see below): that also resets its failure count. Retries that were still pending when it got paused are dropped.

Manage your webhooks

All of these use the same Authorization: Bearer YOUR_API_TOKEN header.

List them

Each webhook comes with its delivery status (lastStatus, lastError, lastDeliveryAt, failureCount). The secret is never shown again, only its last 4 characters in secretHint, so you can tell them apart.

Send a test

We send a signed webhook.test event to your URL right away and tell you how it went:
It’s the quickest way to check your URL and your signature code before real leads come in. Test events aren’t retried.

Pause or turn it back on

Send { "active": true } to turn it back on.

Delete it

Pending retries for a deleted webhook are dropped.