---
title: "แค็ตตาล็อกเหตุการณ์"
description: "ประเภทเหตุการณ์ Webhook ทั้งหมดที่ ThunderPhone ส่งออก"
---

เนื้อหา webhook ทุกรายการมีฟิลด์ `type` ซึ่งมีค่าเป็นหนึ่งในประเภท
เหตุการณ์ในหน้านี้ เมื่อคุณสมัครรับข้อมูล
[ปลายทาง](/th/webhooks/endpoints) อาร์เรย์ `events` ต้องมี
ประเภทเหตุการณ์ที่คุณต้องการ (หรือเว้นว่างไว้เพื่อสมัครรับทุกเหตุการณ์ —
ยกเว้นเหตุการณ์รายเทิร์น [`telephony.turn`](#telephony-turn) /
[`web.turn`](#web-turn) ซึ่งจะส่งไปยังปลายทางที่ระบุชื่อเหตุการณ์เหล่านี้
โดยตรงเท่านั้น)

เหตุการณ์เหล่านี้ส่งผ่านได้สองรูปแบบ:

* **การส่งไปยังปลายทาง** เป็นการแจ้งเตือนแบบ **ไม่บล็อก** เสมอ
  พร้อม [การลองใหม่](/th/webhooks/overview): ตอบกลับด้วย
  2xx ใดก็ได้ ซองข้อมูลมี `event_id` สำหรับใช้กำจัดรายการซ้ำ
* การแลกเปลี่ยนแบบ **บล็อก** ทำงานเฉพาะบน
  [webhook URL เดียวแบบเดิม](/th/webhooks/overview): คำขอกำหนดค่า
  [`telephony.incoming` / `web.incoming`](/th/webhooks/call-incoming)
  (หมายเลขและคีย์วิดเจ็ตในโหมด webhook หมดเวลา 10 วินาที) และ
  [การส่งต่อเครื่องมือ](/th/tools/overview) ในโหมด
  webhook การตอบกลับของคุณกำหนดรูปแบบของสายสด

เพย์โหลดตัวอย่างด้านล่างแสดงซองข้อมูลปลายทางตามลำดับการส่งผ่าน
(คีย์เรียงตามตัวอักษร: `data`, `event_id`, `type`); การส่งแบบเดิมมี
`data` เดียวกันโดยไม่มี `event_id`

## เหตุการณ์การโทร

### `telephony.incoming`

ส่งเมื่อสายเรียกเข้าเข้าถึงหนึ่งใน
[หมายเลขโทรศัพท์](/api-reference/phone-numbers)ของคุณ การส่งไปยังปลายทางเป็นการแจ้งเตือนแบบส่งแล้วไม่ต้องรอผลสำหรับสายเรียกเข้าทุกสาย ไม่ว่าหมายเลขนั้นจะกำหนดค่าให้กับเอเจนต์หรือ webhook ก็ตาม หมายเลขที่ไม่ได้กำหนดเอเจนต์จะได้รับคำขอกำหนดค่าแบบ **บล็อกการทำงาน** บน legacy webhook เพิ่มเติม — ดู
[`telephony.incoming` / `web.incoming`](/th/webhooks/call-incoming)สำหรับสคีมาคำขอ / การตอบกลับฉบับเต็ม

```json
{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | จำนวนเต็ม \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | สตริง \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |

### `telephony.complete`

ส่งเมื่อการโทรผ่านระบบโทรศัพท์ขาเข้าหรือขาออกสิ้นสุดลง ไม่บล็อกการทำงาน
รวมถึงทรานสคริปต์ URL ของไฟล์บันทึกเสียงเมื่อมี และสรุปการเรียกเก็บเงิน ดู
[`telephony.complete` / `web.complete`](/th/webhooks/call-complete)สำหรับสคีมาเพย์โหลด

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | จำนวนเต็ม \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | สตริง \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |

### `telephony.tool`

ส่งหลังจากการโทรผ่านระบบโทรศัพท์เรียกใช้
[เครื่องมือฟังก์ชัน](/th/tools/overview) การแจ้งเตือนตรวจสอบแบบไม่บล็อกการทำงาน —
เครื่องมือได้ทำงานเสร็จแล้วเมื่อมีการส่งเหตุการณ์นี้ ครอบคลุมเครื่องมือฟังก์ชันของคุณเองเท่านั้น (ไม่รวมเครื่องมือในตัว เครื่องมือฐานความรู้ เครื่องมือการเชื่อมต่อแอป หรือเครื่องมือ MCP)

```json
{
  "data": {
    "arguments": { "date": "2026-04-21" },
    "call_id": 987654321,
    "from_number": "+14155550199",
    "response": {
      "response": { "available_slots": ["9:00 AM", "2:00 PM"] },
      "status": 200
    },
    "to_number": "+15551234567",
    "tool_name": "search_appointments"
  },
  "event_id": "1f0a7c3e-52d4-4a0e-8f4b-b1a6a1c0d9e2",
  "type": "telephony.tool"
}
```

`response`คือผลลัพธ์ที่ดำเนินการแล้ว: `{"status": <http status>,
"response": <your endpoint's JSON>}`เมื่อสำเร็จ หรือ
`{"status": <status>, "error": "<message>"}`เมื่อล้มเหลว

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | จำนวนเต็ม \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | สตริง \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |

### `telephony.turn`

ส่งระหว่างที่การโทรผ่านระบบโทรศัพท์ **กำลังดำเนินอยู่** หนึ่งครั้งสำหรับแต่ละเทิร์นที่มีเสียงพูดเมื่อเกิดขึ้น — คำตอบที่เอเจนต์พูดและเทิร์นที่ถอดเสียงของผู้โทร ช่วยให้คุณติดตามการสนทนาแบบสดผ่าน webhook ปกติแทนการทำ polling
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript)
ไม่บล็อกการทำงาน

<Note>
  **ต้องสมัครรับอย่างชัดเจน** ต่างจากเหตุการณ์ประเภทอื่นทั้งหมด เหตุการณ์เทิร์นจะไม่ถูกส่งผ่านอาร์เรย์ `events` ที่ว่างเปล่า (สมัครรับทั้งหมด) ปลายทางจะได้รับเหตุการณ์เหล่านี้ก็ต่อเมื่อรายการ `events` มี `telephony.turn` / `web.turn` อย่างชัดเจน
</Note>

```json
{
  "data": {
    "call_id": 987654321,
    "entry_type": "completion",
    "from_number": "+14155550199",
    "position": 7,
    "role": "assistant",
    "start_ms": 15200,
    "text": "How many employees does your company have?",
    "to_number": "+15551234567"
  },
  "event_id": "8d3f5a2c-7b1e-4c9a-b6d0-2e4f6a8c0d1e",
  "type": "telephony.turn"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | จำนวนเต็ม \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | สตริง \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `position` | จำนวนเต็ม | ดัชนีของเทิร์นในประวัติการโทร — เป็นตัวระบุที่คงที่สำหรับการเรียงลำดับ |
| `role` | สตริง | `assistant` (เสียงพูดของเอเจนต์) หรือ `user` (เสียงพูดของผู้โทร) |
| `text` | สตริง | ข้อความทรานสคริปต์ของเทิร์นตามที่ทราบ ณ เวลาที่ส่งออก |
| `entry_type` | สตริง | ประเภทของรายการประวัติพื้นฐาน: `completion` (เอเจนต์) หรือ `user_turn` / `span` (ผู้โทร) |
| `start_ms`, `end_ms` | จำนวนเต็ม | ออฟเซ็ตเสียงเป็น ms นับจากเริ่มสาย โดยจะแสดงเฉพาะเมื่อทราบจังหวะการเล่นเสียงแล้ว ณ เวลาที่ส่งออก |

<Note>
  การส่งเป็นแบบอย่างน้อยหนึ่งครั้ง และเทิร์นอาจมาถึง **ไม่เรียงลำดับ**:
  กำจัดข้อมูลซ้ำด้วย `event_id` ของ envelope และเรียงลำดับตาม `position` ทรานสคริปต์ของผู้โทรอาจยังได้รับการปรับปรุงหลังจากส่งออก ทรานสคริปต์
  [`telephony.complete`](/th/webhooks/call-complete)หลังจบสายถือเป็นข้อมูลอ้างอิง เฉพาะเทิร์นที่มีเสียงพูดเท่านั้นที่จะส่งออก — การเรียกใช้เครื่องมือ whisper และรายการภายในอื่น ๆ จะไม่ปรากฏในสตรีมนี้
</Note>

### `web.incoming`

เหตุการณ์เทียบเท่าของ `telephony.incoming` สำหรับช่องทางเว็บ ซึ่งส่งเมื่อเซสชัน
[วิดเจ็ตเว็บ](/th/widget/overview)หรือสายทดสอบไมโครโฟนในตัวสร้างเริ่มต้นขึ้น การส่งไปยังปลายทางเป็นแบบส่งแล้วไม่ต้องรอผลสำหรับทุกเซสชันเว็บ คีย์ที่เผยแพร่ได้ใน `mode="webhook"` จะได้รับคำขอกำหนดค่าแบบ **บล็อกการทำงาน** บน legacy webhook เพิ่มเติม — คำขอบล็อกการทำงานนั้นมีโครงสร้างแตกต่างกัน (`origin_domain`,
`publishable_key_prefix`; ไม่มีหมายเลขโทรศัพท์) ดู
[`telephony.incoming` / `web.incoming`](/th/webhooks/call-incoming)

```json
{
  "data": {
    "call_id": 987654322,
    "from_number": "web",
    "origin_domain": "https://example.com",
    "publishable_key_prefix": "pk_live_a1b2",
    "to_number": "+15551234567"
  },
  "event_id": "9a2b4c6d-8e0f-4a1b-9c2d-3e4f5a6b7c8d",
  "type": "web.incoming"
}
```

`from_number`จะเป็นค่าตามตัวอักษร `"web"` เสมอ สำหรับเซสชันวิดเจ็ตในโหมด webhook ค่า `to_number` จะว่างเปล่า (หมายเลขเอเจนต์ของเซสชันจะถูกกำหนดหลังการกำหนดค่า) สำหรับสายทดสอบไมโครโฟนในตัวสร้าง ค่า `origin_domain` และ `publishable_key_prefix` จะว่างเปล่า

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | จำนวนเต็ม \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | สตริง \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |

### `web.complete`

เหตุการณ์เทียบเท่าของ `telephony.complete` สำหรับช่องทางเว็บ ครอบคลุมการโทรจากวิดเจ็ตเว็บ (`direction: "web"`) และสายทดสอบไมโครโฟนในตัวสร้าง
(`direction: "test"`) ไม่บล็อกการทำงาน มีโครงสร้างเพย์โหลดเดียวกับ
[`telephony.complete`](/th/webhooks/call-complete)และเพิ่ม `origin_domain`
โดยกำหนด `from_number` เป็น `"web"`

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | จำนวนเต็ม \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | สตริง \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |

<Note>
  บน legacy webhook แบบ URL เดียว สายทดสอบไมโครโฟนในตัวสร้างมีรายงานเป็น `telephony.complete` มาโดยตลอด — มีเพียงสาย `direction:
  "web"` เท่านั้นที่ใช้ประเภท `web.complete` ที่นั่น ระบบปลายทางแมปทั้งสายเว็บและสายทดสอบไปยัง `web.*` เพย์โหลดในอดีตอาจมีค่า `direction` แบบเดิมคือ `widget` หรือ `mic`
</Note>

### `web.tool`

เหตุการณ์เทียบเท่าของ `telephony.tool` สำหรับช่องทางเว็บ `data` มี
`origin_domain` แทน `from_number` / `to_number`

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | จำนวนเต็ม \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | สตริง \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |

### `web.turn`

เหตุการณ์เทียบเท่าของ [`telephony.turn`](#telephony-turn) สำหรับช่องทางเว็บ ครอบคลุมการโทรจากวิดเจ็ตเว็บและสายทดสอบไมโครโฟนในตัวสร้าง มีโครงสร้างเพย์โหลดเดียวกัน โดยใช้ `origin_domain` แทน `from_number` / `to_number`
เช่นเดียวกับ `telephony.turn` จำเป็นต้องมี **การสมัครรับอย่างชัดเจน** —
จะไม่ถูกส่งผ่านอาร์เรย์ `events` ที่ว่างเปล่า

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | จำนวนเต็ม \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | สตริง \| null | เอเจนต์ที่จัดการสาย เมื่อมีการกำหนดเอเจนต์ |

---

## เหตุการณ์เสียง

การสร้างเสียงแบบกำหนดเองเป็นแบบอะซิงโครนัส เหตุการณ์แบบไม่บล็อกเหล่านี้ช่วยให้คุณตอบสนองต่อผลลัพธ์สุดท้ายได้โดยไม่ต้องโพล
[ปลายทางรายละเอียดโคลน](/api-reference/custom-voices#list-and-retrieve-clones)

`voice.ready` และ `voice.failed` จะส่งไปยังปลายทางระดับทั้งองค์กรที่มี `events: []` เท่านั้น ไม่สามารถเลือกเป็นตัวกรองเหตุการณ์แบบระบุชัดเจนได้

### `voice.ready`

ส่งเมื่อเสียงแบบกำหนดเองประมวลผลเสร็จและสามารถกำหนดให้กับเอเจนต์ได้

```json
{
  "data": {
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "ready",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "2d5f0a61-e9b5-4a3c-b684-29d7d9e4b214",
  "type": "voice.ready"
}
```

### `voice.failed`

ส่งเมื่อการประมวลผลเสียงแบบกำหนดเองล้มเหลวอย่างถาวร

```json
{
  "data": {
    "reason": "audio sample could not be processed",
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "audio sample could not be processed",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "failed",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "3493e985-1a75-4f77-a10a-e74af440cd31",
  "type": "voice.failed"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `voice.id` | สตริง | รหัสสาธารณะของเสียงแบบกำหนดเอง |
| `voice.name` | สตริง | ค่าของเสียงเอเจนต์ในรูปแบบ `custom:<public_id>` |
| `voice.display_name` | สตริง | ชื่อเสียงที่แสดงต่อองค์กร |
| `voice.language` | สตริง | รหัสภาษาภาษาเดียวของโคลน |
| `voice.gender` | สตริง | `male`, `female` หรือสตริงว่าง |
| `voice.status` | สตริง | `ready` สำหรับ `voice.ready`; `failed` สำหรับ `voice.failed` |
| `voice.failure_reason` | สตริง | ว่างเมื่อสำเร็จ; รายละเอียดการประมวลผลล้มเหลวเมื่อไม่สำเร็จ |
| `voice.created_at`, `voice.updated_at` | การประทับเวลา | การประทับเวลา ISO 8601 |
| `reason` | สตริง | รายละเอียดการล้มเหลว; มีเฉพาะใน `voice.failed` |

---

## เหตุการณ์ด้านคุณภาพ

### `call.graded`

ส่งเมื่อการ[ประเมินด้วย AI](/api-reference/calls#ai-call-grading)
สำหรับการโทรเสร็จสิ้น ไม่บล็อก

```json
{
  "data": {
    "call_id": 987654321,
    "grade": {
      "call_outcome": "success",
      "created_at": "2026-04-20T18:25:11.002Z",
      "detected_issues": [],
      "graded_at": "2026-04-20T18:25:11.002Z",
      "grader_model": "heuristic-v1",
      "id": 5512,
      "score": 92,
      "status": "completed",
      "summary": "Caller asked about their policy and got a full answer…"
    }
  },
  "event_id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "type": "call.graded"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | integer \| null | เอเจนต์ที่รับสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | string \| null | เอเจนต์ที่รับสาย เมื่อมีการกำหนดเอเจนต์ |
| `grade.id` | integer | รหัสการประเมิน |
| `grade.score` | integer \| null | 0–100 |
| `grade.call_outcome` | string | `success`, `failure`, `unknown` หรือ `no_conversation` |
| `grade.summary` | string | สรุปหนึ่งย่อหน้า |
| `grade.detected_issues` | array | สตริงปัญหาที่ตัวประเมินพบ |
| `grade.status` | string | เป็น `completed` เสมอ — เฉพาะการประมวลผลที่เสร็จสิ้นเท่านั้นที่ส่งออก |
| `grade.grader_model` | string | ตัวประเมินที่สร้างผลลัพธ์ (เช่น `heuristic-v1`) |
| `grade.graded_at`, `grade.created_at` | timestamp | |

<Note>
  การโทรหนึ่งรายการอาจได้รับการประเมินมากกว่าหนึ่งครั้ง — การประเมินแบบฮิวริสติกที่รวดเร็วมักตามด้วยการประเมินจากโมเดลแบบเต็มเมื่อมีไฟล์บันทึกเสียงพร้อมใช้งาน และสามารถประเมินใหม่ด้วยตนเองได้ การประมวลผลที่เสร็จสิ้นแต่ละครั้งจะส่งเหตุการณ์ `call.graded` ของตนเอง ให้ถือว่า `graded_at` ล่าสุดเป็นข้อมูลที่เชื่อถือได้
</Note>

### `call.data_extracted`

ส่งเมื่อการดึงข้อมูลแบบมีโครงสร้างเสร็จสมบูรณ์สำเร็จ รวมถึงการลองใหม่ภายหลังจาก `telephony.complete` / `web.complete` หรือการเรียกใช้ใหม่ด้วยตนเองผ่าน
[`POST /v1/calls/{call_id}/extract`](/api-reference/calls#run-data-extraction)
ไม่บล็อก

ในโหมดการดึงข้อมูลแบบบล็อก เหตุการณ์เสร็จสิ้นโดยปกติจะรอไม่เกินงบเวลาการดึงข้อมูล 75 วินาที หากกระบวนการเวิร์กเกอร์สำหรับการดึงข้อมูลสูญหาย การระบายงานปิดท้ายในระบบใช้งานจริง (ทุกห้านาที) จะปล่อยเหตุการณ์เสร็จสิ้นที่ `blocking_deadline_at` ผ่านกำหนดแล้ว ก่อนเริ่มความพยายามดึงข้อมูลครั้งถัดไป ความสำเร็จในภายหลังจะถูกส่งแยกต่างหากเป็นเหตุการณ์นี้

<Warning>
  ค่าที่ดึงออกมาเป็นการตีความบทสนทนาของโมเดล แต่ละค่าที่ไม่เป็น null จะมีข้อความอ้างอิง บทบาทของผู้พูด และดัชนีเทิร์นที่ใช้เป็นพื้นฐาน พร้อมแฟล็กการตรวจสอบระดับการประมวลผล ตรวจสอบผลลัพธ์ก่อนตัดสินใจที่เกี่ยวข้องกับเงิน ตัวตน หรือการเข้าถึง
</Warning>

```json
{
  "data": {
    "call_id": 987654321,
    "agent_id": 12,
    "agent_name": "Acme intake",
    "extracted_data": {
      "status": "completed",
      "fields": {
        "customer_name": "Alex Morgan",
        "appointment_date": "2026-04-23"
      },
      "evidence": {
        "customer_name": {
          "quote": "My name is Alex Morgan",
          "speaker_role": "caller",
          "turn_index": 4
        },
        "appointment_date": {
          "quote": "April 23 works for me",
          "speaker_role": "caller",
          "turn_index": 7
        }
      },
      "verification": "verified",
      "field_reasons": {},
      "schema_version": "92850758e231a3c95a..."
    },
    "extracted_at": "2026-04-20T18:25:11.002Z",
    "model": "gemini-2.5-flash"
  },
  "event_id": "4d79ef1d-c2b1-4ed6-85b8-8326bd2895ef",
  "type": "call.data_extracted"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | integer \| null | เอเจนต์ที่รับสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | string \| null | เอเจนต์ที่รับสาย เมื่อมีการกำหนดเอเจนต์ |
| `extracted_data.status` | string | เป็น `completed` เสมอสำหรับเหตุการณ์นี้ |
| `extracted_data.fields` | object | ค่าที่ระบุด้วยคีย์ฟิลด์การดึงข้อมูลที่กำหนดไว้ ค่าที่ไม่พร้อมใช้งานจะเป็น `null` |
| `extracted_data.evidence` | object | หลักฐานที่ระบุด้วยฟิลด์การดึงข้อมูล ค่าที่ไม่เป็น null มีข้อความอ้างอิงแบบตรงตัวที่ตรวจสอบโครงสร้างแล้ว (สูงสุด 1,000 อักขระ) `speaker_role` (`caller` หรือ `agent`) และ `turn_index` ข้อความอ้างอิงที่โมเดลส่งกลับมายาวกว่านี้จะถูกปฏิเสธแทนการตัดทอน และหลักฐานจะเป็น `null` ทุกครั้งที่ฟิลด์ของหลักฐานนั้นเป็น `null` |
| `extracted_data.verification` | string | เป็น `verified` เฉพาะเมื่อขั้นตอนตรวจสอบหลักฐานอิสระส่งคำตัดสินที่ถูกต้องเพียงหนึ่งรายการสำหรับทุกฟิลด์ตัวเลือก `unavailable` หมายถึงขั้นตอนนั้นล้มเหลว หมดเวลา มีงบไม่เพียงพอ หรือส่งผลลัพธ์ที่มีรูปแบบไม่ถูกต้องหรือไม่ครบถ้วน ขั้นตอนที่ไม่พร้อมใช้งานทั้งหมดจะคงค่าที่มีพื้นฐานจากโครงสร้างไว้สำหรับการตรวจสอบโดยลูกค้า สำหรับผลลัพธ์บางส่วน จะใช้คำตัดสินที่ถูกต้อง และล้างค่าเป็น null สำหรับตัวเลือกแต่ละรายการที่ไม่มีคำตัดสินที่ถูกต้องเพียงหนึ่งรายการ |
| `extracted_data.field_reasons` | object | เหตุผลที่ระบุด้วยฟิลด์ซึ่งถูกล้างค่าเป็น null โดยการยืนยันโครงสร้างหรือตัวตรวจสอบอิสระ |
| `extracted_data.schema_version` | string | แฮชของสคีมาฟิลด์แบบตรงตัวที่ใช้สำหรับการดึงข้อมูลนี้ |
| `extracted_at` | timestamp | เวลาเสร็จสิ้นในรูปแบบ ISO 8601 |
| `model` | string | โมเดลที่ใช้สำหรับการดึงข้อมูล |

### `campaign.completed`

ส่งหนึ่งครั้งเมื่อแคมเปญเปลี่ยนจาก `running` เป็น `completed` ไม่ว่ากำหนดการจะสิ้นสุดลงหรือผู้ติดต่อทั้งหมดเข้าสู่สถานะสิ้นสุดแล้ว การลองใหม่ของตัวรันจะไม่ส่งเหตุการณ์เพิ่มเติม เหตุการณ์วงจรชีวิตระดับองค์กรนี้ส่งไปยังปลายทางที่กำหนดขอบเขตระดับองค์กรเท่านั้น ไม่ส่งไปยังปลายทางที่กำหนดขอบเขตระดับเอเจนต์ ไม่บล็อก

```json
{
  "data": {
    "campaign_id": "3f6b2c9e-2a0d-4c63-b6d6-a708dc98f403",
    "name": "May win-back",
    "agent_id": 12,
    "status": "completed",
    "started_at": "2026-04-20T17:00:00Z",
    "completed_at": "2026-04-20T18:25:11Z",
    "counts": {
      "contacts_total": 150,
      "completed": 121,
      "failed": 11,
      "no_answer": 18,
      "remaining": 0
    }
  },
  "event_id": "8d8f52ce-6b46-423f-9dde-cea0b91ec135",
  "type": "campaign.completed"
}
```

จำนวนผลลัพธ์ทั้งสี่รายการไม่ทับซ้อนกันและรวมกันได้ `contacts_total`:
`completed` มีผู้ติดต่อที่สำเร็จ `no_answer` มีผู้ติดต่อที่ล้มเหลวหรือใช้ความพยายามครบแล้วในสถานะสิ้นสุด ซึ่งผลลัพธ์สุดท้ายคือไม่มีผู้รับสาย `failed` มีผู้ติดต่อที่ล้มเหลวหรือใช้ความพยายามครบแล้วในสถานะสิ้นสุดอื่นทั้งหมด และ `remaining` มีผู้ติดต่อที่รอดำเนินการ ถูกกำหนดเวลา หรือกำลังโทรอยู่ ผู้ติดต่อที่รอการลองใหม่จะเป็น `remaining` แม้ว่าความพยายามล่าสุดจะไม่มีผู้รับสายก็ตาม การโทรที่กำลังดำเนินอยู่จะถูกกระทบยอดก่อนสแนปช็อตการเสร็จสิ้นเพียงครั้งเดียว `started_at` คือเวลาเริ่มต้นแคมเปญที่กำหนดไว้ หรือเวลาสร้างแคมเปญเมื่อไม่ได้กำหนดเวลาเริ่มต้น

### `issue.reported`

ส่งเมื่อมีการสร้าง[รายงานปัญหา](/api-reference/issue-reports) —
ไม่ว่าจะส่งโดยผู้ใช้จากแดชบอร์ด (`source: "user"`) หรือสร้างโดยอัตโนมัติจากการประเมินการโทร (`source: "system"`) ไม่บล็อก

```json
{
  "data": {
    "call_id": 987654321,
    "issue_report": {
      "created_at": "2026-04-20T18:25:11.002Z",
      "description": "Five-second silence before responding to the main question.",
      "id": 4321,
      "severity": "warning",
      "source": "system",
      "status": "open",
      "title": "Agent paused too long"
    }
  },
  "event_id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
  "type": "issue.reported"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | integer \| null | เอเจนต์ที่รับสาย เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | string \| null | เอเจนต์ที่รับสาย เมื่อมีการกำหนดเอเจนต์ |
| `issue_report.severity` | string | `critical`, `warning` หรือ `info` |
| `issue_report.status` | string | `open` หรือ `resolved` |
| `issue_report.source` | string | `user` (ส่งจากแดชบอร์ด) หรือ `system` (สร้างโดยการประเมิน) |

<Note>
  การประเมินการโทรใหม่จะสร้างรายงานปัญหาที่ระบบสร้างขึ้นใหม่ ซึ่งจะส่ง `issue.reported` อีกครั้งสำหรับรายงานที่สร้างขึ้นใหม่ กำจัดรายการซ้ำด้วย `call_id` + `title` หากต้องการการแจ้งเตือนเพียงรายการเดียวต่อปัญหาต้นเหตุ
</Note>

### `issue.escalated`

ส่งเมื่อรูปแบบปัญหาถูกส่งไปยัง ThunderPhone เพื่อตรวจสอบโดยทีมงาน: หลังจาก
**รายงานไปยัง ThunderPhone** หรือเมื่อ Fix with AI ไม่สามารถยืนยันการแก้ไขฝั่งลูกค้าและส่งต่อปัญหาโดยอัตโนมัติ มีเพียงปลายทางระดับองค์กรเท่านั้นที่ได้รับเหตุการณ์นี้

```json
{
  "data": {
    "automatic": false,
    "cluster_id": "7ac2844c-2df0-4fa8-a560-7378da649e19",
    "escalation_id": "ec99f52b-c8c0-41dd-a4f2-dd8a07b10894",
    "status": "open"
  },
  "event_id": "d8f8f420-7a42-45ba-bcf1-b747f9bbecda",
  "type": "issue.escalated"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `automatic` | boolean | `true` สำหรับการยกระดับโดยอัตโนมัติ `false` สำหรับการยกระดับด้วยตนเอง |
| `cluster_id` | UUID | รูปแบบปัญหาที่ถูกยกระดับ |
| `escalation_id` | UUID | ระเบียนการยกระดับ |
| `status` | string | `open` เมื่อส่งเหตุการณ์ |

นี่คือการแจ้งเตือน ไม่ใช่ชุดหลักฐาน ใช้ `cluster_id` เพื่อเชื่อมโยงกับรูปแบบปัญหา ดู[รายงานไปยัง ThunderPhone](/th/guides/issues)

---

## เหตุการณ์การโทรทดสอบ

### `test-call.completed`

ส่งเมื่อ
[การรันการโทรทดสอบ](/api-reference/test-calls#test-call-run-object)
ถึงสถานะสุดท้าย — `completed` หรือ `failed` รวมถึงการรัน
ที่ล้มเหลวตั้งแต่เริ่มต้นและไม่เคยสร้างการโทร ไม่บล็อกการทำงาน มีประโยชน์
สำหรับเชื่อมต่อการรัน CI แบบแบตช์เข้ากับระบบแชต/การแจ้งเตือนของคุณ

```json
{
  "data": {
    "test_call_run": {
      "call_id": 987654321,
      "completed_at": "2026-04-20T18:25:04.822Z",
      "error_message": "",
      "id": 7110,
      "status": "completed",
      "target_id": 12,
      "target_type": "agent"
    }
  },
  "event_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
  "type": "test-call.completed"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `agent_id` | integer \| null | เอเจนต์ที่จัดการการโทร เมื่อมีการกำหนดเอเจนต์ |
| `agent_name` | string \| null | เอเจนต์ที่จัดการการโทร เมื่อมีการกำหนดเอเจนต์ |
| `test_call_run.target_type` | string | `agent` หรือ `phone_number` |
| `test_call_run.target_id` | integer | ID เอเจนต์หรือ ID หมายเลขโทรศัพท์ที่การรันกำหนดเป้าหมาย โดยตรงกับ `target_type` |
| `test_call_run.status` | string | `completed` หรือ `failed` |
| `test_call_run.call_id` | integer \| null | เป็น `null` เมื่อการรันล้มเหลวก่อนมีการโทรออก |
| `test_call_run.error_message` | string | ว่างเปล่าเมื่อสำเร็จ |

---

## เหตุการณ์การแจ้งเตือน

### `alert.triggered`

ส่งเมื่อ [กฎการแจ้งเตือน](/th/guides/alerts) ที่เปิดใช้ช่องทาง **ส่งไปยัง
เว็บฮุกของนักพัฒนา** มีค่าถึงเกณฑ์ที่กำหนด ไม่บล็อกการทำงาน กฎจะทริกเกอร์
หนึ่งครั้งแล้วจึงเป็นไปตามช่วงพักของกฎ ดังนั้นการเกินเกณฑ์อย่างต่อเนื่อง
จะสร้างหนึ่งเหตุการณ์ต่อหนึ่งช่วงพัก

```json
{
  "data": {
    "comparator": "lt",
    "event_id": "b8e6a1d4-2c3f-4a5b-9c8d-7e6f5a4b3c2d",
    "fired_at": "2026-04-20T18:00:00+00:00",
    "metric": "success_rate",
    "metric_value": 71.4,
    "rule_id": "d2c3b4a5-6f7e-4d8c-9b0a-1c2d3e4f5a6b",
    "rule_name": "Success rate below 80%",
    "threshold": 80.0,
    "window_hours": 24
  },
  "event_id": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f7a",
  "type": "alert.triggered"
}
```

| ฟิลด์ | ประเภท | คำอธิบาย |
|-------|------|-------------|
| `event_id` (ใน `data`) | UUID | ID **การทริกเกอร์** ของการแจ้งเตือน — แตกต่างจาก `event_id` สำหรับการส่งของเอนเวโลป |
| `rule_id`, `rule_name` | UUID, string | กฎที่ทริกเกอร์ |
| `metric` | string | `success_rate`, `failure_rate`, `avg_score`, `call_volume` หรือ `suite_regression` |
| `comparator` | string | `lt`, `lte`, `gt` หรือ `gte` |
| `metric_value` | number | ค่าของเมตริกภายในช่วงเวลาขณะที่กฎทริกเกอร์ |
| `threshold` | number | เกณฑ์ที่กำหนดค่าไว้ |
| `window_hours` | integer | ช่วงเวลาประเมินย้อนหลัง |
| `fired_at` | timestamp | |

ดู[คู่มือการแจ้งเตือน](/th/guides/alerts) สำหรับการสร้างกฎ เมตริก
ช่วงพัก และช่องทางอีเมล / Slack

---

## ที่เกี่ยวข้อง

<CardGroup cols={2}>
  <Card title="telephony.incoming / web.incoming" icon="phone" href="/th/webhooks/call-incoming">
    เพย์โหลดสายเรียกเข้าที่บล็อกการทำงานและคุณต้องตอบกลับ
  </Card>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/th/webhooks/call-complete">
    ทรานสคริปต์และเมตริกหลังการโทร
  </Card>
  <Card title="ปลายทางเว็บฮุก" icon="bolt" href="/th/webhooks/endpoints">
    สมัครใช้ URL กับชุดย่อยของเหตุการณ์เหล่านี้
  </Card>
  <Card title="เครื่องมือฟังก์ชัน" icon="screwdriver-wrench" href="/th/tools/overview">
    วิธีสร้างเหตุการณ์ `telephony.tool` / `web.tool`
  </Card>
</CardGroup>
