Skip to main content
This page documents the payload structure for each webhook event type.

booking_created

Triggered when a new appointment is booked.

Payload

{
  "webhookType": "booking_created",
  "id": "appt-uuid-12345",
  "secret": "secret-token-xyz",
  "start": "2024-01-15T09:00:00+01:00",
  "end": "2024-01-15T09:30:00+01:00",
  "location": null,
  "isCancelled": false,
  "rescheduledAt": null,
  "meetingInfo": {
    "channel": "zoom",
    "meetingLink": "https://zoom.us/j/123456789"
  },
  "attendees": [
    {
      "id": "att-uuid-789",
      "email": "customer@example.com",
      "firstname": "Jane",
      "lastname": "Doe",
      "fullname": "Jane Doe",
      "phone": "+1-555-123-4567",
      "timezone": "America/New_York",
      "language": "en"
    }
  ],
  "hosts": [
    {
      "id": "host-uuid-123",
      "email": "john@example.com",
      "givenName": "John",
      "familyName": "Smith",
      "fullName": "John Smith",
      "slug": "john-smith",
      "picture": "https://example.com/photo.jpg"
    }
  ],
  "hostIds": ["host-uuid-123"],
  "meetingType": {
    "id": "mt-uuid-456",
    "slug": "discovery-call",
    "meetingInfo": {
      "name": "Discovery Call",
      "duration": 30
    },
    "metadata": {
      "ticketId": "EVAL-12345",
      "source": "crm-integration"
    }
  },
  "meetingTypeId": "mt-uuid-456",
  "companyId": "company-uuid-789",
  "createdAt": "2024-01-14T15:30:00Z",
  "updatedAt": "2024-01-14T15:30:00Z"
}

Key Fields

FieldTypeDescription
idstringUnique appointment identifier
secretstringToken for cancel/reschedule operations
startstringStart time (ISO 8601)
endstringEnd time (ISO 8601)
attendeesarrayList of attendee objects
hostsarrayList of host objects
meetingTypeobjectMeeting type details
meetingType.metadataobjectCustom key-value data set when creating the meeting type
meetingInfo.channelstringVideo platform used
meetingInfo.meetingLinkstringVideo meeting URL

booking_cancelled

Triggered when an appointment is cancelled by the host or attendee. For group bookings, this also fires when a single attendee cancels their spot — in that case isCancelled is false (the appointment remains active for other attendees) but the cancel object is still populated.

Payload

{
  "webhookType": "booking_cancelled",
  "id": "appt-uuid-12345",
  "secret": "secret-token-xyz",
  "start": "2024-01-15T09:00:00+01:00",
  "end": "2024-01-15T09:30:00+01:00",
  "location": null,
  "isCancelled": true,
  "cancel": {
    "actionAt": "2024-01-14T18:00:00Z",
    "actionSource": "attendee",
    "reason": "Schedule conflict",
    "actionBy": null
  },
  "attendees": [
    {
      "id": "att-uuid-789",
      "email": "customer@example.com",
      "firstname": "Jane",
      "lastname": "Doe",
      "fullname": "Jane Doe"
    }
  ],
  "hosts": [
    {
      "id": "host-uuid-123",
      "email": "john@example.com",
      "givenName": "John",
      "familyName": "Smith",
      "fullName": "John Smith"
    }
  ],
  "hostIds": ["host-uuid-123"],
  "meetingType": {
    "id": "mt-uuid-456",
    "slug": "discovery-call"
  },
  "meetingTypeId": "mt-uuid-456",
  "companyId": "company-uuid-789",
  "createdAt": "2024-01-14T15:30:00Z",
  "updatedAt": "2024-01-14T18:00:00Z"
}

Key Fields

FieldTypeDescription
isCancelledbooleantrue for full cancellations, false when a single attendee leaves a group booking
cancel.actionAtstringWhen the cancellation occurred (ISO 8601)
cancel.actionSourcestringWho cancelled: attendee, host, or company (admin)
cancel.reasonstring | nullOptional cancellation reason
cancel.actionByobject | nullHost/admin who cancelled. null when the attendee cancels
cancel.actionBy.idstringUser ID of the host/admin
cancel.actionBy.emailstringEmail of the host/admin

booking_rescheduled

Triggered when an appointment is moved to a new time.

Payload

{
  "webhookType": "booking_rescheduled",
  "oldStartDate": "2024-01-15T09:00:00+01:00",
  "rescheduledAppointment": {
    "id": "appt-uuid-12345",
    "secret": "secret-token-xyz",
    "start": "2024-01-16T10:00:00+01:00",
    "end": "2024-01-16T10:30:00+01:00",
    "location": null,
    "isCancelled": false,
    "rescheduledAt": "2024-01-14T18:30:00Z",
    "attendees": [
      {
        "id": "att-uuid-789",
        "email": "customer@example.com",
        "firstname": "Jane",
        "lastname": "Doe",
        "fullname": "Jane Doe"
      }
    ],
    "hosts": [
      {
        "id": "host-uuid-123",
        "email": "john@example.com",
        "givenName": "John",
        "familyName": "Smith",
        "fullName": "John Smith"
      }
    ],
    "hostIds": ["host-uuid-123"],
    "meetingType": {
      "id": "mt-uuid-456",
      "slug": "discovery-call"
    },
    "meetingTypeId": "mt-uuid-456",
    "companyId": "company-uuid-789",
    "createdAt": "2024-01-14T15:30:00Z",
    "updatedAt": "2024-01-14T18:30:00Z"
  }
}

Key Fields

FieldTypeDescription
oldStartDatestringOriginal start time
rescheduledAppointmentobjectUpdated appointment details
rescheduledAppointment.startstringNew start time
rescheduledAppointment.rescheduledAtstringWhen the reschedule occurred

new_employee

Triggered when a new user is added to your company.

Payload

{
  "webhookType": "new_employee",
  "id": "user-uuid-456",
  "email": "new.hire@example.com",
  "givenName": "Sarah",
  "familyName": "Johnson",
  "fullName": "Sarah Johnson",
  "companyId": "company-uuid-789",
  "userType": "REGULAR",
  "createdAt": "2024-01-14T10:00:00Z"
}

Key Fields

FieldTypeDescription
idstringUser’s unique identifier
emailstringUser’s email address
givenNamestringFirst name
familyNamestringLast name
userTypestringREGULAR or API_PLATFORM

form_submission

Triggered when someone submits a routing form or funnel.

Payload

{
  "webhookType": "form_submission",
  "formId": "form-uuid-123",
  "formName": "Contact Form",
  "formSlug": "contact-form",
  "companyId": "company-uuid-789",
  "workspaceId": "workspace-uuid-456",
  "submissionData": {
    "company_size": "50-200",
    "use_case": "sales"
  },
  "submittedAt": "2024-01-15T10:00:00.000Z",
  "contact": {
    "id": "contact-uuid-789",
    "email": "lead@example.com",
    "firstName": "Sarah",
    "lastName": "Johnson",
    "phoneNumber": "+1-555-987-6543"
  }
}

Key Fields

FieldTypeDescription
formIdstringUnique form identifier
formNamestringDisplay name of the form
formSlugstringURL-friendly form identifier
submissionDataobjectKey-value pairs from form fields
submittedAtstringWhen the form was submitted (ISO 8601)
contactobject | nullContact info if available
contact.emailstringContact’s email address

Common Attendee Fields

All booking events include attendee information:
FieldTypeDescription
idstringAttendee record ID
emailstringEmail address
firstnamestringFirst name
lastnamestringLast name
fullnamestringCombined full name
phonestringPhone number (if provided)
timezonestringAttendee’s timezone
languagestringPreferred language code
notesstringNotes from booking form
attendeeEnrichmentobjectEnriched data from integrations

Common Host Fields

All booking events include host information:
FieldTypeDescription
idstringHost user ID
emailstringEmail address
givenNamestringFirst name
familyNamestringLast name
fullNamestringCombined full name
slugstringURL-friendly identifier
picturestringProfile photo URL

Handling Events

Example: Sync to CRM

async function handleBookingCreated(payload) {
  const attendee = payload.attendees[0];

  // Create or update contact in your CRM
  await crm.contacts.upsert({
    email: attendee.email,
    firstName: attendee.firstname,
    lastName: attendee.lastname,
    phone: attendee.phone,
    lastMeetingDate: payload.start,
    meetingType: payload.meetingType.meetingInfo.name
  });

  // Log the activity
  await crm.activities.create({
    type: 'meeting_scheduled',
    contactEmail: attendee.email,
    subject: `${payload.meetingType.meetingInfo.name} scheduled`,
    scheduledAt: payload.start,
    hostEmail: payload.hosts[0].email
  });
}

Example: Send Slack Notification

async function handleBookingCreated(payload) {
  const attendee = payload.attendees[0];
  const host = payload.hosts[0];

  await slack.chat.postMessage({
    channel: '#bookings',
    text: `New booking!`,
    blocks: [
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `*New ${payload.meetingType.meetingInfo.name}*\n` +
                `Attendee: ${attendee.fullname} (${attendee.email})\n` +
                `Host: ${host.fullName}\n` +
                `Time: ${new Date(payload.start).toLocaleString()}`
        }
      }
    ]
  });
}

Example: Correlate with External Ticket

Use metadata to link bookings back to external systems (e.g., CRM tickets, support cases):
async function handleBookingCreated(payload) {
  // Access custom metadata set when creating the meeting type
  const ticketId = payload.meetingType.metadata?.ticketId;

  if (ticketId) {
    // Update your ticket system with the booking details
    await ticketSystem.updateTicket(ticketId, {
      status: 'appointment_scheduled',
      appointmentTime: payload.start,
      appointmentId: payload.id,
      attendeeEmail: payload.attendees[0].email,
      hostName: payload.hosts[0].fullName
    });

    // Optionally clean up the meeting type after booking
    await fetch(`https://api.meetergo.com/v4/meeting-type/${payload.meetingType.id}`, {
      method: 'DELETE',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'x-meetergo-api-user-id': payload.hosts[0].id
      }
    });
  }
}
The metadata field is set when creating the meeting type and is included in all booking webhooks. Use it to correlate bookings with your external systems.