跳至主要内容

公開 API

服務台只提供一個公開 API:一個 GraphQL 端點。憑個人存取權杖(Personal Access Token,PAT),schema 中的每個操作都能在瀏覽器之外呼叫。

本頁就是契約——什麼是穩定的、如何驗證、權限範圍授予了什麼,以及錯誤採用何種形式。hdmx 命令列工具建構在其之上,而 API 版本管理說明這套介面如何演進。

端點​

POST https://<your-host>/backend/<subdomain>/api/<version>/graphql
  • <subdomain> 用來識別你的帳戶(與你登入時使用的識別碼相同)。
  • <version> 是形如 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. 檢查後建立。完整權杖只會顯示一次——請立即複製。系統只保存雜湊值,因此無法再次顯示;若不慎遺失,請輪替權杖以取得新的。

之後你可以編輯權杖的存取原則與允許清單,對它進行輪替(發出新的密鑰,同時舊密鑰在短暫的寬限期內仍可使用,方便你無中斷切換),以及撤銷它。每個權杖都會顯示上次使用的時間與來源,以及最近的活動紀錄。

權限範圍​

存取控制是粗粒度的,依資源族劃分。權杖帶有一組固定的權限範圍;每個最上層操作都會檢查其中之一。

權限範圍授予
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 允許清單的拒絕,都會在查詢執行之前被擋下,並以不含 GraphQL 主體的 HTTP 401 回傳。請把權杖要求上的 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、結果(成功、錯誤、觸發速率限制、權限範圍遭拒、已撤銷或已到期)以及來回延遲。當權杖行為異常時,這就是應該查看的線索。

版本管理與淘汰​

API 以 YYYY-MM 日期版本進行版本管理。在 URL 中釘選一個版本,它至少會在 12 個月內維持穩定;在你所使用的內容消失之前,淘汰會透過同一條通道事先通知。完整政策請參見 API 版本管理。

探索 schema​

Schema 具備自我描述能力:對帶版本的端點使用標準的 GraphQL 內省,即可產生型別並瀏覽整個介面。互動式 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"
}
}
}'

日常使用時,hdmx 命令列工具會把整套介面包裝成好用的命令。