Skip to content

โทรออก ​

การโทรแต่ละแบบมี endpoint ของตัวเอง เลือกตามสิ่งที่ต้องการให้เกิดขึ้นเมื่อปลายสายรับ

แบบRouteเมื่อปลายสายรับผลตอบกลับ
DialPOST /telephony/call/dialไม่มีเสียงเล่น ใช้สายนี้เพื่อพักหรือโอนต่อ202 queued
TTSPOST /telephony/call/ttsอ่านข้อความ แล้ววางสาย202 queued
AgentPOST /telephony/call/agentAI agent คุยกับปลายสาย201 ringing
SurveyPOST /telephony/call/surveyถามคำถามและส่งคำตอบกลับมาให้คุณ202 หรือ 201
FlowPOST /telephony/call/flowยังใช้ไม่ได้ — สายดัง แต่ยังไม่รัน flow201 ringing
BatchPOST /telephony/call/batchโทรแบบ TTS หรือ dial หนึ่งสายต่อหนึ่งเบอร์202 queued

ติดตามทุกสายได้ด้วย GET /telephony/call/{call_uuid}

API key ต้องมีสิทธิ์ voice.originate ส่วนการโทรหาเบอร์ต่อภายใน (POST /telephony/call/extension) ต้องใช้ผู้ใช้ที่ลงชื่อเข้าใช้ เพราะ API key ไม่มีเครื่องโทรศัพท์ให้ดัง

แต่ละ endpoint รับเฉพาะฟิลด์ของตัวเอง

ฟิลด์ของการโทรแบบอื่นจะถูกปฏิเสธด้วย 400 พร้อมบอก endpoint ที่ถูกต้อง เช่น survey belongs to POST /telephony/call/surveyPOST /telephony/call แบบเดิมยังใช้กับ dial, TTS, agent, flow และ extension ได้ แต่เลิกแนะนำแล้ว และทำแบบสำรวจไม่ได้

โทรหาใคร และโทรจากเบอร์ไหน ​

การโทรหาเบอร์ทุกแบบใช้ฟิลด์ปลายทางชุดเดียวกัน

ฟิลด์ชนิดหมายเหตุ
destinationstringจำเป็น เบอร์ที่จะโทร ในรูปแบบ E.164 (+66812345678)
caller_idstringไม่บังคับ เบอร์ของคุณที่จะแสดงให้ปลายสายเห็น
caller_identity_idstringไม่บังคับ ใช้ caller identity ที่บันทึกไว้แทน caller_id
caller_extension_uuidstringไม่บังคับ โทรออกในนามเบอร์ของ extension นี้
trunkstringไม่บังคับ บังคับใช้ trunk ที่ระบุ
organization_idstringใช้เมื่อเรียกด้วย token ของผู้ใช้เท่านั้น API key ระบุองค์กรอยู่แล้ว

Dial, TTS และ batch รับ mode ได้ด้วย: "queue" (ค่าเริ่มต้น) รอจนมีสายว่าง ส่วน "instant" โทรทันที หรือตอบ 429 เมื่อไม่มีสายว่าง

ลองใหม่อย่างปลอดภัยด้วย Idempotency-Key ​

ส่ง header Idempotency-Key ทุกครั้งที่โทรออก หากส่งซ้ำด้วย key เดิม ระบบจะคืนสายแรกแทนการโทรหาปลายสายซ้ำ SDK ทางการส่ง key ให้อัตโนมัติ และใช้ key เดิมเมื่อ SDK ลองใหม่เอง

bash
curl -X POST "$ME_BASE/telephony/call/tts" \
  -H "API-Key: $ME_API_KEY" \
  -H "X-TenantID: $ME_TENANT" \
  -H "Idempotency-Key: order-1042-reminder" \
  -H "Content-Type: application/json" \
  -d '{
    "destination": "+66812345678",
    "tts": { "text": "คำสั่งซื้อ 1042 กำลังนำส่ง", "voice_id": "eve", "language": "th" }
  }'
json
{
  "kind": "pstn",
  "call": { "call_uuid": "5d2c…", "destination": "+66812345678", "status": "queued" }
}

tts รับ text และ voice_id และรับ provider, language และ repeat (จำนวนครั้งที่เล่น 0 คือเล่นครั้งเดียว) ได้ด้วย

ต่อสายให้ AI agent ​

json
{
  "destination": "+66812345678",
  "agent": { "id": "agent_support_th" },
  "gather": {
    "parameters": {
      "type": "object",
      "properties": { "order_id": { "type": "string" } },
      "required": ["order_id"]
    },
    "callback_url": "https://example.com/hooks/order"
  }
}

agent.id คือ agent ที่บันทึกไว้ (ใส่ config_mode: "draft" เพื่อใช้ฉบับร่าง) ส่วน system_prompt, voice และ language ใช้แทนค่าของ agent เฉพาะสายนี้ gather ไม่บังคับ agent จะถามข้อมูลตาม parameters แล้วส่งคำตอบกลับมา ดู รับคำตอบ

ทำแบบสำรวจ ​

แบบสำรวจจะโทรหาเบอร์ ถามคำถามของคุณ แล้วส่งคำตอบกลับมา ทำได้สองแบบ

กดปุ่ม ("mode": "dtmf") ​

ระบบอ่านคำถามทีละข้อ แล้วปลายสายตอบด้วยการกดปุ่มหนึ่งปุ่ม

json
{
  "destination": "+66812345678",
  "survey": {
    "mode": "dtmf",
    "survey_id": "csat_q3",
    "greeting": "ขอบคุณที่ใช้บริการค่ะ",
    "questions": [
      { "key": "score", "prompt": "พึงพอใจแค่ไหน กด 1 ถึง 5", "min": 1, "max": 5 },
      { "key": "would_return", "prompt": "จะกลับมาใช้บริการอีกไหม กด 1 ไม่ กด 2 ใช่", "min": 1, "max": 2, "required": false }
    ],
    "retry_prompt": "กดได้ตั้งแต่ {min} ถึง {max} กดใหม่อีกครั้ง",
    "closing": "ขอบคุณค่ะ สวัสดีค่ะ",
    "tts": { "provider": "xai", "voice_id": "eve", "language": "th" },
    "callback_url": "https://example.com/hooks/survey"
  }
}
ฟิลด์หมายเหตุ
questionsจำเป็น สูงสุด 20 ข้อ ถามตามลำดับ แต่ละข้อรับปุ่มเดียวระหว่าง min ถึง max (0–9)
keyตัวพิมพ์เล็ก ตัวเลข และ _ ขึ้นต้นด้วยตัวอักษร ใช้เป็นชื่อของคำตอบ
requiredค่าเริ่มต้น true ถ้าข้อบังคับไม่ได้รับคำตอบ สายจะจบ ส่วนข้อไม่บังคับจะข้ามไป
retry_promptพูดก่อนถามซ้ำ เมื่อกดปุ่มนอกช่วงของข้อนั้น โดยเติม {min} และ {max} ให้ ถ้าไม่ระบุจะถามคำถามซ้ำเลย ปลายสายกดได้ 3 ครั้ง
survey_idจัดกลุ่มคำตอบในรายงานแบบสำรวจ คำตอบแต่ละข้อบันทึกเป็น <survey_id>.<key> เช่น csat_q3.score แต่ละข้อจึงคงสเกลของตัวเอง ค่าเริ่มต้น telephony_survey
ttsเสียงที่ใช้อ่านทุกข้อความ: provider, voice_id, language, instructions ผู้ให้บริการที่ใช้ไม่ได้จะถูกปฏิเสธด้วย 400 ก่อนเข้าคิว

แบบสำรวจแบบกดปุ่มจะเข้าคิว ผลตอบกลับคือ 202 พร้อม status: "queued"

ให้คำตอบที่ดีกว่าอยู่บนปุ่มที่สูงกว่า

รายงานแบบสำรวจนับว่าพึงพอใจเมื่อคะแนนอยู่ในสองอันดับบนของสเกล สำหรับคำถามใช่/ไม่ ให้ ใช่ อยู่บนปุ่มที่สูงกว่า (1 ไม่ 2 ใช่) รายงานจะอ่านได้ตรงตามที่คาด

พูดตอบ ("mode": "agent" ค่าเริ่มต้น) ​

AI agent ถามข้อมูลตาม parameters ด้วยเสียง และวางสายเมื่อได้คำตอบที่จำเป็นครบและถูกต้อง สายจะดังทันที ผลตอบกลับคือ 201

json
{
  "destination": "+66812345678",
  "survey": {
    "greeting": "สวัสดีค่ะ ขอเวลาทำแบบสำรวจสั้น ๆ",
    "parameters": {
      "type": "object",
      "properties": {
        "rating": { "type": "integer", "x-parse": "integer" },
        "comment": { "type": "string" }
      },
      "required": ["rating"]
    },
    "language": "th",
    "callback_url": "https://example.com/hooks/survey"
  }
}

x-parse กำหนดรูปแบบคำตอบที่ agent ส่งกลับของแต่ละฟิลด์: text, integer, number, boolean, date, phone หรือ email ฟิลด์ของแบบกดปุ่ม (questions, closing, retry_prompt, survey_id, tts) จะถูกปฏิเสธในโหมดนี้

รับคำตอบ ​

คำตอบจาก gather หรือแบบสำรวจส่งถึงคุณสองทาง ด้วย body เดียวกัน

  • Webhook — event call.ai_gather.ended ใน webhook ของ workspace ส่งเมื่อสายที่มีคนรับจบลง พร้อม status เป็น valid หรือ incomplete
  • callback_url — ส่งเฉพาะเมื่อคำตอบที่จำเป็นครบและ valid ทั้งหมด พร้อมลายเซ็น: X-webhook-signature คือ HMAC-SHA256 แบบ base64 ของ body ดิบ โดยใช้ call.gather.callback_secret จากผลตอบกลับตอนโทร (หรือ callback_secret ที่คุณส่งมา) เป็น key
json
{
  "event": "call.ai_gather.ended",
  "id": "evt_…",
  "created_at": "2026-09-25T09:30:12Z",
  "workspace_id": "org_…",
  "gather_id": "…",
  "session_uuid": "…",
  "status": "valid",
  "result": { "score": 4, "would_return": 2 }
}

จับคู่ gather_id กับ call.gather.gather_id จากผลตอบกลับตอนโทร

โทรหลายเบอร์ ​

json
{
  "destinations": ["+66811111111", "+66822222222"],
  "tts": { "text": "วันนี้สำนักงานปิดทำการ", "voice_id": "eve", "language": "th" }
}
json
{ "queued": 2, "total": 2, "calls": [{ "destination": "+66811111111", "call": { "call_uuid": "…", "status": "queued" } }] }

เบอร์ที่เข้าคิวไม่ได้จะมี error ในรายการของเบอร์นั้น เบอร์อื่นยังโทรออกตามปกติ

สถานะของสาย ​

bash
curl "$ME_BASE/telephony/call/$CALL_UUID" \
  -H "API-Key: $ME_API_KEY" -H "X-TenantID: $ME_TENANT"
json
{ "call_uuid": "5d2c…", "room": "…", "destination": "+66812345678", "status": "completed", "handled_by_ai": false, "duration_secs": 42 }

status เปลี่ยนจาก pending, ringing และ in_progress แล้วจบที่ completed, no_answer, failed หรือ canceled

SDK ​

go
res, err := c.Telephony.Survey(ctx, &sdk.SurveyCallRequest{
	DialTarget: sdk.DialTarget{Destination: "+66812345678"},
	Survey: &sdk.Survey{
		Mode:      sdk.SurveyModeDTMF,
		SurveyID:  "csat_q3",
		Questions: []sdk.SurveyQuestion{{Key: "score", Prompt: "กด 1 ถึง 5", Min: 1, Max: 5}},
	},
})
ts
const res = await me.telephony.survey({
  destination: "+66812345678",
  survey: { mode: "dtmf", survey_id: "csat_q3", questions: [{ key: "score", prompt: "กด 1 ถึง 5", min: 1, max: 5 }] },
});

SDK ทุกภาษามีบริการ telephony เหมือนกัน: dial, tts, agent, survey, flow, extension, batch และ status