Send events to a webhook
Ovante posts a signed JSON message to your HTTPS endpoint each time an event you picked happens, retries what fails, and logs every delivery.
On this page
A custom webhook sends each event you pick to an HTTPS endpoint you run, as a signed JSON POST. Ovante has no public REST API; webhooks are how Ovante's data reaches a system of your own.
Before you start
- Connecting needs Pro, and only the org's owner can do it.
- Have an HTTPS endpoint ready that answers a POST with any 2xx status. Ovante doesn't follow redirects, and won't send to a private or local address.
Create the connection
- 1Open Settings → Integrations.
- 2On the Custom webhook card, click Connect.
- 3Give it a Name, and paste your endpoint into Destination URL.
- 4Under Events to send, tick the events you want. See Webhook events.
- 5Under Privacy, tick anything to hold back: Only send contacts who opted into marketing, Leave out phone numbers, Leave out custom field answers.
- 6Click Create connection.
- 7Copy the signing secret from Save your signing secret, store it with your endpoint's settings, and click Done.
- 8Click Send test. Ovante sends one sample per event you ticked, and says whether your endpoint accepted them.
You can open the secret again later from the connection's menu with View signing secret.
Verify the signature
Every request carries X-Ovante-Signature: t=<unix seconds>,v1=<hex>. The v1 value is an HMAC-SHA256, keyed with your signing secret, of the timestamp, a period, and the raw request body. It's the same scheme Stripe uses. Compute it over the raw body before you parse it, compare in constant time, and reject old timestamps so a captured request can't be replayed. This is the snippet the signing secret dialog gives you:
const crypto = require('crypto');
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(
header.split(',').map((p) => p.split('='))
);
const expected = crypto
.createHmac('sha256', secret)
.update(`${parts.t}.${rawBody}`)
.digest('hex');
// Reject anything older than 5 minutes.
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(parts.v1)
);
}
// header = req.headers['x-ovante-signature']Each request also carries X-Ovante-Event-Type, X-Ovante-Event-Id and Idempotency-Key, which is the same id as the event's id.
Retries and turning off
- A delivery succeeds when your endpoint answers 2xx in time. Anything else, a slow answer included, is a failure.
- Ovante retries a failed delivery several times, waiting longer between tries. After the last try it shows as Failed.
- The connection shows Failing while deliveries fail. After a long run of failures in a row, Ovante turns it off, shows Disabled, and emails the owner. An answer of 410 Gone turns it off at once.
- While it's off, Ovante holds new events instead of dropping them. Fix the endpoint, then click Resume in the connection's menu. What Ovante held from recent days goes out; anything older stays in the log to replay.
- Pause stops it on purpose. A paused connection holds nothing, so events while paused never go out.
- When
- A connection keeps failing
- Then
- After a long run of failed deliveries in a row, Ovante turns it off and emails the org's owner. A CRM that stops accepting Ovante's sign-in is turned off at the first refusal and waits for you to reconnect.
- When
- A connection is waiting to be reconnected, or a webhook was turned off after failing
- Then
- Ovante keeps a record of what happens meanwhile. Reconnecting, or turning the webhook back on, sends the recent held deliveries.
- When
- You pause a webhook connection
- Then
- Nothing is recorded or sent while it's paused, and resuming sends nothing from that time. Salesforce and ChabadOne have no pause; disconnecting is the way to stop them.
The delivery log
Open the connection's menu and click Recent activity. Each delivery shows the event, who it was about, Sent, Not sent or Failed, the HTTP status your endpoint returned, how long it took, how many tries it took, and the start of your endpoint's error body. Click Replay to send one again.
Good to know
- A delivery can arrive more than once. Dedupe on
id. - Deliveries can arrive out of order.
sequenceonly grows, so use it to order them. - Roll signing secret makes a new secret, and the old one stops verifying at once. Update your endpoint first.
- Send existing contacts sends every contact on your list that has an email as a Contact created event, whether or not the connection subscribes to it.