Skip to main content
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

FieldTypeRequiredDescription
endpointstringYesURL to receive webhook POST requests
descriptionstringNoHuman-readable description
eventTypesstring[]YesEvents to subscribe to

Event Types

ValueDescription
booking_createdNew appointment booked
booking_cancelledAppointment cancelled
booking_rescheduledAppointment time changed
new_employeeNew 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:
FieldTypeDescription
endpointstringNew endpoint URL
descriptionstringNew description
eventTypesstring[]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

LimitValue
Maximum webhooks per company6
Minimum event types per webhook1

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:
  1. Return 200 quickly - Process asynchronously if needed
  2. Be idempotent - Same webhook delivered twice should have same result
  3. 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