Conversation Events

Conversation Events

Conversation events notify you about the lifecycle of conversations in your campaigns.

Available Events

EventDescription
CONVERSATION_QUEUEDConversation is queued and waiting to start
CONVERSATION_STARTEDConversation has started with the candidate
CONVERSATION_COMPLETEDConversation completed successfully
CONVERSATION_NEEDS_REVIEWConversation requires manual review
CONVERSATION_OPTED_OUTCandidate opted out of the conversation
START_CONVERSATION_FAILEDFailed to start the conversation

CONVERSATION_STARTED

Triggered when the first message is successfully delivered to the candidate.

Payload

{
  "event": "CONVERSATION_STARTED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_xyz789",
    "organizationId": "org_123456",
    "conversationStatus": "ONGOING",
    "candidateId": "cand_abc123",
    "externalId": "your_external_id",
    "externalCampaignId": "your_campaign_external_id",
    "participantFirstName": "John",
    "participantLastName": "Doe",
    "campaignConversationUrl": "https://ai.joinpopp.com/campaign/outbound/{campaignId}?conversationId={conversationId}"
  }
}

Data Fields

FieldTypeDescription
conversationStatusstringCurrent status of the conversation (e.g., ONGOING)
candidateIdstringPopp internal candidate ID
externalIdstringYour external reference ID for the conversation
externalCampaignIdstringYour external reference ID for the campaign
participantFirstNamestringCandidate's first name
participantLastNamestringCandidate's last name
campaignConversationUrlstringDirect link to view the conversation in Popp AI

CONVERSATION_COMPLETED

Triggered when a conversation reaches a successful conclusion.

Payload

{
  "event": "CONVERSATION_COMPLETED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_xyz789",
    "organizationId": "org_123456",
    "conversationStatus": "COMPLETED_SCREENING_PASSED",
    "scorecardTotalValue": 85,
    "screeningQuestionsOutcome": [
      {
        "screeningQuestion": "Do you have 5+ years of experience?",
        "responseSummary": "Yes, I have 7 years of experience",
        "questionOutcome": "PASSED"
      },
      {
        "screeningQuestion": "Are you authorized to work in the US?",
        "responseSummary": "No, I would need visa sponsorship",
        "questionOutcome": "FAILED"
      },
      {
        "screeningQuestion": "Are you willing to relocate?",
        "responseSummary": null,
        "questionOutcome": "NOT_COMPLETED"
      }
    ],
    "candidateId": "cand_abc123",
    "externalId": "your_external_id",
    "externalCampaignId": "your_campaign_external_id",
    "participantFirstName": "John",
    "participantLastName": "Doe",
    "campaignConversationUrl": "https://ai.joinpopp.com/campaign/outbound/{campaignId}?conversationId={conversationId}"
  }
}

Additional Data Fields

FieldTypeDescription
conversationStatusstringFinal status (COMPLETED_SCREENING_PASSED, COMPLETED_SCREENING_FAILED, COMPLETED_CANDIDATE_NOT_INTERESTED)
scorecardTotalValuenumberTotal score from screening questions (0-100)
screeningQuestionsOutcomearrayArray of screening question results

Screening Question Outcome Object

FieldTypeDescription
screeningQuestionstringThe screening question asked
responseSummarystringSummary of the candidate's response
questionOutcomestringOutcome of the question (PASSED, FAILED, NOT_COMPLETED)

CONVERSATION_NEEDS_REVIEW

Triggered when the AI determines the conversation requires human review.

Payload

{
  "event": "CONVERSATION_NEEDS_REVIEW",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_xyz789",
    "organizationId": "org_123456",
    "externalId": "your_external_id",
    "externalCampaignId": "your_campaign_external_id",
    "campaignConversationUrl": "https://ai.joinpopp.com/campaign/outbound/{campaignId}?conversationId={conversationId}"
  }
}

Common Reasons for Review

  • Candidate asked a question the AI couldn't answer
  • Sensitive topic detected
  • Candidate expressed concerns or complaints
  • Ambiguous candidate response

CONVERSATION_OPTED_OUT

Triggered when a candidate opts out of receiving messages.

Payload

{
  "event": "CONVERSATION_OPTED_OUT",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_xyz789",
    "organizationId": "org_123456",
    "campaignConversationUrl": "https://ai.joinpopp.com/campaign/outbound/{campaignId}?conversationId={conversationId}"
  }
}

CONVERSATION_QUEUED

Triggered when a conversation is created but waiting to start (e.g., there's already an ongoing conversation with the same participant).

Payload

{
  "event": "CONVERSATION_QUEUED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_xyz789",
    "organizationId": "org_123456",
    "campaignConversationUrl": "https://ai.joinpopp.com/campaign/outbound/{campaignId}?conversationId={conversationId}"
  }
}

START_CONVERSATION_FAILED

Triggered when a conversation fails to start.

Payload

{
  "event": "START_CONVERSATION_FAILED",
  "eventId": "evt_abc123",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_xyz789",
    "organizationId": "org_123456",
    "campaignConversationUrl": "https://ai.joinpopp.com/campaign/outbound/{campaignId}?conversationId={conversationId}"
  }
}

Common Failure Reasons

  • Invalid phone number format
  • Phone number not reachable
  • Message delivery failed

Example: Handling Conversation Events

interface ConversationWebhookData {
  recordId: string;
  organizationId: string;
  conversationStatus?: string;
  scorecardTotalValue?: number;
  screeningQuestionsOutcome?: {
    screeningQuestion: string;
    responseSummary: string;
    questionOutcome: 'PASSED' | 'FAILED' | 'NOT_COMPLETED';
  }[];
  candidateId?: string;
  externalId?: string;
  externalCampaignId?: string;
  participantFirstName?: string;
  participantLastName?: string;
  campaignConversationUrl?: string;
}

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

  switch (event) {
    case 'CONVERSATION_STARTED':
      // Update your CRM to show conversation is active
      updateCandidateStatus(data.recordId, 'in_progress');
      break;

    case 'CONVERSATION_COMPLETED':
      // Process screening results
      if (data.scorecardTotalValue && data.scorecardTotalValue >= 70) {
        moveToNextStage(data.externalId);
      }
      break;

    case 'CONVERSATION_NEEDS_REVIEW':
      // Alert your team for manual review
      notifyRecruiters(data.campaignConversationUrl);
      break;

    case 'CONVERSATION_OPTED_OUT':
      // Update opt-out status in your system
      markAsOptedOut(data.recordId);
      break;
  }
}