Quickstart
From zero to your first accepted webhook in under ten minutes.
This guide walks you through wiring up a Custom Integration end-to-end. By the end you will have an event accepted by LiveRecover and visible in your LiveRecover dashboard.
1. Generate your webhook secret
In the LiveRecover dashboard, open Settings → Providers → Custom E-Com and click Connect. The page will display:
- A short
webhookId(an opaque, URL-safe string). - A one-time-visible
webhook_secret— copy this immediately into your platform's secret store. It is shown only at creation and on rotation.
You can rotate the secret at any time from the same page. When you click
Regenerate, LiveRecover issues a fresh webhook_secret and keeps your
previous secret valid for 24 hours, so requests still in flight or
being retried during your rollout keep verifying. After 24 hours the old
secret stops being accepted and signatures computed with it are rejected
with 401.
The matching API key is not graced — it is invalidated immediately on rotation. Only the webhook secret carries the 24-hour grace window.
The safe rollout is: click Regenerate, copy the new webhook_secret
into your sender's configuration, and deploy. You have a full 24 hours to
finish that deploy before the old secret stops working. See
HMAC Verification → Rotating your secret
for the full grace-window semantics.
2. Note your webhook URL
Your endpoint is:
POST https://<your-vyg-webhook-host>/custom/{webhookId}Replace {webhookId} with the value from step 1. Your account contact
will give you the exact <your-vyg-webhook-host> for your environment.
3. Send a sample event
Every request must include three headers and a JSON body:
| Header | Value |
|---|---|
content-type | application/json |
x-vyg-signature | Lowercase hex HMAC-SHA256 of the raw body, keyed with your secret. |
x-vyg-event-id | A unique string per event. Same id within 24h is idempotent. |
x-vyg-topic | One of the supported topics (see Endpoint Reference). |
The JSON body must include type, event_id, and data:
{
"type": "checkout_abandoned",
"event_id": "evt_01HZX5K9N2P0Q5R7T9V1W3Y5A7",
"data": { "id": "ck_001", "email": "shopper@example.com", "total_price": "42.00" }
}End-to-end cURL:
SECRET="your-webhook-secret"
URL="https://<your-vyg-webhook-host>/custom/V1StGXR8_Z5jdHi6B-myT"
BODY='{"type":"checkout_abandoned","event_id":"evt_demo_1","data":{"id":"ck_001","email":"shopper@example.com","total_price":"42.00"}}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')
curl -sS -X POST "$URL" \
-H "content-type: application/json" \
-H "x-vyg-topic: checkout_abandoned" \
-H "x-vyg-event-id: evt_demo_1" \
-H "x-vyg-signature: $SIG" \
--data "$BODY"Full HMAC details — including Node and Python examples — live in HMAC Verification.
4. Verify success
A successful request returns 200 OK with body {"ok":true}. The matching
checkout, order, subscription, or charge will appear in the LiveRecover
dashboard within a few seconds.
If the same x-vyg-event-id is replayed inside the 24-hour idempotency
window, the response is still 200 OK with body {"deduplicated":true} — no
duplicate work is done.
The 200 response confirms the event was recorded, not that a flow ran.
If you have built and activated a campaign flow on this event, flow
triggering happens asynchronously afterward — a background poll picks
the event up within a few minutes and runs your flow. The webhook response
always reports flow_event_id: null because no flow has run yet at reply
time. See
Custom Events → Triggering flows for
how events become flow candidates and where flow activity is visible.
5. Handle retries
Treat the response status as the source of truth:
- 2xx — accepted. Stop retrying.
- 4xx — your request is wrong (bad signature, malformed body, unknown integration id). Do not retry; fix the request first.
- 5xx — transient on our side. Retry with jittered exponential backoff.
See Errors & Retry Semantics for the full status-code catalog and a recommended retry policy.