Skip to main content
conversation.started This event is triggered when a new conversation is started, regardless of the channel.
{
  event: 'conversation.started';
  organization_id: string;
  data: {
    conversation_id: string;
    assignee:
    | {
      type: 'AI';
      name: string;
    }
    | {
      id: string;
      type: 'human';
      name: string;
      avatar_url: string;
    };
    contact: {
      id?: string;
      name?: string;
      enriched_data?: {
        address?: string | null;
        phone_number?: string;
        email?: string;
      };
      custom_data?: object;
    };
    channel: 'web' | 'email' | 'phone';
    first_message: string;
    timestamp: string;
  };
}

conversation.closed This event is triggered when a conversation is closed, a conversation can be marked as resolved or not resolved, and can be closed by a human or an AI.
{
    event: "conversation.closed";
    organization_id: string;
    data: {
        conversation_id?: string;
        timestamp: string;
        contact_id?: string;
        contact?: {
          id: string;
          name?: string;
          email?: string;
          phone_number?: string;
          custom_data?: object;
        };
        human_resolution_status: "resolved" | "not_resolved" | null;
        ai_resolution_status: string | null; 
        ai_billing_tier: string | null; 
        closed_by:
        | {
            type: "AI";
            name: string;
        }
        | {
            id: number;
            type: "human";
            email: string;
        }
        | {
            type: "workflow";
            id: string;
        }
        | {
            type: "contact";
            id: string;
        };
        is_from_third_party: boolean;
        third_party_name: "dynamics365" | "freshchat" | "freshdesk" | "gorgias" | "hubspot" | "intercom" | "open" | "salesforce" | "twilio_flex" | "zendesk" | "zendesk_v2" | null;
        summary: string | null | undefined;
        contact_reason: string | null | undefined;
        user_sentiment: string | null | undefined;
        language: string | null | undefined;
    }[];
}

conversation.handoff_to_human This event is triggered when a conversation is handed off to a human agent. Note that a handoff event can happen for multiple reasons; for example, a human agent might decide to take over the conversation, or the AI might decide to hand off the conversation to a human agent.
{
    event: "conversation.handoff_to_human";
    organization_id: string;
    data: {
        conversation_id: string | null | undefined;
        timestamp: string;
        contact?: {
          id: string;
          name?: string;
          email?: string;
          phone_number?: string;
          custom_data?: object;
        };
        reason:
        | "ai_decided_to_handoff_the_conversation" 
        | "ai_is_forbidden_from_handling_this_topic" 
        | "human_agent_decided_to_take_over"
        | "human_agent_decided_forced_handoff"
        | "ai_decided_to_auto_handoff_the_issue";
        summary: string;
        contact_reason?: string;
        user_sentiment?: string;
        was_handedoff_to_third_party?: boolean;
        during_work_hours?: boolean;
        third_party_name?: "dynamics365" | "freshchat" | "freshdesk" | "gorgias" | "hubspot" | "intercom" | "open" | "salesforce" | "twilio_flex" | "zendesk" | "zendesk_v2" | null;
        message_count: number;
        language: string;
        integration_metadata?: {
           sunshine?: {
             sunshine_conversation_id: string;
           };
        };
    }[];
}
conversation.contact_response When a contact sends a message to your inbox.
{
  event: 'conversation.contact_response';
  organization_id: string;
  data: {
    conversation_id: string;
    timestamp: string;
    response: string;
    channel: 'web' | 'email' | 'phone_voice' | 'slack' | 'sms' | 'whatsapp' | 'instagram' | 'messenger' | 'api' | 'web_voice';
    custom_data?: Record<string, unknown> | null | undefined;
  }
}
conversation.ai_response When an AI responds to a contact message,
{
  event: 'conversation.ai_response';
  organization_id: string;
  data: {
    conversation_id: string;
    timestamp: string;
    response: string;
    contact: {
      id: string;
      name?: string;
      email?: string;
      phone_number?: string;
      custom_data?: object;
    };
    channel: 'web' | 'email' | 'phone_voice' | 'slack' | 'sms' | 'whatsapp' | 'instagram' | 'messenger' | 'api' | 'web_voice';
  }
}

conversation.agent_response When a human agent responds from the Open inbox,
{
  event: 'conversation.agent_response';
  organization_id: string;
  data: {
    conversation_id: string;
    timestamp: string;
    customer_id?: string;
    response: string;
    channel: 'web' | 'email' | 'phone_voice' | 'slack' | 'sms' | 'whatsapp' | 'instagram' | 'messenger' | 'api' | 'web_voice';
  }
}
conversation.third_party_agent_response When a third-party software agent responds to a previously handed-off conversation, Open will notify you. In some configurations, Open might also initiate the handoff to a third-party agent, such as Zendesk or Intercom. Even while the third-party agent handles the conversation, Open continues to monitor and send events to your webhooks.
{
  event: 'conversation.third_party_agent_response';
  organization_id: string;
  data: {
    conversation_id: string | null | undefined;
    timestamp: string;
    contact?: {
      id: string;
      name?: string;
      email?: string;
      phone_number?: string;
      custom_data?: object;
    };
    third_party_name: 'dynamics365' | 'freshchat' | 'freshdesk' | 'gorgias' | 'hubspot' | 'intercom' | 'open' | 'salesforce' | 'twilio_flex' | 'zendesk' | 'zendesk_v2';
    response: string;
    message_count: number;
    language: string;
    channel: 'web' | 'email' | 'phone_voice' | 'slack' | 'sms' | 'whatsapp' | 'instagram' | 'messenger' | 'api' | 'web_voice';
    agent: {
      name?: string;
    };
    attachments?: Array<{ mime_type: string; url: string; file_name?: string }>;
  }
}