Scheduling Events
Scheduling Events
Scheduling events notify you about calendar and meeting-related activities.
Available Events
| Event | Description |
|---|---|
CALENDAR_MEETING_SCHEDULED | A meeting has been scheduled |
CALENDAR_MEETING_CANCELLED | A meeting has been cancelled |
CALENDAR_MEETING_RESCHEDULED | A meeting has been rescheduled |
CALENDAR_AVAILABILITY_NOT_FOUND | No available time slots found |
CALENDAR_MORE_TIME_REQUESTED | Candidate requested more availability options |
CALENDAR_NOTE_TAKER_COMPLETED | Meeting 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
| Field | Type | Description |
|---|---|---|
title | string | Meeting title |
startDateTime | string | ISO 8601 start time |
endDateTime | string | ISO 8601 end time |
timezone | string | IANA timezone (e.g., America/New_York) |
location | string | Physical meeting location (only for in-person meetings) |
videoConference | boolean | Whether this is a video conference |
meetingUrl | string | Video conference URL (present when videoConference is true) |
participants | array | List 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
| Field | Type | Description |
|---|---|---|
conversationId | string | Popp conversation ID |
externalConversationId | string | Your external conversation reference |
externalCampaignId | string | Your external campaign reference |
meetingDetails | object | Meeting 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
| Field | Type | Description |
|---|---|---|
noteTakerTranscriptSummary | string | AI-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:
- The conversation is marked as Needs Review in the Popp dashboard
- 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
| Field | Type | Description |
|---|---|---|
conversationId | string | Popp conversation ID |
externalConversationId | string | Your external conversation reference (if provided at creation) |
externalCampaignId | string | Your external campaign reference (if provided at creation) |
campaignId | string | Popp campaign ID |
calendarMeetingTemplateId | string | The meeting template ID associated with this conversation |
Recommended Actions
When you receive this event, you should:
- Review the request - Check if additional availability can be provided
- Gather new availability - Collect updated time slots from the interviewers
- 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
Updated about 14 hours ago