> ## Documentation Index
> Fetch the complete documentation index at: https://docs.antler.qode.world/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Events

> Define conversation events

## Overview

This document defines the **event model**.

<Info>
  All events in this document are **append-only**, immutable, and ordered by timestamp.
</Info>

***

## 🔔 Webhook vs Internal Events (IMPORTANT)

Not all events are sent to Antler.

We separate events into **two categories**:

### 1️⃣ Webhook Events (Sent to Antler)

Only the following events are pushed to the **Antler webhook**.

| event              | when it fires                                  | payload                       |
| ------------------ | ---------------------------------------------- | ----------------------------- |
| `submit_form`      | Founder submits application + pitch deck       | Founder & pitch deck metadata |
| `report_generated` | Conversation completed and report is generated | Full conversation payload     |

These events are **business-critical** and power Antler's downstream workflows.

***

### 2️⃣ Internal Events (Tracking & Monitoring Only)

All other events are **NOT sent** to Antler.

They are used internally for:

* Funnel tracking
* Debugging
* Reliability monitoring
* Conversation analytics

Examples:
`create_attempt`, `link_opened`, `candidate_ready`, `tracy_joined`, `face_detected`, `speech_detected`, etc.

***

## Webhook Payloads

Only the following events will be sent to **Antler Webhook**.

***

### Event: `submit_form`

Triggered when the founder submits the pitch deck.

```json theme={null}
{
  "event_name": "submit_form",
  "timestamp": "2025-12-09T14:10:00Z",
  "founder_first_name": "John",
  "founder_last_name": "Smith",
  "founder_name": "John Smith",
  "founder_email": "founder@startup.com",
  "founder_phone": "+84901234567",
  "founder_role": "CEO",
  "founder_linkedin": "https://linkedin.com/in/founder",
  "founder_current_location": "Ho Chi Minh City, Vietnam",
  "co_founders": {
    "co_founder_1": {
      "co_founder_first_name": "Jane",
      "co_founder_last_name": "Doe",
      "co_founder_role": "CTO",
      "co_founder_email": "jane@startup.com",
      "co_founder_linkedin": "https://linkedin.com/in/janedoe",
      "co_founder_phone": "+84901234568"
    },
    "co_founder_2": {
      "co_founder_first_name": "Alex",
      "co_founder_last_name": "Lee",
      "co_founder_role": "COO",
      "co_founder_email": "alex@startup.com",
      "co_founder_linkedin": "https://linkedin.com/in/alexlee",
      "co_founder_phone": "+84901234569"
    }
  },
  "tokenized_link": "https://antler.qode.world/interview/abc123",
  "pitch_deck_url": "https://storage.qode.ai/pitchdeck.pdf",
  "cohort": "SEA-AI-3"
}
```

<Note>
  The `co_founders` field is a dynamic object where each key (`co_founder_1`, `co_founder_2`, ...) represents a co-founder. Each co-founder object contains: `co_founder_first_name`, `co_founder_last_name`, `co_founder_role`, `co_founder_email`, `co_founder_linkedin`, and `co_founder_phone`. This field is `null` if no co-founders are provided.
</Note>

***

### Event: `report_generated`

Triggered when the interview is completed and the report is ready.

```json theme={null}
{
  "event_name": "report_generated",
  "founder_email": "founder@startup.com",
  "conversation_id": "uuid",
  "cohort": "SEA-AI-3",
  "timestamp": "2025-12-09T14:46:59Z",
  "conversation_data": {
    "conversation_id": "uuid",
    "date": "2025-12-09T14:00:00.000Z",
    "founder_first_name": "John",
    "founder_last_name": "Smith",
    "founder_name": "John Smith",
    "founder_email": "founder@startup.com",
    "founder_role": "CEO",
    "founder_phone": "+84901234567",
    "founder_linkedin": "https://linkedin.com/in/founder",
    "founder_current_location": "Ho Chi Minh City, Vietnam",
    "co_founders": {
      "co_founder_1": {
        "co_founder_first_name": "Jane",
        "co_founder_last_name": "Doe",
        "co_founder_role": "CTO",
        "co_founder_email": "jane@startup.com",
        "co_founder_linkedin": "https://linkedin.com/in/janedoe",
        "co_founder_phone": "+84901234568"
      },
      "co_founder_2": {
        "co_founder_first_name": "Alex",
        "co_founder_last_name": "Lee",
        "co_founder_role": "COO",
        "co_founder_email": "alex@startup.com",
        "co_founder_linkedin": "https://linkedin.com/in/alexlee",
        "co_founder_phone": "+84901234569"
      }
    },
    "tokenized_link": "https://antler.qode.world/interview/abc123",
    "cohort": "SEA-AI-3",
    "source": "Antler",
    "status": "COMPLETED",
    "ps_summary": "...",
    "cap_table": "...",
    "pitch_deck": "https://example.com/deck.pdf",
    "elevator_pitch": "...",
    "problem": "...",
    "solution": "...",
    "traction": "...",
    "commercial": "...",
    "market_size": "...",
    "why_now": "...",
    "competition": "...",
    "why_you": "...",
    "why_antler": "...",
    "fundraising_status": "...",
    "availability": "...",
    "passport_and_visa": "...",
    "video_url": "https://cdn.example.com/video.mp4",
    "transcript": "Tracy: Welcome!...\nFounder: Thanks..."
  }
}
```

This payload contains the **entire conversation output**, allowing Antler to:

* Run evaluation pipelines
* Store records
* Trigger investment or screening workflows

***

## Field Definitions

### Core Identifiers

* **`conversation_id`**
  Unique identifier for the conversation (unique for each attempt). Create a new `conversation_id` if the founder retries again.

* **`founder_email`**
  Founder email address used for identification and notifications.

***

### Event Metadata

* **`event_name`**
  Canonical event name emitted by Qode
  (example: `submit_form`, `report_generated`).

* **`timestamp`**
  UTC timestamp indicating when the event occurred.

***

### Co-founders

The `co_founders` field is a dynamic object supporting **multiple co-founders**. Each co-founder is keyed as `co_founder_1`, `co_founder_2`, etc.

Each co-founder object contains:

| field                   | type   | description                |
| ----------------------- | ------ | -------------------------- |
| `co_founder_first_name` | string | First name of co-founder   |
| `co_founder_last_name`  | string | Last name of co-founder    |
| `co_founder_role`       | string | Role of co-founder         |
| `co_founder_email`      | string | Email of co-founder        |
| `co_founder_linkedin`   | string | LinkedIn URL of co-founder |
| `co_founder_phone`      | string | Phone number of co-founder |

***

## Canonical Event Model

Each row represents a **canonical event** emitted during the conversation lifecycle.

| event                   | description                                          | sent to Antler |
| ----------------------- | ---------------------------------------------------- | -------------- |
| `submit_form`           | Founder uploads a pitch deck and submits a form      | ✅ Yes          |
| `create_interview_link` | Returns a unique conversation link                   | ❌ No           |
| `link_opened`           | Candidate opens the conversation link                | ❌ No           |
| `create_attempt`        | A new attempt starts                                 | ❌ No           |
| `tracy_joined`          | AI interviewer joins the room                        | ❌ No           |
| `camera_permission`     | Camera permission requested, granted, or blocked     | ❌ No           |
| `mic_permission`        | Microphone permission requested, granted, or blocked | ❌ No           |
| `has_speaker_device`    | Speaker device detected                              | ❌ No           |
| `has_camera_device`     | Camera detected                                      | ❌ No           |
| `has_mic_device`        | Microphone detected                                  | ❌ No           |
| `device_check_passed`   | All device permissions granted                       | ❌ No           |
| `device_check_failed`   | Device check failed (missing permissions or devices) | ❌ No           |
| `candidate_ready`       | Candidate clicks Start                               | ❌ No           |
| `face_detected`         | Face detection status update                         | ❌ No           |
| `speech_detected`       | Speech detection / warm-up status                    | ❌ No           |
| `first_question`        | First interview question begins                      | ❌ No           |
| `candidate_end`         | Candidate finishes the interview                     | ❌ No           |
| `attempt_end`           | Tracy ends the interview                             | ❌ No           |
| `tracy_left`            | Tracy leaves the room                                | ❌ No           |
| `abandon`               | Candidate abandons the interview                     | ❌ No           |
| `expire`                | Interview session expires (timeout)                  | ❌ No           |
| `connection_failure`    | Connection failure detected                          | ❌ No           |
| `skip_generate_report`  | Report generation skipped                            | ❌ No           |
| `report_generated`      | Interview completed, report generated                | ✅ Yes          |
