Overview
Webhooks send HTTP POST requests to your URL when events happen in Tonic Desk. Use them to sync data with other tools, trigger automations, or keep external systems up to date.
Setup
- Go to Settings > Webhooks
- Click Add Webhook
- Enter your endpoint URL (must be HTTPS)
- Select which events to subscribe to
- Optionally add a signing secret for verification
Available Events
| Event | Fires when |
|---|---|
contact.created |
A new contact is created |
contact.updated |
A contact is modified |
contact.deleted |
A contact is deleted |
company.created |
A new company is created |
company.updated |
A company is modified |
company.deleted |
A company is deleted |
deal.created |
A new deal is created |
deal.updated |
A deal is modified |
deal.stage_changed |
A deal moves to a different stage |
deal.won |
A deal is marked as won |
deal.lost |
A deal is marked as lost |
task.created |
A new task is created |
task.completed |
A task is marked as completed |
activity.created |
A new activity is logged |
Payload Format
All webhooks deliver a JSON payload:
{
"event": "deal.stage_changed",
"timestamp": "2026-04-05T14:30:00Z",
"data": {
"id": 42,
"name": "Acme Enterprise License",
"amount": 25000,
"stage": "Negotiation",
"previous_stage": "Proposal",
"pipeline": "Sales Pipeline"
}
}
Signature Verification
If you provided a signing secret, each webhook includes an X-Webhook-Signature header containing an HMAC-SHA256 signature of the request body.
Verify it in your handler:
import hmac
import hashlib
def verify_signature(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Delivery
- Webhooks are delivered within seconds of the event
- Failed deliveries (non-2xx response) are retried up to 3 times with exponential backoff
- Delivery history is available in Settings > Webhooks for each endpoint
- Webhook URLs must be publicly accessible HTTPS endpoints (no internal/private URLs)
Best Practices
- Always verify the signature if you set a secret. This prevents spoofed requests.
- Respond with 200 quickly. Process the webhook asynchronously. Return 200 immediately, then handle the data in a background job.
- Handle duplicates. In rare cases, a webhook may be delivered more than once. Use the event ID or timestamp to deduplicate.
- Monitor delivery failures. Check the webhook delivery history periodically. Consistent failures may indicate an endpoint issue.