asana-api について
Asana REST API でワークスペース、プロジェクト、タスクを扱うためのガイドです。HTTP リクエストで業務管理を自動化する人向けに、ページング対応のタスクスクリプトやコメント、サブタスク、タグ、添付ファイルの例を紹介します。
主な機能
- 01ページング付きタスク一覧
- 02タスクの作成・更新・完了
- 03コメントの取得と追加
- 04プロジェクト・セクション・サブタスクの管理
- 05ワークスペース・ユーザー・タグの検索
- 06API のページングとエラー処理
活用シーン
- 01プロジェクトや担当者別のタスク出力
- 02タスク状態の更新とコメント追加
- 03タスクのプロジェクト内セクション移動
- 04ワークスペース内のプロジェクトやメンバー検索
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ anthropics/ claude-tag-plugins --skill asana-apiインストール後、Claude Code で/asana-apiを入力して読み込まれたか確認します。
同梱ファイルreferences/api.mdscripts/asana_tasks.sh
詳細
Asana の REST API のルートは https://app.asana.com/api/1.0 です。すべての呼び出しには、次の 3 つの共通点があります。
すべてのオブジェクトは文字列の gid(グローバル ID)で識別され、すべてのレスポンスはペイロードをトップレベルの data キーでラップし、書き込みリクエストのボディもフィールドを data でラップします。ほとんどの読み取りでは、コンパクトなレコード(gid、name、resource_type)が返されます。追加の情報を取得するには opt_fields を指定してください。
リソースは規則的にネストされています。ワークスペース(組織がある場合は organization)にはプロジェクトとユーザーが含まれます。プロジェクトにはセクションとタスクが含まれます。タスクには、ストーリーとしてのコメントとアクティビティのほか、サブタスク、タグ、添付ファイル、カスタムフィールドが含まれます。
リクエストの設定
認証はランタイムが処理します。この API への送信リクエストには認証情報が注入されるため、設定は不要です。トークンやキーの作成、発行、更新、検証を試みないでください。認証情報の変数は、リクエストの形式を整える目的でのみ存在します。設定されていない場合は、任意のプレースホルダー値を設定してください。401/403 が継続する場合は、このワークスペースに認証情報が設定されていないことを意味します。認証をデバッグするのではなく、その旨を報告してください。
リクエストにはベアラートークンを使用します。ベース URL は固定(インスタンスごとではありません)ですが、ワークスペース/プロジェクト/タスクの gid は実際の値であり、パスの一部です。
export ASANA_TOKEN="placeholder" # injected by the runtime; any value works
export ASANA_BASE="https://app.asana.com/api/1.0"
セッションごとに一度、ヘルパーを定義します。
asana() { curl -sS -H "Authorization: Bearer ${ASANA_TOKEN}" \
-H "Accept: application/json" -H "Content-Type: application/json" "$@"; }
動作確認 — トークンが機能することを確認し、ワークスペースの gid を取得します。
asana "${ASANA_BASE}/users/me?opt_fields=name,email,workspaces.name" \
| jq '.data | {gid, name, email, workspaces: [.workspaces[]? | {gid, name}]}'
# 200 with your user + workspaces → wired up. 401 → credential not configured; report it.
レスポンスの規約
以下のすべてのエンドポイントでは、3 つのパターンが繰り返し登場します。レシピを簡潔にするため、ここでまとめて説明します。
dataエンベロープ。 読み取りでは{"data": ...}(オブジェクトまたは配列)が返されます。書き込みでは{"data": {...}}を送信し、結果はdataの下に返されます。エラー時はdataがerrorsに置き換わります(「エラー処理」を参照)。プロジェクトの.dataを確認し、存在しない場合は.errorsを確認してください。- 名前ではなく
gid。 すべての参照には文字列のgidを使用します。名前は先に gid に解決してください(ワークスペース、プロジェクト、ユーザー、タグについてはレシピ 9)。 - フィールドには
opt_fields。 コンパクトなレコードに含まれるのはgid、name、resource_typeのみです。カンマ区切りのopt_fieldsを追加して、ドット表記で関連情報(assignee.name、memberships.section.name)を展開します。gidは常に返されます。POST/PUT では、オプションをdataと並ぶoptionsオブジェクトにネストします。
主な操作
1. タスクの一覧表示(scripts/asana_tasks.sh)
同梱スクリプトを実行します(パスはこのスキルのディレクトリからの相対パスです)。このスクリプトは、プロジェクト、タグ、セクション、または担当者とワークスペースで絞り込んで /tasks に GET リクエストを送信し、opt_fields のリストを指定して、すべてのページで next_page.offset をたどり、TSV または JSONL を出力します。
scripts/asana_tasks.sh --project 1201234567890123 --limit 200
scripts/asana_tasks.sh --assignee me --workspace 1209876543210987 --completed-since now
- セレクターは 1 つだけ指定してください。
--project GID、--tag GID、--section GID、または--assignee GID --workspace GIDを使用します(担当者の指定にはワークスペースが必要です)。--assignee meは/users/meを使って呼び出し元を解決します。 --completed-since WHEN— ISO 8601、または未完了タスクのみを表示するnowを指定します(すべてを含める場合は省略します)。--fields LIST— リクエストするopt_fieldsを指定します。TSV の列は固定です(gid、name、completed、assignee、due_on、permalink_url)。追加のフィールドは--json出力にのみ含まれます。--limit Nは取得するタスク数の上限です(デフォルトは 100、0はすべて)。--page-size Nはリクエストごとのページサイズを指定します(1〜100、デフォルトは 100)。取得数と、切り捨てがあった場合の警告は stderr に出力されます。--jsonは TSV の代わりに、タスクオブジェクトを 1 行に 1 つずつ生の形式で出力します。- 終了コード:
0は成功、1はリクエスト失敗/API エラー/引数不正です(API 独自のerrors[].messageは stderr に出力されます)。
スクリプトでエラーが発生した場合は、内容を確認してください。通常の curl と jq だけで構成されています。references/api.md を参照してデバッグしてください。
2. 1 件のタスクを取得する
asana "${ASANA_BASE}/tasks/TASK_GID?opt_fields=name,notes,completed,assignee.name,due_on,projects.name,tags.name,parent.name,num_subtasks,custom_fields.name,custom_fields.display_value,permalink_url" \
| jq '.data'
opt_fields を指定しない場合、コンパクトなレコードのみが取得されます。タスクのコメントを読むには、レシピ 5 を参照してください。
3. タスクを作成する
フィールドは data の下にネストします。workspace、projects、parent のいずれかが必須です(単独のタスクには workspace が必要です)。
asana -X POST "${ASANA_BASE}/tasks" -d '{
"data": {
"name": "Draft the launch checklist",
"notes": "Plain-text body. Use html_notes for rich text.",
"workspace": "1209876543210987",
"projects": ["1201234567890123"],
"assignee": "me",
"due_on": "2026-06-15",
"followers": ["1200000000000001"]
}
}' | jq '.data | {gid, name, permalink_url}'
assignee と followers にはユーザーの gid(または me)を指定します。due_on は日付、due_at は ISO 8601 形式のタイムスタンプです。リッチテキストには html_notes を使用します(Asana の HTML サブセット)。カスタムフィールドの値は custom_fields: {"FIELD_GID": value} に指定します。
4. タスクを更新または完了する
PUT は、送信したフィールドのみを置き換えます(引き続き data でラップします)。タスクを完了するには completed を設定します。専用のエンドポイントはありません。
asana -X PUT "${ASANA_BASE}/tasks/TASK_GID" -d '{"data": {"completed": true}}' \
| jq '.data | {gid, completed, completed_at}'
asana -X PUT "${ASANA_BASE}/tasks/TASK_GID" -d '{"data": {"name": "Revised", "due_on": "2026-07-01"}}'
削除:asana -X DELETE "${ASANA_BASE}/tasks/TASK_GID" — 空の data: {} が返され、タスクはゴミ箱に移動します。
5. タスクにコメントする/アクティビティを読む(ストーリー)
ストーリーは、タスクのコメントとシステムアクティビティです。作成できるのはコメントのストーリーのみです。
# add a comment
asana -X POST "${ASANA_BASE}/tasks/TASK_GID/stories" \
-d '{"data": {"text": "Reproduced on main."}}' | jq '.data | {gid, created_at}'
# read comments only (filter out system activity client-side)
asana "${ASANA_BASE}/tasks/TASK_GID/stories?opt_fields=resource_subtype,text,created_by.name,created_at" \
| jq '.data[] | select(.resource_subtype=="comment_added") | {by: .created_by.name, text, created_at}'
リッチテキストのコメントには、text の代わりに html_text を使用します。
6. ワークスペース内のタスクを検索する(プレミアム)
高度な検索はワークスペース単位で行い、プレミアム限定です。オフセットによるページネーションには対応していません(結果は不安定で、上限は100件です)。フィルターで絞り込むか、created_at で並べ替え、created_at.before を使って手動でページを進めてください。「プロジェクト内のタスク/自分のタスク」のような通常の検索には、リストスクリプト(レシピ1)を使用してください。すべてのページを取得でき、無料プランでも利用できます。
asana -G "${ASANA_BASE}/workspaces/WORKSPACE_GID/tasks/search" \
--data-urlencode "text=launch" \
--data-urlencode "assignee.any=me" \
--data-urlencode "completed=false" \
--data-urlencode "sort_by=modified_at" \
--data-urlencode "opt_fields=name,assignee.name,due_on,permalink_url" \
| jq '.data[] | {gid, name, due_on}'
7. プロジェクトとセクション
asana -G "${ASANA_BASE}/projects" --data-urlencode "workspace=WORKSPACE_GID" \
--data-urlencode "archived=false" --data-urlencode "opt_fields=name,owner.name" \
| jq '.data[] | {gid, name}'
asana "${ASANA_BASE}/projects/PROJECT_GID?opt_fields=name,notes,owner.name,members.name" | jq '.data'
asana "${ASANA_BASE}/projects/PROJECT_GID/sections?opt_fields=name" | jq '.data[] | {gid, name}'
8. プロジェクト間およびセクション間でタスクを移動する
タスクは メンバーシップ を通じてプロジェクトに属します。専用の POST で、タスクの追加、削除、またはセクションへの配置を行います。成功すると、それぞれ空の data: {} が返されます。
asana -X POST "${ASANA_BASE}/tasks/TASK_GID/addProject" \
-d '{"data": {"project": "PROJECT_GID", "section": "SECTION_GID"}}'
asana -X POST "${ASANA_BASE}/tasks/TASK_GID/removeProject" -d '{"data": {"project": "PROJECT_GID"}}'
asana -X POST "${ASANA_BASE}/sections/SECTION_GID/addTask" -d '{"data": {"task": "TASK_GID"}}'
9. ワークスペース、ユーザー、プロジェクトを探す(gid の検索)
すべて gid で参照します。ここで名前から gid を解決します。
asana "${ASANA_BASE}/workspaces?opt_fields=name,is_organization" | jq '.data[] | {gid, name}'
asana -G "${ASANA_BASE}/users" --data-urlencode "workspace=WORKSPACE_GID" \
--data-urlencode "opt_fields=name,email" | jq '.data[] | {gid, name, email}'
asana "${ASANA_BASE}/users/me?opt_fields=name,email,workspaces.name" | jq '.data'
10. サブタスク、タグ、添付ファイル
asana "${ASANA_BASE}/tasks/TASK_GID/subtasks?opt_fields=name,completed" | jq '.data[] | {gid, name}'
asana -X POST "${ASANA_BASE}/tasks/TASK_GID/subtasks" -d '{"data": {"name": "A subtask"}}' | jq '.data.gid'
asana "${ASANA_BASE}/workspaces/WORKSPACE_GID/tags?opt_fields=name" | jq '.data[] | {gid, name}'
asana -X POST "${ASANA_BASE}/tasks/TASK_GID/addTag" -d '{"data": {"tag": "TAG_GID"}}'
asana "${ASANA_BASE}/tasks/TASK_GID/attachments?opt_fields=name,download_url" | jq '.data[] | {gid, name}'
添付ファイルはマルチパートフォームデータ(JSON ではありません)でアップロードします。references/api.md の「Attachments」セクションを参照してください。タスクの PUT でカスタムフィールドを設定するには、{"data": {"custom_fields": {"FIELD_GID": value}}} を指定します。
ページネーション
- オフセットトークン。 コレクションの GET(
/tasks、/projects、/users、/storiesなど)ではlimit(1~100)を指定でき、続きがある場合はnext_pageオブジェクトが返されます:{"offset": "...", "path": "...", "uri": "..."}。next_page.offsetを?offset=...として渡し、next_pageがnullになったら停止します。オフセットは不透明で、有効期限があります。API から渡されたものだけを再利用し、自分で作成しないでください。scripts/asana_tasks.shはタスクについてこの処理を行います。 - 検索ではオフセットなし。
/workspaces/{gid}/tasks/searchはoffsetを無視し、並び順が不安定な結果を100件までに制限します。created_atで並べ替え、created_at.beforeを使ってページを進めてください(レシピ6)。 - 非常に大きな結果セット(数万件)では、切り捨てを示すメッセージとともに
400が返ることがあります。再試行するのではなく、クエリを絞り込んでください。
レート制限
制限はワークスペースとトークンの組み合わせごとに、1分あたりで適用されます。
- 無料プランでは毎分150リクエスト、有料プランでは毎分1500リクエストです。検索は毎分60リクエストです。
- 同時実行数:GET は50件、書き込みは15件です。複製/エクスポートジョブはユーザーあたり同時に5件までに制限されます。
- コストベースの別の制限により、高コストなグラフトラバーサルが拒否されることがあります。ほとんどの呼び出し元がこの制限に達することはありません。
429 が返された場合は、Retry-After の秒数(指定がない場合は約30秒)だけ待機してから、バックオフして再試行してください。ポーリング間隔を短くしないでください。
エラー処理
すべてのエラーでは、data が errors に置き換わります:{"errors": [{"message": "...", "help": "...", "phrase": "..."}]}(phrase はサポートへの問い合わせ用として、500 の場合のみ表示されます)。.data を参照する前に .errors を確認してください。
400— 不正なリクエストです。パラメーターがない、または不正な形式である、dataエンベロープが不正である、あるいは結果セットが大きすぎて返せない場合に発生します。原因はmessageに記載されています。401— 認証情報がないか、拒否されました。ASANA_TOKENが設定されていることを確認してください(値は何でも構いません)。解決しない場合、このワークスペース用の認証情報が設定されていません。報告してください。402— 支払いが必要です。この機能にはプレミアム組織が必要です(例:タスク検索、一部のカスタムフィールド操作)。403— アクセスが禁止されています。トークンのユーザーには、そのオブジェクトへのアクセス権がありません。404— 見つかりません。gidが間違っているか、オブジェクトが存在しません。非公開オブジェクトも403ではなく404として表示される場合があります。429— レート制限に達しました。Retry-Afterに従って待機してから、バックオフを行って再試行してください。451— 法的な理由により利用できません(禁輸対象の IP)。5xx— Asana 側のエラーです。読み取りをバックオフ付きで再試行してください。エスカレーションする場合はerrors[].phraseを伝えてください。
さらに詳しく
references/api.md には、より詳細なカタログが記載されています。タスクの全フィールドとメンバーシップのモデル、html_notes/html_text のマークアップ、セクションと並べ替え、依存関係、カスタムフィールドと列挙型のオプション、添付ファイル(マルチパートアップロード)、タグ、チームとポートフォリオ、プロジェクトのステータス、Webhook(X-Hook-Secret のハンドシェイク)、バッチ API、監査ログイベントが含まれます。上記で扱っていないエンドポイントや、書き込み時の正確なボディ形式を確認する場合に参照してください。