Skip to main content

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:

  1. คลิก New token
  2. ตั้งชื่อที่คุณจะจำได้ในภายหลัง
  3. เลือกวันหมดอายุ (สูงสุด 365 วัน — ไม่มีตัวเลือก "ไม่มีวันหมดอายุ")
  4. กำหนดนโยบายการเข้าถึง — เปิดเฉพาะทรัพยากรที่โทเค็นนี้ต้องใช้จริง โดยเลือกอ่านอย่างเดียวหรืออ่านและเขียน ค่าเริ่มต้นคือไม่ให้สิทธิ์เข้าถึงสิ่งใดเลย
  5. เพิ่ม ที่อยู่ IP หรือ CIDR อย่างน้อยหนึ่งรายการลงในรายการที่อนุญาต (จำเป็น — ดูรายการ IP ที่อนุญาต) แบบฟอร์มสามารถเพิ่ม IP ปัจจุบันของคุณให้ได้
  6. ตรวจสอบแล้วสร้าง โทเค็นแบบเต็มจะแสดงเพียงครั้งเดียวเท่านั้น — คัดลอกทันที ระบบเก็บไว้เพียงค่าแฮช จึงไม่สามารถแสดงซ้ำได้อีก หากทำหาย ให้หมุนเปลี่ยน (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 ห่อหุ้มส่วนต่อประสานทั้งหมดนี้ไว้เบื้องหลังคำสั่งที่ใช้งานง่าย