Manage your webhook endpoints programmatically using the Webhooks API.
Create a Webhook
Register a new webhook endpoint:
curl -X POST "https://api.meetergo.com/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "x-meetergo-api-user-id: {userId}" \
-H "Content-Type: application/json" \
-d '{
"endpoint": "https://your-server.com/webhooks/meetergo",
"description": "Production webhook",
"eventTypes": ["booking_created", "booking_cancelled", "booking_rescheduled"]
}'
Request Body
| Field | Type | Required | Description |
|---|
endpoint | string | Yes | URL to receive webhook POST requests |
description | string | No | Human-readable description |
eventTypes | string[] | Yes | Events to subscribe to |
Event Types
| Value | Description |
|---|
booking_created | New appointment booked |
booking_cancelled | Appointment cancelled |
booking_rescheduled | Appointment time changed |
new_employee | New user added to company |
Response
{
"id": "webhook-uuid-123",
"endpoint": "https://your-server.com/webhooks/meetergo",
"description": "Production webhook",
"eventTypes": ["booking_created", "booking_cancelled", "booking_rescheduled"],
"companyId": "company-uuid-789",
"createdAt": "2024-01-15T10:00:00Z"
}
List Webhooks
Get all webhooks for your company:
curl -X GET "https://api.meetergo.com/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "x-meetergo-api-user-id: {userId}"
Response
[
{
"id": "webhook-uuid-123",
"endpoint": "https://your-server.com/webhooks/meetergo",
"description": "Production webhook",
"eventTypes": ["booking_created", "booking_cancelled"],
"companyId": "company-uuid-789",
"createdAt": "2024-01-15T10:00:00Z"
},
{
"id": "webhook-uuid-456",
"endpoint": "https://staging.your-server.com/webhooks/meetergo",
"description": "Staging webhook",
"eventTypes": ["booking_created"],
"companyId": "company-uuid-789",
"createdAt": "2024-01-14T09:00:00Z"
}
]
Update a Webhook
Modify an existing webhook:
curl -X PATCH "https://api.meetergo.com/webhooks/{webhookId}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "x-meetergo-api-user-id: {userId}" \
-H "Content-Type: application/json" \
-d '{
"eventTypes": ["booking_created", "booking_cancelled", "booking_rescheduled", "new_employee"]
}'
Request Body
All fields are optional:
| Field | Type | Description |
|---|
endpoint | string | New endpoint URL |
description | string | New description |
eventTypes | string[] | New event subscriptions |
Delete a Webhook
Remove a webhook endpoint:
curl -X DELETE "https://api.meetergo.com/webhooks/{webhookId}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "x-meetergo-api-user-id: {userId}"
Returns 204 No Content on success.
Limits
| Limit | Value |
|---|
| Maximum webhooks per company | 6 |
| Minimum event types per webhook | 1 |
Error: Maximum Webhooks Reached
{
"statusCode": 406,
"message": "Company reached maximum",
"error": "Not Acceptable"
}
Solution: Delete unused webhooks before creating new ones.
Testing Webhooks
Local Development
Use a tunneling service for local development:
ngrok
ngrok http 3000
# Returns: https://abc123.ngrok.io
localtunnel
npx localtunnel --port 3000
# Returns: https://your-subdomain.loca.lt
Register the tunnel URL as your webhook endpoint during development.
Test with curl
Simulate a webhook delivery to your endpoint:
curl -X POST "https://your-server.com/webhooks/meetergo" \
-H "Content-Type: application/json" \
-d '{
"event": "booking_created",
"data": {
"id": "test-appt-123",
"start": "2024-01-15T09:00:00+01:00",
"end": "2024-01-15T09:30:00+01:00",
"attendees": [{
"email": "[email protected]",
"firstname": "Test",
"lastname": "User"
}],
"hosts": [{
"email": "[email protected]",
"givenName": "Host",
"familyName": "User"
}],
"meetingType": {
"id": "mt-123",
"meetingInfo": { "name": "Test Meeting" }
}
}
}'
Webhook Reliability
Delivery Guarantees
- Webhooks are delivered at least once
- Failed deliveries are not automatically retried
- Implement idempotent handlers using the appointment
id
Handling Failures
Your endpoint should:
- Return 200 quickly - Process asynchronously if needed
- Be idempotent - Same webhook delivered twice should have same result
- Log all requests - For debugging failed deliveries
Example: Idempotent Handler
const processedEvents = new Set();
app.post('/webhooks/meetergo', async (req, res) => {
const { event, data } = req.body;
const eventKey = `${event}:${data.id}:${data.updatedAt}`;
// Return 200 immediately
res.status(200).send('OK');
// Skip if already processed
if (processedEvents.has(eventKey)) {
console.log('Duplicate event, skipping:', eventKey);
return;
}
processedEvents.add(eventKey);
// Process asynchronously
try {
await processEvent(event, data);
} catch (error) {
console.error('Failed to process webhook:', error);
// Add to retry queue
await retryQueue.add({ event, data });
}
});
Best Practices
Use HTTPS - All production webhook endpoints should use HTTPS
Return 200 immediately - Don’t block the response while processing
Implement idempotency - Handle duplicate deliveries gracefully
Log requests - Keep logs for debugging
Monitor failures - Alert when webhook processing fails
Don’t expose secrets - Never include API keys or secrets in webhook endpoint URLs