Webhook / CRM
NativeAutomatically send the leads you unlock to your own system (CRM)
What it does
When you unlock a lead (spend credit), that patient's full details are instantly delivered to your own server/CRM via a signed webhook. Enter your URL, get a signing key — leads land directly in your system without copying from the panel.
How to connect
- 01
Enter and save the HTTPS webhook URL where you want to receive leads.
- 02
Send a test event with 'Send test'; if your server returns 2xx the integration activates.
- 03
When you unlock a lead, its full data is instantly POSTed to your webhook.
What this integration accesses
The real fields sent to your system when you unlock a patient (spend credit). This is exactly what the code sends.
| Field | Description |
|---|---|
| event | Event type — always "lead.unlocked" |
| delivery_id | Unique delivery id (don't process twice) |
| occurred_at | Unlock time (ISO8601) |
| clinic_id | Your clinic's id |
| lead.category | Treatment category (e.g. hair-transplant) |
| lead.title | Request title |
| lead.description | The patient's own note |
| lead.city | Preferred city |
| lead.country_code | Country code (ISO2, from phone prefix) |
| lead.country | Country name |
| lead.locale | Patient's language signal |
| lead.budget_min_eur / max_eur | Budget range (EUR) |
| lead.timing.start / end | Preferred date range |
| lead.contact.name | Patient's namePII |
| lead.contact.phone | Phone numberPII |
| lead.contact.email | Email addressPII |
| lead.credit_cost | Credits spent on this lead |
| lead.source | Lead source |
Patient contact info (name · phone · email) is sent ONLY for leads you unlock with credit. No PII is sent for requests you don't unlock.
{ } JSON
{
"event": "lead.unlocked",
"delivery_id": "dlv_9f2c…",
"occurred_at": "2026-07-24T09:12:00Z",
"clinic_id": "cl_1a2b…",
"lead": {
"category": "hair-transplant",
"city": "Köln",
"country_code": "DE",
"budget_min_eur": 2000,
"budget_max_eur": 3500,
"contact": { "name": "…", "phone": "+49…", "email": "…" },
"credit_cost": 10,
"source": "doctorvi"
}
}Signature verification
Every request includes X-ClinicVi-Signature: t=<time>,v1=<hmac>. v1 = HMAC-SHA256(secret, `${t}.${body}`) (hex). Reject if t is older than 5 minutes (replay). Delivery is at-least-once: do not process the same X-ClinicVi-Delivery (delivery_id) twice.
Signature verification example (Node):
import crypto from "node:crypto";
function verify(headers, rawBody, secret) {
const parts = Object.fromEntries(
headers["x-clinicvi-signature"].split(",").map((p) => p.split("="))
);
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && crypto.timingSafeEqual(
Buffer.from(parts.v1), Buffer.from(expected)
);
}FAQ
Is this a native integration?
No. ClinicVi's native live integrations are Telegram, Webhook/CRM and Stripe. Other tools are reached via a signed webhook (directly) or a Zapier/Make bridge.
Where does my data go?
Only to the HTTPS address you enter, one-way. Patient contact info is sent only for leads you unlock with credit.
When does it trigger?
The moment you unlock a patient (spend credit). Requests you don't unlock are never sent.
Let your first lead land straight in your system.
We review your application the same day. We handle setup; you just talk to the patient.