Scheduling Events

Scheduling Events

Scheduling events notify you about calendar and meeting-related activities.

Available Events

EventDescription
CALENDAR_MEETING_SCHEDULEDA meeting has been scheduled
CALENDAR_MEETING_CANCELLEDA meeting has been cancelled
CALENDAR_MEETING_RESCHEDULEDA meeting has been rescheduled
CALENDAR_AVAILABILITY_NOT_FOUNDNo available time slots found
CALENDAR_MORE_TIME_REQUESTEDCandidate requested more availability options
CALENDAR_NOTE_TAKER_COMPLETEDMeeting notes are ready

Meeting Details Object

All scheduling events include a meetingDetails object with comprehensive meeting information:

{
  "meetingDetails": {
    "title": "Interview with John Doe",
    "startDateTime": "2024-01-15T14:00:00.000Z",
    "endDateTime": "2024-01-15T14:30:00.000Z",
    "timezone": "America/New_York",
    "videoConference": true,
    "meetingUrl": "https://meet.google.com/abc-defg-hij",
    "participants": [
      {
        "email": "[email protected]",
        "name": "John Doe"
      },
      {
        "email": "[email protected]",
        "name": "Jane Smith"
      }
    ]
  }
}

Meeting Details Fields

FieldTypeDescription
titlestringMeeting title
startDateTimestringISO 8601 start time
endDateTimestringISO 8601 end time
timezonestringIANA timezone (e.g., America/New_York)
locationstringPhysical meeting location (only for in-person meetings)
videoConferencebooleanWhether this is a video conference
meetingUrlstringVideo conference URL (present when videoConference is true)
participantsarrayList of meeting participants

CALENDAR_MEETING_SCHEDULED

Triggered when a candidate successfully schedules a meeting.

Payload

{
  "event": "CALENDAR_MEETING_SCHEDULED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "booking_xyz789",
    "organizationId": "org_123456",
    "conversationId": "conv_abc123",
    "externalConversationId": "your_conversation_id",
    "externalCampaignId": "your_campaign_id",
    "meetingDetails": {
      "title": "Interview with John Doe",
      "startDateTime": "2024-01-15T14:00:00.000Z",
      "endDateTime": "2024-01-15T14:30:00.000Z",
      "timezone": "America/New_York",
      "videoConference": true,
      "meetingUrl": "https://meet.google.com/abc-defg-hij",
      "participants": [
        {
          "email": "[email protected]",
          "name": "John Doe"
        },
        {
          "email": "[email protected]",
          "name": "Jane Smith"
        }
      ]
    }
  }
}

Data Fields

FieldTypeDescription
conversationIdstringPopp conversation ID
externalConversationIdstringYour external conversation reference
externalCampaignIdstringYour external campaign reference
meetingDetailsobjectMeeting details

CALENDAR_MEETING_CANCELLED

Triggered when a scheduled meeting is cancelled.

Payload

{
  "event": "CALENDAR_MEETING_CANCELLED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "booking_xyz789",
    "organizationId": "org_123456",
    "conversationId": "conv_abc123",
    "externalConversationId": "your_conversation_id",
    "externalCampaignId": "your_campaign_id",
    "meetingDetails": {
      "title": "Interview with John Doe",
      "startDateTime": "2024-01-15T14:00:00.000Z",
      "endDateTime": "2024-01-15T14:30:00.000Z",
      "timezone": "America/New_York",
      "videoConference": true,
      "meetingUrl": "https://meet.google.com/abc-defg-hij",
      "participants": [
        {
          "email": "[email protected]",
          "name": "John Doe"
        }
      ]
    }
  }
}

CALENDAR_MEETING_RESCHEDULED

Triggered when a meeting is moved to a different time.

Payload

{
  "event": "CALENDAR_MEETING_RESCHEDULED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "booking_xyz789",
    "organizationId": "org_123456",
    "conversationId": "conv_abc123",
    "externalConversationId": "your_conversation_id",
    "externalCampaignId": "your_campaign_id",
    "meetingDetails": {
      "title": "Interview with John Doe",
      "startDateTime": "2024-01-16T15:00:00.000Z",
      "endDateTime": "2024-01-16T15:30:00.000Z",
      "timezone": "America/New_York",
      "videoConference": true,
      "meetingUrl": "https://meet.google.com/abc-defg-hij",
      "participants": [
        {
          "email": "[email protected]",
          "name": "John Doe"
        }
      ]
    }
  }
}

CALENDAR_NOTE_TAKER_COMPLETED

Triggered when the meeting note-taker has finished processing a meeting recording.

Payload

{
  "event": "CALENDAR_NOTE_TAKER_COMPLETED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T16:00:00.000Z",
  "data": {
    "recordId": "booking_xyz789",
    "organizationId": "org_123456",
    "conversationId": "conv_abc123",
    "externalConversationId": "your_conversation_id",
    "externalCampaignId": "your_campaign_id",
    "noteTakerTranscriptSummary": "Summary of the interview: The candidate demonstrated strong technical skills...",
    "meetingDetails": {
      "title": "Interview with John Doe",
      "startDateTime": "2024-01-15T14:00:00.000Z",
      "endDateTime": "2024-01-15T14:30:00.000Z",
      "timezone": "America/New_York",
      "videoConference": true,
      "meetingUrl": "https://meet.google.com/abc-defg-hij",
      "participants": [
        {
          "email": "[email protected]",
          "name": "John Doe"
        }
      ]
    }
  }
}

Additional Data Fields

FieldTypeDescription
noteTakerTranscriptSummarystringAI-generated summary of the meeting

CALENDAR_AVAILABILITY_NOT_FOUND

Triggered when using non-connected calendars with autoCollectAvailability set to false and pre-defined availability passed via the API, but the system could not find matching time slots to offer the candidate.

This typically occurs when creating an auto-schedule conversation via the Create Auto-Schedule Conversation API endpoint and the provided availability time slots don't produce valid meeting options.

Payload

{
  "event": "CALENDAR_AVAILABILITY_NOT_FOUND",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_xyz789",
    "organizationId": "org_123456"
  }
}

Common Reasons

  • Provided time slots have already passed
  • No overlapping availability between participants
  • Time slots don't meet minimum meeting duration requirements

CALENDAR_MORE_TIME_REQUESTED

Triggered when a candidate clicks "Request additional time" on the booking page, indicating that none of the available time slots work for them. This event is only raised when the meeting template does not have autoCollectAvailability enabled for any participant.

When this event is triggered:

  1. The conversation is marked as Needs Review in the Popp dashboard
  2. You can use the Resend Booking URL API endpoint to send new availability options

Payload

{
  "event": "CALENDAR_MORE_TIME_REQUESTED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_abc123",
    "organizationId": "org_123456",
    "conversationId": "conv_abc123",
    "externalConversationId": "your_conversation_id",
    "externalCampaignId": "your_campaign_id",
    "campaignId": "campaign_xyz789",
    "calendarMeetingTemplateId": "template_abc123"
  }
}

Data Fields

FieldTypeDescription
conversationIdstringPopp conversation ID
externalConversationIdstringYour external conversation reference (if provided at creation)
externalCampaignIdstringYour external campaign reference (if provided at creation)
campaignIdstringPopp campaign ID
calendarMeetingTemplateIdstringThe meeting template ID associated with this conversation

Recommended Actions

When you receive this event, you should:

  1. Review the request - Check if additional availability can be provided
  2. Gather new availability - Collect updated time slots from the interviewers
  3. Resend booking URL - Use the Resend Booking URL API to send a new booking link with updated availability

Example Response

case 'CALENDAR_MORE_TIME_REQUESTED':
  // Optionally, automatically resend with extended availability
  await resendBookingUrl({
    conversationId: data.conversationId,
    meetingConfiguration: extendedAvailabilityConfig,
    meetingParticipants: updatedParticipants,
  });
  break;

Example: Handling Scheduling Events

interface MeetingDetails {
  title: string;
  startDateTime: string;
  endDateTime: string;
  timezone: string;
  location?: string;
  videoConference: boolean;
  meetingUrl?: string;
  participants: { email: string; name: string }[];
}

interface SchedulingWebhookData {
  recordId: string;
  organizationId: string;
  conversationId?: string;
  externalConversationId?: string;
  externalCampaignId?: string;
  campaignId?: string;
  calendarMeetingTemplateId?: string;
  noteTakerTranscriptSummary?: string;
  meetingDetails?: MeetingDetails;
}

function handleSchedulingWebhook(payload: {
  event: string;
  eventId: string;
  eventTimestamp: string;
  data: SchedulingWebhookData;
}) {
  const { event, data } = payload;

  switch (event) {
    case 'CALENDAR_MEETING_SCHEDULED':
      // Update your calendar with the new meeting
      syncMeeting({
        conversationId: data.conversationId,
        startTime: data.meetingDetails?.startDateTime,
        endTime: data.meetingDetails?.endDateTime,
        meetingUrl: data.meetingDetails?.meetingUrl,
      });
      break;

    case 'CALENDAR_MEETING_CANCELLED':
      // Remove from calendar, notify relevant parties
      removeMeetingFromCalendar(data.conversationId);
      break;

    case 'CALENDAR_MEETING_RESCHEDULED':
      // Update calendar with new time
      updateMeetingTime({
        conversationId: data.conversationId,
        newStartTime: data.meetingDetails?.startDateTime,
        newEndTime: data.meetingDetails?.endDateTime,
      });
      break;

    case 'CALENDAR_NOTE_TAKER_COMPLETED':
      // Save meeting notes to your CRM
      saveMeetingNotes({
        conversationId: data.conversationId,
        summary: data.noteTakerTranscriptSummary,
      });
      break;

    case 'CALENDAR_AVAILABILITY_NOT_FOUND':
      // Alert team to manually find a time
      alertSchedulingTeam(data.recordId);
      break;

    case 'CALENDAR_MORE_TIME_REQUESTED':
      // Candidate needs different availability options
      notifyHiringManager({
        conversationId: data.conversationId,
        message: 'Candidate requested more time options',
      });
      // Optionally resend booking URL with new availability
      break;
  }
}

Use Cases

  • Calendar Sync: Keep external calendars synchronized with Popp meetings
  • Notifications: Send Slack/email alerts when meetings are scheduled or cancelled
  • Analytics: Track scheduling success rates and candidate engagement
  • Meeting Notes: Automatically store AI-generated meeting summaries in your CRM
  • Availability Management: Respond to candidates who need different time slots via the Resend Booking URL API