Webhooks
PushButtonCRM can POST signed JSON payloads to your endpoint whenever CRM events occur. Use webhooks to sync data to external systems in real time.
Setup
- Go to Settings → Developer → Webhooks
- Click Add endpoint
- Enter your HTTPS endpoint URL
- Select the event types you want to receive
- Copy the generated webhook secret for signature verification
Payload format
All webhook payloads are JSON objects with a consistent envelope:
{
"id": "evt_01HXK9P2Y3Z4A5B6C7D8E9F0",
"event": "contact.created",
"created_at": "2026-03-16T10:23:41Z",
"tenant_id": 12,
"data": {
"id": 1043,
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@acme.com",
"stage": "prospect",
"pipeline_type": "sales"
}
}Signature verification
Every request includes an X-PushButtonCRM-Signature header containing an HMAC-SHA256 signature of the raw request body, signed with your webhook secret. Always verify this signature before processing the payload.
// Node.js verification example
import crypto from "crypto";
export function verifyWebhook(rawBody: string, signature: string, secret: string) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody, "utf8")
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expected, "hex")
);
}Always use
timingSafeEqual — never compare signatures with ===, which is vulnerable to timing attacks.Retry policy
PushButtonCRM retries failed deliveries (non-2xx or timeout) with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 5 seconds |
| 2nd retry | 30 seconds |
| 3rd retry | 5 minutes |
| 4th retry | 30 minutes |
| Final retry | 2 hours |
After 5 failed attempts the delivery is marked as failed. You can replay failed deliveries from the Webhooks dashboard.
Event types
| Event | Description |
|---|---|
| contact.created | A new contact was added |
| contact.updated | A contact field was changed |
| contact.deleted | A contact was soft-deleted |
| deal.created | A new deal was created |
| deal.updated | A deal field (stage, value, etc.) changed |
| deal.won | A deal was marked as won |
| deal.lost | A deal was marked as lost |
| campaign.sent | An email or SMS campaign was dispatched |
| automation.fired | An automation rule was triggered |
| ticket.opened | A new support ticket was created |
| ticket.closed | A support ticket was resolved |