เมนูคู่มือ

Server API

Server API ช่วยให้เซิร์ฟเวอร์ของคุณอ่านและปิดทิกเก็ต ดึงรายงาน กำหนดว่าใครจะเห็นบอต และดูเวอร์ชันที่เผยแพร่แล้วได้ ทุกการเรียกใช้ต้องใช้คีย์ลับ

ข้อกำหนดฉบับเต็มอยู่ในไฟล์ openapi.yaml (OpenAPI 3.1) สามารถนำเข้าใน Postman หรือ Insomnia หรือใช้สร้างไคลเอนต์ได้ SDK ฝั่งเซิร์ฟเวอร์มีฟังก์ชันสำหรับเรียกใช้ทุกเอนด์พอยต์ในหน้านี้

การยืนยันตัวตน

URL หลัก: https://api.kavchat.com ส่งคีย์ลับเป็น bearer token โดยเก็บไว้บนเซิร์ฟเวอร์ของคุณและไม่ส่งไปยังเบราว์เซอร์หรือแอปเด็ดขาด สามารถเปลี่ยนคีย์ได้ที่หน้า การติดตั้ง ในแดชบอร์ด

curl
curl https://api.kavchat.com/v1/server/workspace \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY" \
  -H "Accept-Language: en"

การตอบกลับและข้อผิดพลาด

ทุกการตอบกลับเป็น JSON ที่มีฟิลด์ success ข้อผิดพลาดจะมี code แบบคงที่ที่โค้ดของคุณใช้ตรวจสอบได้ และ message เป็นภาษาตามเฮดเดอร์ Accept-Language (he, en, ar, ru, es, fr, de, pt, it, tr)

JSON
// success
{ "success": true, "data": { ... } }

// error
{ "success": false, "code": "ticket_not_found", "message": "Request not found" }
สถานะตัวอย่างรหัสความหมาย
400ticket_status_invalidพารามิเตอร์หรือฟิลด์ในเนื้อหาคำขอไม่ถูกต้อง
401invalid_keyไม่ได้ระบุคีย์ คีย์ไม่ถูกต้อง หรือคีย์ถูกเปลี่ยนแล้ว
404ticket_not_foundไม่มีทิกเก็ตนี้ในพื้นที่ทำงาน

เอนด์พอยต์

พื้นที่ทำงาน

GET /v1/server/workspace

รายละเอียดพื้นที่ทำงาน คีย์สาธารณะ และอักขระ 4 ตัวสุดท้ายของคีย์ลับ (secretKeyHint) เหมาะสำหรับเรียกใช้เป็นครั้งแรกเพื่อตรวจสอบว่าคีย์ใช้งานได้

curl
curl https://api.kavchat.com/v1/server/workspace \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY" \
  -H "Accept-Language: en"
Response
{
  "success": true,
  "data": {
    "id": "6718e9a1f0c2a4b5c6d7e8f9",
    "name": "Example Store",
    "locale": "en",
    "defaultCountry": "IL",
    "plan": "premium",
    "publicKey": "pk_live_Ab12Cd34Ef56Gh78Ij90Kl",
    "secretKeyHint": "a1b2",
    "webhookUrl": "https://example.com/kavchat/webhook"
  }
}

รายการทิกเก็ต

GET /v1/server/tickets

ทิกเก็ตที่เปิดจากแชต เรียงจากใหม่ไปเก่า

พารามิเตอร์คำอธิบาย
statusopen หรือ closed หากไม่ระบุ จะได้รับทั้งสองสถานะ
limitตั้งแต่ 1 ถึง 200 ค่าเริ่มต้นคือ 50
beforeสำหรับแบ่งหน้า: ค่า number ของทิกเก็ตสุดท้ายที่ได้รับแล้ว
curl
curl "https://api.kavchat.com/v1/server/tickets?status=open&limit=50" \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY"

# next page: pass the number of the last ticket you received
curl "https://api.kavchat.com/v1/server/tickets?status=open&limit=50&before=120" \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY"
Response
{
  "success": true,
  "data": [
    {
      "id": "6718f0c2a4b5c6d7e8f90123",
      "number": 128,
      "status": "open",
      "name": "Dana",
      "email": "dana@example.com",
      "phone": "+972501234567",
      "userId": "user_123",
      "topicId": "billing",
      "topicName": "Billing",
      "scriptId": "returns",
      "sessionId": "k3J9xQ2mP7aB",
      "message": "My refund has not arrived yet.",
      "transcript": [
        { "from": "bot", "text": "Hi! How can I help?", "stepId": "start", "at": "2026-10-25T09:14:02.000Z" }
      ],
      "createdAt": "2026-10-25T09:15:40.000Z",
      "updatedAt": "2026-10-25T09:15:40.000Z"
    }
  ]
}

userId คือฟิลด์ sub จากโทเค็นระบุตัวตนเมื่อระบุตัวตนผู้ใช้แล้ว ส่วน phone อยู่ในรูปแบบ E.164

ทิกเก็ตหนึ่งรายการ

GET /v1/server/tickets/{id}

ทิกเก็ตหนึ่งรายการพร้อมบันทึกการสนทนาฉบับเต็ม โดยใช้โครงสร้างเดียวกับแต่ละรายการในรายการทิกเก็ต หากไม่พบ ID จะได้รับข้อผิดพลาด 404 พร้อม ticket_not_found

curl
curl https://api.kavchat.com/v1/server/tickets/6718f0c2a4b5c6d7e8f90123 \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY"

ปิดหรือเปิดอีกครั้ง

PUT /v1/server/tickets/{id}/status

เนื้อหาคำขอ: { "status": "closed" } หรือ { "status": "open" } ส่งกลับทิกเก็ตที่อัปเดตแล้ว

curl
curl -X PUT https://api.kavchat.com/v1/server/tickets/6718f0c2a4b5c6d7e8f90123/status \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "closed" }'

รายงาน

GET /v1/server/reports

การสนทนาและผลลัพธ์ (open, answered, contact, abandoned) สรุปของแต่ละสคริปต์ ขั้นตอนที่ผู้ใช้ออกจากการสนทนา และคำถามที่บอตหาคำตอบไม่พบซึ่งจัดไว้เป็นกลุ่ม ค่า from และ to เป็นวันที่และเวลาในรูปแบบ ISO 8601 ค่าเริ่มต้นคือ 30 วันที่ผ่านมา

curl
curl "https://api.kavchat.com/v1/server/reports?from=2026-10-01T00:00:00Z&to=2026-10-25T00:00:00Z" \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY"
Response
{
  "success": true,
  "data": {
    "from": "2026-10-01T00:00:00.000Z",
    "to": "2026-10-25T00:00:00.000Z",
    "totals": { "sessions": 940, "open": 12, "answered": 801, "contact": 64, "abandoned": 63 },
    "byScript": [
      { "scriptId": "returns", "name": "Returns", "sessions": 310, "open": 3, "answered": 270, "contact": 22, "abandoned": 15 }
    ],
    "dropOff": [
      { "scriptId": "returns", "scriptName": "Returns", "stepId": "label", "stepText": "Print the return label from...", "count": 9 }
    ],
    "unmatched": [
      { "groupKey": "gift card balance", "sample": "how do I check my gift card balance", "count": 17, "lastAt": "2026-10-24T18:02:11.000Z" }
    ]
  }
}

การตั้งค่าบอต

GET /v1/server/settings

กลุ่มเป้าหมาย รายชื่อผู้ใช้ทดสอบ และรูปลักษณ์ของบอต

curl
curl https://api.kavchat.com/v1/server/settings \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY"
Response
{
  "success": true,
  "data": {
    "enabled": true,
    "audience": "testers",
    "testerPhones": ["+972501234567"],
    "botName": "Support",
    "avatarText": "S",
    "avatarImageUrl": null,
    "subtitle": "Replies instantly",
    "primaryColor": "#2563eb",
    "position": "end",
    "contactTopics": [{ "id": "billing", "name": "Billing" }]
  }
}

เปลี่ยนกลุ่มเป้าหมาย

PUT /v1/server/settings

ที่นี่เปลี่ยนได้เฉพาะ audience (off, testers หรือ all) และ testerPhones (สูงสุด 50 หมายเลข) การตั้งค่าอื่นแก้ไขได้ในแดชบอร์ด การตอบกลับจะเป็นค่าการตั้งค่าเช่นเดียวกับ GET

curl
curl -X PUT https://api.kavchat.com/v1/server/settings \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "audience": "testers", "testerPhones": ["+972501234567"] }'

# open the bot to everyone
curl -X PUT https://api.kavchat.com/v1/server/settings \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "audience": "all" }'

เวอร์ชัน

GET /v1/server/releases

50 เวอร์ชันล่าสุดที่เผยแพร่แล้ว เรียงจากใหม่ไปเก่า ฟิลด์ restoredFrom จะปรากฏเมื่อเวอร์ชันนั้นเป็นการกู้คืนเวอร์ชันก่อนหน้า

curl
curl https://api.kavchat.com/v1/server/releases \
  -H "Authorization: Bearer $KAVCHAT_SECRET_KEY"
Response
{
  "success": true,
  "data": [
    {
      "version": 7,
      "note": "New returns flow",
      "publishedAt": "2026-10-20T11:30:00.000Z",
      "scripts": [
        { "id": "opening", "kind": "opening", "name": "Welcome" },
        { "id": "returns", "kind": "topic", "name": "Returns" }
      ]
    },
    {
      "version": 6,
      "note": "Restore",
      "restoredFrom": 4,
      "publishedAt": "2026-10-12T08:05:00.000Z",
      "scripts": [{ "id": "opening", "kind": "opening", "name": "Welcome" }]
    }
  ]
}

ใช้งานผ่าน SDK ฝั่งเซิร์ฟเวอร์

SDK ทุกตัวเรียกใช้ API ชุดเดียวกัน ข้อผิดพลาดจะถูกโยนเป็นข้อผิดพลาด API พร้อม status, code, message และ details หากไม่ได้รับการตอบกลับ (timeout หรือ network_error) ค่า status จะเป็น 0

Node.js
await kavchat.getWorkspace();
await kavchat.listTickets({ status: 'open', limit: 50, before: 120 });
await kavchat.getTicket(id);
await kavchat.setTicketStatus(id, 'closed');
await kavchat.getReports({ from: new Date('2026-01-01'), to: new Date() });
await kavchat.getSettings();
await kavchat.updateSettings({ audience: 'testers', testerPhones: ['+972501234567'] });
await kavchat.listReleases();
Python
kavchat.get_workspace()
kavchat.list_tickets(status="open", limit=50, before=120)
kavchat.get_ticket(ticket_id)
kavchat.set_ticket_status(ticket_id, "closed")
kavchat.get_reports(from_=datetime(2026, 1, 1, tzinfo=timezone.utc), to=datetime.now(timezone.utc))
kavchat.get_settings()
kavchat.update_settings(audience="testers", tester_phones=["+972501234567"])
kavchat.list_releases()
PHP
$kavchat->getWorkspace();
$kavchat->listTickets(status: 'open', limit: 50, before: 120);
$kavchat->getTicket($id);
$kavchat->setTicketStatus($id, 'closed');
$kavchat->getReports(new DateTimeImmutable('2026-01-01'), new DateTimeImmutable());
$kavchat->getSettings();
$kavchat->updateSettings(audience: 'testers', testerPhones: ['+972501234567']);
$kavchat->listReleases();
Java
kavchat.getWorkspace();
kavchat.listTickets(ListTicketsParams.create().status(TicketStatus.OPEN).limit(50).before(120));
kavchat.getTicket(id);
kavchat.setTicketStatus(id, TicketStatus.CLOSED);
kavchat.getReports(Instant.parse("2026-01-01T00:00:00Z"), Instant.now());
kavchat.getSettings();
kavchat.updateSettings(UpdateSettingsParams.create().audience(Audience.TESTERS).testerPhones(List.of("+972501234567")));
kavchat.listReleases();
.NET
await kavchat.GetWorkspaceAsync();
await kavchat.ListTicketsAsync(new ListTicketsOptions { Status = TicketStatus.Open, Limit = 50, Before = 120 });
await kavchat.GetTicketAsync(id);
await kavchat.SetTicketStatusAsync(id, TicketStatus.Closed);
await kavchat.GetReportsAsync(DateTimeOffset.UtcNow.AddDays(-7), DateTimeOffset.UtcNow);
await kavchat.GetSettingsAsync();
await kavchat.UpdateSettingsAsync(new UpdateSettingsRequest { Audience = Audience.Testers, TesterPhones = ["+972501234567"] });
await kavchat.ListReleasesAsync();
Go
client.GetWorkspace(ctx)
client.ListTickets(ctx, kavchat.ListTicketsParams{Status: kavchat.TicketOpen, Limit: 50, Before: 120})
client.GetTicket(ctx, id)
client.SetTicketStatus(ctx, id, kavchat.TicketClosed)
client.GetReports(ctx, kavchat.ReportParams{From: time.Now().AddDate(0, 0, -7)})
client.GetSettings(ctx)
client.UpdateSettings(ctx, kavchat.UpdateSettingsParams{Audience: kavchat.AudienceTesters, TesterPhones: []string{"+972501234567"}})
client.ListReleases(ctx)
Ruby
kavchat.get_workspace
kavchat.list_tickets(status: "open", limit: 50, before: 120)
kavchat.get_ticket(id)
kavchat.set_ticket_status(id, "closed")
kavchat.get_reports(from: Time.now - 7 * 86_400, to: Time.now)
kavchat.get_settings
kavchat.update_settings(audience: "testers", tester_phones: ["+972501234567"])
kavchat.list_releases

Client API

วิดเจ็ตและ SDK สำหรับมือถือใช้อินเทอร์เฟซสาธารณะอีกชุดที่ /v1/client/{publicKey} ซึ่งส่งกลับเวอร์ชันที่เผยแพร่แล้ว บันทึกลำดับการสนทนา และเปิดทิกเก็ตจากแบบฟอร์มติดต่อ อินเทอร์เฟซนี้เปิดให้ผู้เยี่ยมชมใช้งานได้ด้วยและต้องใช้เพียงคีย์สาธารณะ คุณไม่จำเป็นต้องเรียกใช้เอง โดยมีคำอธิบายอยู่ในไฟล์ openapi.yaml เพื่อให้ข้อมูลครบถ้วน