Webhooks
Signed event deliveries: available events, verifying X-LinkProfit-Signature in JavaScript and Python, retries and the failing state.
Updated August 13, 2026
Webhooks push events to your endpoint as JSON POST requests — no polling.
Register endpoints in the dashboard (Settings → Webhooks) or via
POST /v1/webhooks; the signing secret is shown once at creation.
Events
| Event | Fires when | Available to |
|---|---|---|
| link.created / link.updated / link.deleted | A link changes — via dashboard, API or bulk import | workspace and partner endpoints |
| domain.pending_ssl | DNS verified, certificate being issued | workspace and partner |
| domain.activated | The domain serves traffic | workspace and partner |
| domain.error | Provisioning failed; details inside | workspace and partner |
| click.threshold | 80% / 100% of the monthly tracked-clicks limit | workspace and partner |
| conversion.created | A conversion was recorded: an order, signup or custom goal attributed to a click | workspace and partner |
| workspace.subscribed | A client paid the first invoice of a subscription | partner only |
| workspace.past_due | A client payment failed | partner only |
| workspace.suspended | A client was suspended (dunning or manually) | partner only |
| payment.succeeded | A client payment settled, with the fee breakdown | partner only |
| payment.refunded | A payment was refunded | partner only |
The delivery
POST /your/endpoint HTTP/1.1
Content-Type: application/json
X-LinkProfit-Event: link.created
X-LinkProfit-Delivery: dlv_8Yq2…
X-LinkProfit-Signature: t=1755081600,v1=5f8a2c…
{
"id": "dlv_8Yq2…",
"type": "link.created",
"created_at": "2026-08-13T10:00:00.000Z",
"data": { "id": "lnk_…", "domain": "go.your-brand.com", "slug": "x7f2q1z", "url": "https://example.com" }
}
Answer with any 2xx within 10 seconds. Anything else — including a timeout —
counts as a failure and schedules a retry. Deliveries can arrive out of order
and, rarely, twice: deduplicate by id.
Verifying the signature
The signature is HMAC-SHA256 over `${t}.${rawBody}` with your endpoint
secret, hex-encoded. Always verify against the raw request body, before any
JSON parsing, and reject timestamps older than 5 minutes.
import { createHmac, timingSafeEqual } from "node:crypto";
function verifySignature(secret, rawBody, header, toleranceSeconds = 300) {
const parts = Object.fromEntries(
header.split(",").map((piece) => piece.split("=", 2)),
);
if (!parts.t || !parts.v1) return false;
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > toleranceSeconds) return false;
const expected = createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(parts.v1);
return a.length === b.length && timingSafeEqual(a, b);
}
import hashlib
import hmac
import time
def verify_signature(secret: str, raw_body: bytes, header: str, tolerance: int = 300) -> bool:
parts = dict(piece.split("=", 1) for piece in header.split(",") if "=" in piece)
timestamp, signature = parts.get("t"), parts.get("v1")
if not timestamp or not signature:
return False
if abs(time.time() - int(timestamp)) > tolerance:
return False
expected = hmac.new(
secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Retries and the failing state
The first attempt is immediate. Failures retry on a fixed schedule:
1 min → 5 min → 30 min → 2 h → 12 h. After the fifth retry the endpoint is
marked failing, stops receiving new events and the owner gets an email.
Fix the endpoint, then re-enable it in the dashboard or with
PATCH /v1/webhooks/{id} and {"status": "active"}. Missed events are not
replayed automatically — the delivery log (GET /v1/webhooks/{id}/deliveries
or the dashboard) shows every payload so you can reconcile.
A successful delivery resets the failure streak.
Testing
The Send test button (or POST /v1/webhooks/{id}/test) delivers a real,
signed event with "data": { "test": true } through the same pipeline as
production events — the delivery log shows the response of your endpoint.