Tuhmo API
自社のシステムから Tuhmo のタスク、ノート、クライアント、プロジェクトを読み書きでき、変更があれば Webhook で通知を受け取れます。
はじめに
「設定」の「開発者」にある「API キー」でキーを作成します。キーは一度しか表示されないため、安全な場所に保管してください。
すべてのリクエストの Authorization ヘッダーにキーを付けて送信します。まず /me を呼び出して、キーが使えることを確認してください。
curl https://app.tuhmo.com/api/v1/me \ -H "Authorization: Bearer tmk_..."
キーでできること
キーは作成した人として、作成したワークスペースの中でだけ動作します。閲覧や変更ができる範囲はその人と同じで、他の人のプライベートページにはアクセスできません。作成した人がワークスペースを離れると、キーはすぐに使えなくなります。
キーには「読み取り専用」と「読み取りと書き込み」の2種類があります。Free プランでは1人につき読み取り専用のキーを2つまで、Plus 以上では書き込みもできるキーを1人10個まで作成できます。お金に関する書類はどのプランでも読み取り専用で、API からクライアントに書類を送信する手段はありません。
エンドポイント
すべてのパスは https://app.tuhmo.com/api/v1 で始まります。{id} は対象の24文字の ID です。リクエストとレスポンスは JSON です。
| メソッド | パス | 内容 |
|---|---|---|
| GET | /me | このキーの所有者、ワークスペース、書き込み可否 |
| GET | /tasks | タスク一覧 |
| GET | /tasks/{id} | タスクを1件取得 |
| POST | /tasks | タスクを作成(title と status は必須) |
| PATCH | /tasks/{id} | タスクの一部の項目を更新 |
| DELETE | /tasks/{id} | タスクをゴミ箱に移動 |
| PATCH | /tasks/{id}/props | カスタムプロパティを更新 |
| GET | /tasks/{id}/comments | タスクのコメント |
| POST | /tasks/{id}/comments | タスクにコメント |
| GET | /tasks/{id}/github | タスクに紐づく GitHub のプルリクエスト、Issue、コミット |
| GET | /tasksets | タスクセット |
| GET | /notes/tree | 閲覧できるすべてのノートのツリー |
| GET | /notes/search?q= | ノートを検索 |
| GET | /notes/{id} | ノートを本文ごと取得 |
| POST | /notes | ノートを作成 |
| PATCH | /notes/{id} | ノートのタイトルまたは本文を更新 |
| DELETE | /notes/{id} | ノートをゴミ箱に移動 |
| GET | /notes/{id}/comments | ノートのコメント |
| POST | /notes/{id}/comments | ノートにコメント |
| GET | /clients | クライアント一覧 |
| GET | /clients/{id} | クライアントを1件取得 |
| POST | /clients | クライアントを作成 |
| PUT | /clients/{id} | クライアントを更新 |
| GET | /clients/{id}/jobs | クライアントのプロジェクト |
| GET | /projects | プロジェクト一覧 |
| GET | /projects/job/{id} | プロジェクトを1件取得 |
| POST | /jobs | プロジェクトを作成 |
| PATCH | /jobs/{id} | プロジェクトを更新 |
| GET | /invoices · /invoices/{id} | 請求書(読み取り専用) |
| GET | /proposals · /proposals/{id} | 見積書(読み取り専用) |
| GET | /contracts · /contracts/{id} | 契約書(読み取り専用) |
例:タスクを作成する
curl -X POST https://app.tuhmo.com/api/v1/tasks \
-H "Authorization: Bearer tmk_..." \
-H "Content-Type: application/json" \
-d '{"title": "クライアントにファイルを送る", "status": "todo", "dueDate": "2026-10-20"}'status は todo、doing、review、done のいずれかです。dueDate は YYYY-MM-DD 形式です。
すべてのタスクには number があり、ワークスペース内の短い番号として使えます(TUH-42 の 42)。コミットやプルリクエストにこの番号を書くと、タスクが自動で GitHub と紐づきます。紐づいたプルリクエストは /tasks/{id}/github で確認できます。
Webhook
オーナーと管理者は「設定」の「開発者」で送信先を追加し、受け取るイベントを選びます。すべてのイベントは送信先の URL に JSON の POST で届きます。
ノートの本文は送信されません。本文が必要な場合は API キーで /notes/{id} を呼び出してください。プライベートページとその配下のものは送信されません。
| event | 送信されるタイミング | data の内容 |
|---|---|---|
| task.created | タスクが作成されたとき | タスク全体 |
| task.updated | タイトル、ステータス、日付、担当者などタスクが変更されたとき | タスク全体 |
| task.status_changed | タスクのステータスが変わったとき(task.updated と同時に送信) | タスクと previousStatus |
| task.deleted | タスクがゴミ箱に移動されたとき | id、title、number、url |
| note.created | ノートページが作成されたとき | id、title、icon、parentId、projectId、clientId、日時、url(本文は含まれません) |
| note.updated | ノートが変更されたとき。編集が30秒止まった時点でまとめて1回送信 | note.created と同じ |
| note.deleted | ノートがゴミ箱に移動されたとき | id、title、url |
| comment.created | タスク、ノート、テーブルの行に新しいコメントが付いたとき | コメントと、コメント先の url |
| ping | 設定で「テストリクエストを送信」を押したとき | data なし |
{
"id": "6720c1f2a9e4b3d1c0a1b2c3",
"event": "task.status_changed",
"at": "2026-10-20T09:30:00Z",
"workspaceId": "66f0a8e2c4b1d2e3f4a5b6c7",
"data": {
"id": "6714e0b2a9e4b3d1c0a19f00",
"previousStatus": "doing",
"status": "review",
"number": 42,
"title": "...",
"dueDate": "2026-10-20T00:00:00Z",
"url": "https://app.tuhmo.com/tasks?task=6714e0b2a9e4b3d1c0a19f00"
}
}最上位の id は配信ごとの ID で、再試行でも変わらないため重複の除外に使えます。at はイベントが発生した日時、data.id はタスク、ノート、コメントの ID です。
署名と再試行
すべてのリクエストには X-Event(イベント名)、X-Delivery-Id(本文の id と同じ)、X-Signature-256 が付きます。X-Signature-256 は生のリクエスト本文の HMAC SHA256 で、送信先の whsec_ シークレットで署名されています。データを信頼する前に必ず検証してください。
import crypto from "node:crypto";
// body = 生のリクエスト本文(JSON.parse の前)、secret = 送信先の whsec_ シークレット
function verify(body, header, secret) {
const sig = "sha256=" + crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(header ?? ""));
}15秒以内に 2xx を返してください。返さない場合は約10時間かけてさらに5回再試行します。20回続けて失敗すると送信先は自動で無効になり、オーナーと管理者に通知されます。
Free プランは送信先1つ、1時間あたり100回まで配信できます。Plus 以上は送信先10個、それぞれ1時間あたり1,000回まで配信できます。
受信 Webhook
他のシステムから、キーなしで1つの URL を通じて Tuhmo にデータを送れます。GitHub Actions、Zapier、フォームなどに便利です。URL は「設定」の「開発者」にある「受信 Webhook」で作成します(オーナーと管理者、Plus 以上)。
URL は作成した人として動作し、閲覧や変更ができる範囲もその人と同じです。URL は一度しか表示されず、知っている人は誰でもデータを送れます。漏れた場合は新しい URL を作成すると、古い URL はすぐに使えなくなります。
3種類の action のいずれかを指定して JSON の POST を送信します。受信 Webhook はお金に関する書類には触れず、クライアントに何かを送ることもできません。
| action | 項目 | 内容 |
|---|---|---|
| create_task | title note status dueDate projectId clientId | タスクを作成します。status を省略すると todo になります |
| append_to_note | noteId text | ノートの末尾にテキストを追加します |
| add_comment | taskId または noteId と text | タスクまたはノートにコメントします |
curl -X POST https://app.tuhmo.com/api/hooks/in/tih_... \
-H "Content-Type: application/json" \
-d '{"action": "create_task", "title": "main のビルドが失敗", "dueDate": "2026-10-20"}'成功すると、作成したものの id とともに 201 または 200 を返します。無効にした URL は 403 と code disabled を返します。URL ごとに1分あたり60リクエストまで、本文は256 KB までです。
すべてのリクエストは URL の履歴に14日間保存され、何をしたか、成功したか、どの IP から来たかを確認できます。
制限
キーごとに平均で毎秒3リクエスト、瞬間的には10まで、ワークスペース全体では毎秒10リクエストまでです。超えると 429 が返り、Retry-After ヘッダーに待つべき秒数が入ります。
リクエスト本文は1 MB までです。
エラー
エラーは JSON で返り、人が読むための error と、プログラムで分岐に使える code が含まれます。
| ステータス | code | 意味 |
|---|---|---|
| 401 | unauthorized | キーがない、間違っている、期限切れ、または取り消されている |
| 403 | read_only | 読み取り専用のキーでデータを変更しようとした |
| 403 | plan | ワークスペースのプランが対応していない(Free での書き込みなど) |
| 403 | キーの所有者にワークスペースでその操作をする権限がない | |
| 403 | disabled | 受信 Webhook の URL が無効になっている |
| 404 | not_found | パスが API に含まれていない、または対象が存在しない |
| 413 | too_large | リクエスト本文が1 MB を超えている(受信 Webhook は256 KB) |
| 429 | rate_limited | リクエストが多すぎる。Retry-After の秒数だけ待つ |

