OyeChats
FeaturesSolutionsIntegrationsPricingDocsBlogContact us

Webhook event reference

The five events OyeChats sends, and the exact contents of each one's `data` object.

The five events

EventDashboard labelFires when
tier_transitionLead qualifiedA conversation crosses a qualification tier boundary.
lead_capturedLead capturedA visitor submits contact details.
handoff_requestedHandoff requestedA visitor asks to speak to a human.
meeting_bookedMeeting bookedA visitor books a meeting through the widget.
chat_closedConversation closedAn operator closes or resolves a live conversation.
Subscribe narrowly. Select only the events you handle. An endpoint subscribed to everything gets retried on payloads it ignores, which makes your delivery log harder to read when something real breaks.

tier_transition

The event most integrations are built on. new_tier is one of unqualified, mql, sal, sql.

JSON
{
  "event": "tier_transition",
  "bot_id": 42,
  "timestamp": "2026-08-17T14:23:05.412000+00:00",
  "data": {
    "session_id": "session_8f3a2b1c",
    "old_tier": "mql",
    "new_tier": "sql",
    "score": 80,
    "behavioral_score": 15
  }
}
No contact details in this payload. This event carries scores and tiers only. To get the contact for the same conversation, either handle lead_captured as well or call GET /leads/{session_id} with the session_id from this payload.

lead_captured

JSON
{
  "event": "lead_captured",
  "bot_id": 42,
  "timestamp": "2026-08-17T14:19:44.108000+00:00",
  "data": {
    "session_id": "session_8f3a2b1c",
    "name": "Sarah Chen",
    "email": "sarah@acme.com",
    "phone": "+91 98765 43210",
    "company": "Acme"
  }
}

Fields the visitor did not supply arrive as null. Only session_id is guaranteed non-null.

handoff_requested

JSON
{
  "event": "handoff_requested",
  "bot_id": 42,
  "timestamp": "2026-08-17T14:21:02.771000+00:00",
  "data": {
    "session_id": "session_8f3a2b1c",
    "reason": "Wants to discuss enterprise pricing",
    "department_id": 3,
    "contact": {
      "name": "Sarah Chen",
      "email": "sarah@acme.com",
      "phone": "+91 98765 43210"
    }
  }
}

contact is present only if the conversation had already captured details. department_id is null when the visitor was not asked to choose a department.

meeting_booked

JSON
{
  "event": "meeting_booked",
  "bot_id": 42,
  "timestamp": "2026-08-17T14:31:19.004000+00:00",
  "data": {
    "session_id": "session_8f3a2b1c",
    "booking_url": "https://calendly.com/acme/intro/2026-08-20T10:00:00Z",
    "meeting_time": "2026-08-20T10:00:00+00:00",
    "attendee_email": "sarah@acme.com"
  }
}

chat_closed

JSON
{
  "event": "chat_closed",
  "bot_id": 42,
  "timestamp": "2026-08-17T14:40:55.220000+00:00",
  "data": {
    "session_id": "session_8f3a2b1c",
    "operator_id": 7,
    "resolution": "resolved"
  }
}

resolution is present with the value resolved when the operator ended the conversation outright, and absent when they closed it back to the chatbot. That difference is how you distinguish a finished conversation from one the visitor may continue.

Something here wrong or missing? Tell us and name this page. We will fix it.