Webhooks
Webhooks deliver HTTP POST notifications to your endpoint when events occur.
Supported events
Section titled “Supported events”| Event | Triggered when |
|---|---|
lead.created | A new lead is created |
lead.updated | A lead is updated |
lead.deleted | A lead is deleted |
lead.scored | A lead score is recalculated |
note.created | A note is added to a lead |
note.deleted | A note is deleted |
List Webhooks
Section titled “List Webhooks”GET /webhooksCreate Webhook
Section titled “Create Webhook”POST /webhooks{ "url": "https://your-server.com/hooks/klozeo", "events": ["lead.created", "lead.updated"], "secret": "optional-signing-secret"}Response 201 Created: Full webhook object.
If a secret is provided, each request includes an X-Klozeo-Signature header (HMAC-SHA256 of the raw request body, hex-encoded).
Delete Webhook
Section titled “Delete Webhook”DELETE /webhooks/{id}Response 204 No Content.
Payload format
Section titled “Payload format”All timestamps are Unix seconds.
{ "event": "lead.created", "timestamp": 1703520000, "data": { "id": "cl_...", "name": "Acme", "source": "website", "score": 0, "created_at": 1703520000 }}The data object is the full lead (or note) that triggered the event.
Verifying signatures
Section titled “Verifying signatures”When a secret is set, verify each incoming request to prevent spoofed events:
import hmac, hashlib
def verify_webhook(payload_bytes: bytes, signature_header: str, secret: str) -> bool: expected = hmac.new(secret.encode(), payload_bytes, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature_header)
# In your request handler:body = request.get_data() # raw bytes, before any parsingsig = request.headers.get("X-Klozeo-Signature", "")if not verify_webhook(body, sig, "your-secret"): return 401const crypto = require("crypto");
function verifyWebhook(rawBody, signatureHeader, secret) { const expected = crypto .createHmac("sha256", secret) .update(rawBody) .digest("hex"); return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));}Delivery & reliability
Section titled “Delivery & reliability”- Your endpoint must return a
2xxstatus within 5 seconds to acknowledge receipt. - Design your handler to be idempotent — the same event may be delivered more than once in rare cases (network failures, retries).
- If your endpoint is unreachable or returns a non-2xx status, deliveries are retried with exponential backoff.