公開 API
ヘルプデスクは公開 API を 1 つ提供しています。GraphQL エンドポイントです。スキーマ上のすべての操作は、パーソナルアクセストークン(Personal Access Token、PAT)を使ってブラウザーの外から到達できます。
このページは契約そのものです。何が安定しているか、どう認証するか、スコープが何を許可するか、エラーがどのような形をとるかを定めます。hdmx CLI はこの上に構築されており、API バージョン管理 はこの API の進化のしかたを説明します。
エンドポイント
POST https://<your-host>/backend/<subdomain>/api/<version>/graphql
<subdomain>はあなたのアカウントを識別します(サインインに使うものと同じハンドルです)。<version>は2026-07のような日付版 API バージョンです — API バージョン管理 を参照してください。バージョンのセグメントを省略して…/backend/<subdomain>/graphqlを呼び出すこともできます。その場合、リクエストはサポートされている最も古いバージョンで処理され、どのバージョンが応答したかは各レスポンスが示します。
認証
パーソナルアクセストークンを Bearer 資格情報として送信します。
Authorization: Bearer hdmx_<random>
PAT は長期間有効(ただし有効期限は必須)で、スコープを持ち、IP で制限され、失効させることができます。1 つのアカウントに紐付いており、別アカウントのサブドメインにトークンを提示すると HTTP 401 で拒否されます。
トークンの作成
トークンはエージェントアプリの Settings → API tokens で自分で作成・管理します。
- New token をクリックします。
- 後で見分けられる 名前 を付けます。
- 有効期限 を選びます(最長 365 日 — 「無期限」はありません)。
- アクセスポリシー を設定します。このトークンに必要なリソースだけを、読み取りまたは読み書きで有効にします。既定ではすべてアクセス不可です。
- 許可リストに IP アドレスまたは CIDR を最低 1 つ追加します(必須 — IP 許可リスト を参照)。フォームが現在の IP を代わりに追加できます。
- 内容を確認して作成します。完全なトークンが表示されるのは 1 回だけ です。すぐにコピーしてください。保存されるのはハッシュのみなので、再表示はできません。紛失した場合はトークンをローテーションして新しいものを取得します。
作成後も、トークンのアクセスポリシーと許可リストを編集し、ローテーション(新しいシークレットを発行し、古いものは短い猶予期間だけ有効なままにして無停止で切り替える)や 失効 を行えます。各トークンには、最後に使われた日時と場所、そして直近のアクティビティログが表示されます。
スコープ
アクセス権は粗い粒度で、リソースのまとまりごとに分かれています。トークンは固定のスコープ集合を持ち、すべてのトップレベル操作がそのいずれかを検査します。
| スコープ | 付与される権限 |
|---|---|
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 リクエストのコストは 1 です。超過すると Retry-After ヘッダーと extensions.code = "RATE_LIMITED" を伴う HTTP 429 が返ります。行儀のよいクライアントはリセット時刻まで待機します。
IP 許可リスト
セルフサービスで作成したトークンは、必ず 1 つ以上の IP または CIDR を持つ必要があります。「任意の IP」を許すトークンはありません。各リクエストの送信元 IP はトークンのリストと照合され、一致しなければ HTTP 401 と extensions.sub_code = "ip_not_allowed" で拒否されます。
- IPv4、IPv6、CIDR 範囲のいずれも指定できます。単一ホストには
/32(IPv4)または/128(IPv6)を使います。 - 範囲は保存時に検証・正規化されます。
- 許可リストは作成後も編集できます。編集してもシークレットは変わりません。
トークンは、CI ランナー、スケジュール実行のジョブ、固定オフィスの NAT、既知の IP 範囲にある自社サーバーなど、安定した送信元から使ってください。漏えいしたトークンは、許可リスト外のどこからでも役に立ちません。
トークンのアクティビティ
トークンが行った認証済みリクエストはすべて記録されます。日時、操作名、送信元 IP、結果(成功、エラー、レート制限、スコープ拒否、失効、期限切れ)、および往復のレイテンシです。トークンの挙動がおかしいときに確認すべき記録です。
バージョン管理と非推奨
API は YYYY-MM の日付版バージョンで管理されます。URL でバージョンを固定すれば、最低 12 か月は安定した状態が保たれます。非推奨は、あなたが使っているものが失われる前に、通信の中で通知されます。詳しいポリシーは API バージョン管理 を参照してください。
スキーマの探索
スキーマは自己記述的です。バージョン付きエンドポイントに対して標準の GraphQL イントロスペクション を実行すれば、型を生成し、API 全体を調べられます。対話的な 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 CLI がこの API 全体を使いやすいコマンドで包んでくれます。