Webhooks
Receive real-time notifications when events happen in your GetTalk account. Available on Pro plans.
Overview
Webhooks allow you to receive HTTP POST notifications to your server when events occur in GetTalk. This enables you to:
- Sync bookings to your CRM
- Send custom notification emails
- Update external calendars
- Trigger automations in tools like Zapier or Make
- Log events for analytics
Setting Up Webhooks
- Go to Dashboard → Webhooks
- Click "Add Webhook"
- Enter your endpoint URL (must be HTTPS)
- Select the events you want to receive
- Save and note your webhook secret for signature verification
Event Types
| Event | Description |
|---|---|
booking.created | A new booking has been created |
booking.confirmed | A booking has been confirmed |
booking.cancelled | A booking has been cancelled |
booking.rescheduled | A booking has been rescheduled |
booking.completed | A booking has been marked as completed |
booking.no_show | Attendee did not show up |
Payload Format
All webhooks are sent as HTTP POST requests with a JSON body:
{
"event": "booking.created",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {
"id": "clk123abc",
"status": "CONFIRMED",
"startTime": "2024-01-20T14:00:00.000Z",
"endTime": "2024-01-20T14:30:00.000Z",
"durationMinutes": 30,
"timezone": "Europe/Oslo",
"attendee": {
"name": "John Doe",
"email": "[email protected]",
"phone": "+1234567890",
"company": "Acme Inc",
"notes": "Looking forward to our call"
},
"meeting": {
"type": "video",
"location": "Google Meet",
"link": "https://meet.google.com/xxx-yyy-zzz"
},
"eventType": {
"id": "evt123",
"name": "30 Minute Meeting",
"slug": "30-min-meeting"
},
"host": {
"id": "usr123",
"name": "Jane Smith",
"email": "[email protected]"
},
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
}HTTP Headers
Each webhook request includes the following headers:
| Header | Description |
|---|---|
Content-Type | application/json |
X-GetTalk-Event | The event type (e.g., booking.created) |
X-GetTalk-Signature | HMAC-SHA256 signature for verification |
X-GetTalk-Timestamp | Unix timestamp of when the webhook was sent |
Signature Verification
Always verify webhook signatures to ensure requests are from GetTalk. The signature is computed using HMAC-SHA256.
Security: Never skip signature verification in production. Skipping this step could allow attackers to send fake webhook events.
Verification Steps
- Get the timestamp from the
X-GetTalk-Timestampheader - Get the signature from the
X-GetTalk-Signatureheader - Create the signed payload:
{timestamp}.{body} - Compute HMAC-SHA256 with your webhook secret
- Compare the computed signature with the received signature
Node.js Example
import crypto from 'crypto'
function verifyWebhookSignature(payload, signature, timestamp, secret) {
const signedPayload = `${timestamp}.${payload}`
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
)
}
// Express.js handler
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-gettalk-signature']
const timestamp = req.headers['x-gettalk-timestamp']
const payload = req.body.toString()
if (!verifyWebhookSignature(payload, signature, timestamp, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature')
}
const event = JSON.parse(payload)
console.log('Received event:', event.event)
// Process the webhook...
res.status(200).send('OK')
})Python Example
import hmac
import hashlib
def verify_webhook_signature(payload, signature, timestamp, secret):
signed_payload = f"{timestamp}.{payload}"
expected_signature = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_signature)
# Flask handler
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-GetTalk-Signature')
timestamp = request.headers.get('X-GetTalk-Timestamp')
payload = request.get_data(as_text=True)
if not verify_webhook_signature(payload, signature, timestamp, WEBHOOK_SECRET):
return 'Invalid signature', 401
event = request.get_json()
print(f"Received event: {event['event']}")
# Process the webhook...
return 'OK', 200Retry Policy
If your endpoint returns a non-2xx status code or times out, we'll retry the webhook:
- First retry: 1 minute after initial attempt
- Second retry: 5 minutes after first retry
- Third retry: 30 minutes after second retry
- Fourth retry: 2 hours after third retry
- Fifth retry: 24 hours after fourth retry
After 5 failed attempts, the webhook will be marked as failed. You can view failed webhooks in your dashboard and manually retry them.
Best Practices
Respond Quickly
Return a 200 response immediately after receiving the webhook. Process the event asynchronously (e.g., using a queue) to avoid timeouts.
Handle Duplicates
Webhooks may occasionally be sent more than once. Use the booking ID to deduplicate events in your system.
Use HTTPS
Webhook endpoints must use HTTPS to protect data in transit. We don't send webhooks to HTTP endpoints.
Validate Timestamps
Reject webhooks with timestamps older than 5 minutes to prevent replay attacks.
Testing Webhooks
You can test your webhook endpoint from the dashboard:
- Go to Dashboard → Webhooks
- Click the "Test" button next to your webhook
- Select an event type to send
- A test event will be sent to your endpoint
For local development, use tools like ngrok or webhook.site to expose your local server to the internet.