Webhooks
Webhooks allow SilentChat to push real-time event notifications to your server. Instead of polling the API, your application receives an HTTP POST request whenever an event occurs.
Setting Up a Webhook
- In the dashboard, go to Settings → Webhooks and click New Webhook.
- Enter the HTTPS URL of your endpoint.
- Select the events you want to receive.
- Click Save. SilentChat will immediately send a test ping event to verify the endpoint is reachable.
Available Events
| Event | Description |
|---|---|
conversation.created | A new conversation has been started by a visitor. |
conversation.closed | A conversation has been marked as resolved. |
conversation.assigned | A conversation has been assigned to an agent or team. |
message.created | A new message has been sent in a conversation. |
contact.created | A new contact has been created. |
contact.updated | A contact's details have been updated. |
visitor.identified | A tracked visitor has become active on a domain. |
widget.installed | A test event sent when a webhook is first created or tested manually. |
subscription.updated | A test event sent when a webhook is first created or tested manually. |
Payload Format
Every webhook request is an HTTP POST with a JSON body and the Content-Type: application/json header. The top-level structure is consistent across all events:
{"id": "evt_01HXY3ABC","type": "message.created","tenant_id": "tn_abc123","created_at": "2025-10-12T14:35:00Z","data": {"conversation_id": "conv_01HXYZ","message_id": "msg_01HXYZ","sender_type": "visitor","text": "Hi, I need help with my order."}}
Webhook Request Headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-SilentChat-Signature | Every webhook request includes an X-SilentChat-Signature header containing an HMAC-SHA256 signature. Always verify this signature to confirm the request originated from SilentChat and was not tampered with. |
X-SilentChat-Event | The event type string (e.g. conversation.created). |
X-SilentChat-Delivery | A unique identifier for this delivery attempt. |
Verifying the Signature
Every webhook request includes an X-SilentChat-Signature header containing an HMAC-SHA256 signature. Always verify this signature to confirm the request originated from SilentChat and was not tampered with.
Verification Example (Node.js)
const crypto = require('crypto');function verifySignature(secret, body, signature) {const expected = crypto.createHmac('sha256', secret).update(body, 'utf8').digest('hex');return crypto.timingSafeEqual(Buffer.from(expected, 'hex'),Buffer.from(signature, 'hex'));}// In your request handler:app.post('/webhooks/silentchat', (req, res) => {const signature = req.headers['x-silentchat-signature'];const rawBody = req.rawBody; // raw request body as a stringif (!verifySignature(process.env.SC_WEBHOOK_SECRET, rawBody, signature)) {return res.status(401).send('Invalid signature');}const event = req.body;console.log('Received event:', event.type);// Process the event ...res.status(200).send('OK');});
Verification Example (Python)
import hmacimport hashlibimport osfrom flask import Flask, request, abortapp = Flask(__name__)def verify_signature(secret: str, body: bytes, signature: str) -> bool:expected = hmac.new(secret.encode('utf-8'),body,hashlib.sha256).hexdigest()return hmac.compare_digest(expected, signature)@app.route('/webhooks/silentchat', methods=['POST'])def handle_webhook():signature = request.headers.get('X-SilentChat-Signature', '')raw_body = request.get_data()if not verify_signature(os.environ['SC_WEBHOOK_SECRET'], raw_body, signature):abort(401)event = request.get_json()print(f"Received event: {event['type']}")# Process the event ...return 'OK', 200
Retry Policy
If your endpoint does not respond with a 2xx status within 10 seconds, SilentChat will retry the delivery with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry: 1 minute after the initial attempt. | 2nd retry: 5 minutes later. |
| 3rd retry: 30 minutes later. | 4th retry: 2 hours later. |
| 5th retry: 8 hours later. | 5th retry: 8 hours later. |
After five failed attempts the webhook delivery is marked as failed. You can inspect and replay failed deliveries from Settings → Webhooks → Delivery Log.
If an endpoint consistently fails (more than 100 consecutive failures) it will be automatically disabled and you will receive an email notification.
Best Practices
- Respond with a 200 OK immediately and process the event asynchronously to avoid timeout failures.
- Make your handler idempotent — SilentChat may deliver the same event more than once.
- Always verify the signature before processing any payload.
- Filter events at the webhook configuration level rather than ignoring them in code.
- Use the delivery log in the dashboard to inspect and replay failed events during development.