API สาธารณะ
เฮลป์เดสก์เปิดให้ใช้ API สาธารณะเพียงชุดเดียว คือเอนด์พอยต์ GraphQL ทุกการดำเนินการในสคีมาเข้าถึงได้จากนอกเบราว์เซอร์ด้วยโทเค็นการเข้าถึงส่วนบุคคล (Personal Access Token หรือ PAT)
หน้านี้คือข้อตกลงการใช้งาน — อะไรที่เสถียร ยืนยันตัวตนอย่างไร ขอบเขตสิทธิ์ให้สิทธิ์อะไรบ้าง และข้อผิดพลาดมีรูปแบบอย่างไร CLI hdmx สร้างขึ้นบนพื้นฐานนี้ ส่วนการกำหนดเวอร์ชันของ API อธิบายว่าส่วนต่อประสานนี้พัฒนาไปอย่างไร
เอนด์พอยต์
POST https://<your-host>/backend/<subdomain>/api/<version>/graphql
<subdomain>ระบุบัญชีของคุณ (ชื่อเดียวกับที่คุณใช้เข้าสู่ระบบ)<version>คือเวอร์ชัน API แบบระบุวันที่ เช่น2026-07— ดูการกำหนดเวอร์ชันของ API คุณจะละส่วนของเวอร์ชันแล้วเรียก…/backend/<subdomain>/graphqlก็ได้ กรณีนี้คำขอจะถูกให้บริการโดยเวอร์ชันเก่าที่สุดที่ยังรองรับ และทุกการตอบกลับจะบอกว่าเวอร์ชันใดเป็นผู้ตอบ
การยืนยันตัวตน
ส่งโทเค็นการเข้าถึงส่วนบุคคลเป็นข้อมูลรับรองแบบ Bearer:
Authorization: Bearer hdmx_<random>
PAT มีอายุการใช้งานยาว (แต่ต้องกำหนดวันหมดอายุ) มีขอบเขตสิทธิ์ จำกัดตาม IP และเพิกถอนได้ โทเค็นผูกกับบัญชีเดียว การนำโทเค็นไปใช้กับซับโดเมนของบัญชีอื่นจะถูกปฏิเสธด้วย HTTP 401
การสร้างโทเค็น
สร้างและจัดการโทเค็นด้วยตนเองในแอปสำหรับเจ้าหน้าที่ ที่ Settings → API tokens:
- คลิก New token
- ตั้งชื่อที่คุณจะจำได้ในภายหลัง
- เลือกวันหมดอายุ (สูงสุด 365 วัน — ไม่มีตัวเลือก "ไม่มีวันหมดอายุ")
- กำหนดนโยบายการเข้าถึง — เปิดเฉพาะทรัพยากรที่โทเค็นนี้ต้องใช้จริง โดยเลือกอ่านอย่างเดียวหรืออ่านและเขียน ค่าเริ่มต้นคือไม่ให้สิทธิ์เข้าถึงสิ่งใดเลย
- เพิ่ม ที่อยู่ IP หรือ CIDR อย่างน้อยหนึ่งรายการลงในรายการที่อนุญาต (จำเป็น — ดูรายการ IP ที่อนุญาต) แบบฟอร์มสามารถเพิ่ม IP ปัจจุบันของคุณให้ได้
- ตรวจสอบแล้วสร้าง โทเค็นแบบเต็มจะแสดงเพียงครั้งเดียวเท่านั้น — คัดลอกทันที ระบบเก็บไว้เพียงค่าแฮช จึงไม่สามารถแสดงซ้ำได้อีก หากทำหาย ให้หมุนเปลี่ยน (rotate) โทเค็นเพื่อรับอันใหม่
ภายหลังคุณสามารถแก้ไขนโยบายการเข้าถึงและรายการที่อนุญาตของโทเค็น หมุนเปลี่ยน โทเค็น (ออกความลับชุดใหม่โดยที่ชุดเดิมยังใช้ได้ในช่วงผ่อนผันสั้น ๆ เพื่อให้เปลี่ยนได้โดยไม่หยุดให้บริการ) และเพิกถอนได้ โทเค็นแต่ละอันจะแสดงว่าถูกใช้ครั้งล่าสุดเมื่อใดและจากที่ใด พร้อมบันทึกกิจกรรมล่าสุด
ขอบเขตสิทธิ์
การให้สิทธิ์เป็นแบบหยาบและแบ่งตามกลุ่มทรัพยากร โทเค็นหนึ่งอันมีชุดขอบเขตสิทธิ์ที่ตายตัว และทุกการดำเนินการระดับบนสุดจะตรวจสอบหนึ่งในนั้น
| ขอบเขตสิทธิ์ | ให้สิทธิ์ |
|---|---|
tickets:read | อ่านทิกเก็ต ข้อความ ฉบับร่าง ประวัติ ไฟล์แนบ และรายงาน |
tickets:write | สร้าง / แก้ไข / ลบทิกเก็ต ส่งข้อความ อัปโหลดไฟล์แนบ ครอบคลุม tickets:read ด้วย |
chat:read | อ่านแชท บทสนทนา ข้อความ และเซสชัน |
chat:write | ส่งข้อความในนามเจ้าหน้าที่ เข้าร่วม / ออก / ปิด / เปิดบทสนทนาใหม่ ครอบคลุม chat:read ด้วย |
customers:read | อ่านระเบียนลูกค้า |
customers:write | สร้าง / แก้ไข / รวมระเบียนลูกค้า ครอบคลุม customers:read ด้วย |
settings:read | อ่านการตั้งค่าบัญชี (แผนก สถานะ ระดับความสำคัญ กล่องจดหมาย — ไม่รวมข้อมูลลับ) |
ฟิลด์ข้อมูลรับรองของกล่องจดหมาย (ชื่อผู้ใช้ รหัสผ่าน และโฮสต์ของ IMAP/SMTP) จะไม่ถูกส่งกลับให้โทเค็นไม่ว่าจะมีขอบเขตสิทธิ์ใดก็ตาม ข้อมูลลับเหล่านี้เป็นของผู้ให้บริการอีเมลของคุณ และอยู่นอกระยะเอื้อมของ API สาธารณะ
การจำแนกข้อผิดพลาด
การตอบกลับของ GraphQL ใช้ errors[].extensions.code:
| รหัส | ความหมาย | HTTP |
|---|---|---|
SCOPE_DENIED | โทเค็นขาดขอบเขตสิทธิ์ที่จำเป็น extensions.valid_values จะแสดงขอบเขตสิทธิ์ที่เพียงพอต่อการดำเนินการนั้น | 200 |
RATE_LIMITED | โควตาคำขอต่อโทเค็นหมดแล้ว extensions.retryAfter คือจำนวนวินาทีจนกว่าจะรีเซ็ต และส่วนหัว Retry-After ก็มีตัวเลขเดียวกัน | 429 |
INVALID_API_TOKEN | ไม่พบโทเค็น รูปแบบไม่ถูกต้อง หรือใช้งานไม่ได้ด้วยเหตุอื่น | 200 |
โทเค็นที่ถูกเพิกถอน โทเค็นหมดอายุ ความไม่ตรงกันข้ามบัญชี และการปฏิเสธจากรายการ IP ที่อนุญาต จะถูกปฏิเสธก่อนที่คิวรีจะทำงาน และปรากฏเป็น HTTP 401 โดยไม่มีเนื้อหา GraphQL ให้ถือว่า 401 ในคำขอที่ใช้โทเค็นหมายถึง "โทเค็นนี้ใช้กับคำขอนี้ไม่ได้อีกแล้ว — ตรวจสอบวันหมดอายุ ขอบเขตสิทธิ์ และรายการ IP ที่อนุญาต"
ขีดจำกัดอัตราการเรียก
ทุกคำขอที่ใช้โทเค็นจะได้รับส่วนหัวเหล่านี้:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 96
X-RateLimit-Reset: 1715692800
โควตาเริ่มต้นคือ 120 คำขอต่อนาทีต่อโทเค็น ทุกคำขอมีต้นทุนเท่ากับ 1 ไม่ว่าจะเป็นการอ่านหรือเขียน หากเกินโควตาจะได้รับ HTTP 429 พร้อมส่วนหัว Retry-After และ extensions.code = "RATE_LIMITED" ไคลเอนต์ที่ทำงานอย่างเหมาะสมควรรอจนถึงเวลารีเซ็ต
รายการ IP ที่อนุญาต
โทเค็นที่ผู้ใช้สร้างเองทุกอันต้องมี IP หรือ CIDR อย่างน้อยหนึ่งรายการ ไม่มีโทเค็นแบบ "IP ใดก็ได้" IP ต้นทางของทุกคำขอจะถูกเทียบกับรายการของโทเค็น หากไม่ตรงจะถูกปฏิเสธด้วย HTTP 401 และ extensions.sub_code = "ip_not_allowed"
- รองรับทั้ง IPv4, IPv6 และช่วง CIDR สำหรับโฮสต์เดียวให้ใช้
/32(IPv4) หรือ/128(IPv6) - ช่วงที่ระบุจะถูกตรวจสอบและปรับให้เป็นรูปแบบมาตรฐานเมื่อบันทึก
- แก้ไขรายการที่อนุญาตได้หลังสร้างโทเค็นแล้ว การแก้ไขไม่ทำให้ค่าความลับเปลี่ยน
ใช้โทเค็นจากจุดออกที่คงที่ เช่น CI runner งานตามกำหนดเวลา NAT ของสำนักงานที่มี IP คงที่ หรือเซิร์ฟเวอร์ของคุณเองในช่วง IP ที่ทราบแน่ชัด โทเค็นที่รั่วไหลจะใช้ไม่ได้เลยจากที่ใดก็ตามนอกรายการที่อนุญาต
กิจกรรมของโทเค็น
ทุกคำขอที่ผ่านการยืนยันตัวตนของโทเค็นจะถูกบันทึกไว้ ได้แก่ เวลา ชื่อการดำเนินการ IP ต้นทาง ผลลัพธ์ (สำเร็จ ข้อผิดพลาด ติดขีดจำกัดอัตรา ขอบเขตสิทธิ์ไม่พอ ถูกเพิกถอน หรือหมดอายุ) และเวลาตอบกลับไป-กลับ นี่คือร่องรอยที่ควรตรวจสอบหากโทเค็นทำงานผิดไปจากที่คาด
การกำหนดเวอร์ชันและการเลิกใช้งาน
API กำหนดเวอร์ชันด้วยรูปแบบระบุวันที่ YYYY-MM ตรึงเวอร์ชันไว้ใน URL แล้วเวอร์ชันนั้นจะคงที่อย่างน้อย 12 เดือน ส่วนการเลิกใช้งานจะถูกประกาศมาพร้อมกับการตอบกลับก่อนที่สิ่งที่คุณใช้อยู่จะหายไป ดูนโยบายฉบับเต็มได้ที่ การกำหนดเวอร์ชันของ API
การสำรวจสคีมา
สคีมาอธิบายตัวเองได้: ใช้ GraphQL introspection มาตรฐานกับเอนด์พอยต์ที่ระบุเวอร์ชัน เพื่อสร้างไทป์และสำรวจส่วนต่อประสานทั้งหมด GraphQL Playground แบบโต้ตอบอยู่ที่ …/backend/<subdomain>/playground
เริ่มต้นอย่างรวดเร็วด้วย curl
ตัวอย่างต่อไปนี้สมมติว่าโฮสต์คือ helpdesk.example.com ซับโดเมนคือ acme เวอร์ชันคือ 2026-07 และเก็บโทเค็นไว้ใน $TOKEN
อ่านข้อมูลผู้ใช้ปัจจุบัน (ขอบเขตสิทธิ์ใดก็ได้)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"{ currentUser { id email firstname lastname } }"}'
แสดงรายการทิกเก็ตล่าสุด (tickets:read)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query ($first: Int!) {
ticketList(first: $first) {
edges { node { code subject status { name } updatedAt } }
}
}",
"variables": { "first": 10 }
}'
ส่งคำตอบแบบสาธารณะ (tickets:write)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation ($input: SaveTicketInput!) {
saveTicket(input: $input) {
ticket { code }
error { code message }
}
}",
"variables": {
"input": {
"id": "TICKET-UUID-HERE",
"message": "Thanks — fixing this now.",
"messageType": "PUBLIC"
}
}
}'
สำหรับการใช้งานประจำวัน CLI hdmx ห่อหุ้มส่วนต่อประสานทั้งหมดนี้ไว้เบื้องหลังคำสั่งที่ใช้งานง่าย