atlassian-cli はコミュニティによる独立したオープンソースプロジェクトです。Atlassian と提携・関連しておらず、Atlassian による承認、推奨、後援のいずれも受けておらず、Atlassian が提供する公式 CLI(acli)でもありません。製品名は互換性を示す目的でのみ使用しています。

Jira REST API とは

Jira REST API は、課題、プロジェクト、遷移、コメントといった Jira のデータをプログラムから読み書きできるように Atlassian が公開している HTTP インターフェースです。Jira の Web UI でできることは、HTTP リクエストでも実行できます。Jira Cloud では、すべての呼び出しが https://your-domain.atlassian.net/rest/api/3/ 配下の URL に送られます。your-domain はサイト名です。

Cloud では 2 つのバージョンが稼働しています。バージョン 3(/rest/api/3/)が現行で、課題の説明などのリッチテキストのフィールドを、入れ子の JSON 構造である Atlassian Document Format(ADF)で表現します。バージョン 2(/rest/api/2/)も引き続きサポートされており、同じフィールドにプレーンな wiki マークアップを受け付けるため、手早いスクリプトではこちらのほうが扱いやすいことが多いです。どちらのバージョンもリソースのパスは同じで、主な違いはテキストのフィールドをどう表現するかにあります。

このガイドは生の API のリファレンスです。認証の方法、知っておく価値のあるエンドポイント、実際に動く curl コマンド、そしてページネーションの挙動を扱います。最後に、日常的な作業のたびに JSON を手書きしなくて済むよう、同じ呼び出しを短いコマンドに対応付けます。HTTP を完全に省きたい場合は、コマンドラインからの Jira API の記事が CLI 側から解説しています。

Server / Data Center についての注記:セルフホストの Jira は /rest/api/2/ と、自社ホストの異なるベースパスを使います。以下のエンドポイント名は同じですが、認証と ADF の扱いは異なります。ここでの例は Jira Cloud を対象としています。

認証と API トークン

スクリプトやターミナルでの作業では、Atlassian アカウントのメールアドレスと、パスワードの代わりに API トークンを使う HTTP Basic 認証が最も簡単です。実際のアカウントのパスワードは使わず、専用のトークンを作成してください。

  1. id.atlassian.com を開き、アカウントの Security セクションに移動します。
  2. Create API token を選び、ラベルを付けて値をコピーします。値が表示されるのは 1 回だけです。
  3. シェルの履歴やコミットするファイルに残らないよう、環境変数に保存します。
# Keep the token out of your command history
export JIRA_API_TOKEN="your-api-token-here"

# Verify auth by fetching the current user
curl -u "you@example.com:$JIRA_API_TOKEN" \
  -H "Accept: application/json" \
  "https://your-domain.atlassian.net/rest/api/3/myself"

-u フラグは curl に Basic 認証を送るよう指示するもので、email:token を base64 エンコードして Authorization ヘッダーに入れてくれます。アカウントの JSON とともに 200 が返れば認証は成功です。401 はメールアドレスかトークンが誤っていることを意味し、403 はたいてい、トークンは有効だがそのリソースへの権限が不足していることを意味します。

他のユーザーの代理で動作するアプリケーションでは、Basic 認証ではなく OAuth 2.0(3LO)を使ってください。このフローは特定の権限にスコープを絞った短命のアクセストークンを発行するもので、ユーザーに触れるものにはこちらが適切です。自分用の自動化や使い捨てのスクリプトであれば、API トークンで十分です。

実際によく使う主要エンドポイント

Jira Cloud は数百のエンドポイントを公開していますが、日々の作業のほとんどはごく一部で足ります。最初に使うことになるものを、それぞれが想定する HTTP メソッドとあわせて示します。

操作 メソッド エンドポイント
課題を 1 件取得 GET /rest/api/3/issue/{issueIdOrKey}
JQL で検索 POST /rest/api/3/search/jql
課題を作成 POST /rest/api/3/issue
課題を更新 PUT /rest/api/3/issue/{issueIdOrKey}
遷移の一覧・実行 GET / POST /rest/api/3/issue/{issueIdOrKey}/transitions
課題を割り当て PUT /rest/api/3/issue/{issueIdOrKey}/assignee
プロジェクトを一覧 GET /rest/api/3/project/search
フィールドを一覧(カスタム ID を調べる) GET /rest/api/3/field

ここでつまずきやすい点が 2 つあります。1 つ目は、Jira Cloud ではユーザーをユーザー名やメールアドレスではなく accountId で参照することです。これは GDPR に伴う変更です。2 つ目は、カスタムフィールドが customfield_10010 のような ID で指定され、その ID は /field エンドポイントで調べる必要があることです。どちらも、Server 時代の古いスニペットをコピーしていると見落としやすい点です。

curl の例、取得・検索・作成・遷移

以下の例はいずれも、上記のとおり JIRA_API_TOKEN をエクスポート済みであることを前提としています。your-domain、プロジェクトキー、課題キーはご自身のものに置き換えてください。

課題を 1 件取得する

curl -u "you@example.com:$JIRA_API_TOKEN" \
  -H "Accept: application/json" \
  "https://your-domain.atlassian.net/rest/api/3/issue/DEV-123?fields=summary,status,assignee"

fields クエリパラメーターを使うと、レスポンスを必要なフィールドだけに絞れます。指定しない場合、Jira は課題全体を返すため、応答が大きくなります。生の ADF ではなく HTML に描画されたテキストが欲しい場合は expand=renderedFields を追加してください。

JQL で検索する

現行の検索エンドポイントは、JQL クエリ、返すフィールド、ページサイズを含む POST ボディを受け取ります。

curl -u "you@example.com:$JIRA_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -X POST \
  --data '{
    "jql": "project = DEV AND status = \"In Progress\" ORDER BY created DESC",
    "maxResults": 50,
    "fields": ["summary", "status", "assignee"]
  }' \
  "https://your-domain.atlassian.net/rest/api/3/search/jql"

課題を作成する(ADF の description)

v3 が冗長になるのはここです。description フィールドは文字列ではなく ADF のドキュメントでなければなりません。

curl -u "you@example.com:$JIRA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -X POST \
  --data '{
    "fields": {
      "project": { "key": "DEV" },
      "issuetype": { "name": "Task" },
      "summary": "Investigate login 500 errors",
      "description": {
        "type": "doc",
        "version": 1,
        "content": [
          { "type": "paragraph",
            "content": [ { "type": "text", "text": "Users report a 500 on login." } ] }
        ]
      }
    }
  }' \
  "https://your-domain.atlassian.net/rest/api/3/issue"

たった 1 文のために大げさな ADF ブロックだと感じたなら、それは多くの人と同じ感想です。/rest/api/2/ に切り替えれば、"description": "Users report a 500 on login." をプレーンテキストとして渡せます。その代わり、v2 の書式指定は ADF ではなく wiki マークアップになります。

遷移を一覧して実行する

遷移の ID はワークフローごとに異なるため、まず利用できるものを取得し、次に目的の ID を POST します。

# 1. See which transitions are available for this issue
curl -u "you@example.com:$JIRA_API_TOKEN" \
  -H "Accept: application/json" \
  "https://your-domain.atlassian.net/rest/api/3/issue/DEV-123/transitions"

# 2. Apply one by its numeric id (e.g. 31 = Done)
curl -u "you@example.com:$JIRA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -X POST \
  --data '{ "transition": { "id": "31" } }' \
  "https://your-domain.atlassian.net/rest/api/3/issue/DEV-123/transitions"

遷移に成功すると 204 No Content が返り、本文は空です。更新後の課題が返ってくると思っていると驚く部分です。新しい状態が必要な場合は、課題をもう一度取得してください。

ページネーションとレート制限

JQL 検索エンドポイントはトークンベースのページネーションを使います。オフセットを指定する代わりに、各レスポンスから nextPageToken を読み取り、それを送り返して次のページを取得します。トークンが無くなったら終端です。

# First page: no token
curl -u "you@example.com:$JIRA_API_TOKEN" \
  -H "Content-Type: application/json" -X POST \
  --data '{ "jql": "project = DEV ORDER BY created DESC", "maxResults": 100, "fields": ["key"] }' \
  "https://your-domain.atlassian.net/rest/api/3/search/jql"

# Response contains "nextPageToken". Send it back for page two:
curl -u "you@example.com:$JIRA_API_TOKEN" \
  -H "Content-Type: application/json" -X POST \
  --data '{ "jql": "project = DEV ORDER BY created DESC", "maxResults": 100, "nextPageToken": "<token-from-previous-response>" }' \
  "https://your-domain.atlassian.net/rest/api/3/search/jql"

古い一覧エンドポイント(プロジェクトやコメントなど)は、今も startAtmaxResults のパラメーターによるオフセット方式のページネーションを使い、total の件数を返します。トークン方式は総件数を返さないため、あらかじめページ数を計算するのではなく、次のトークンが無くなるまでループします。

レート制限について、Jira Cloud はコストベースのモデルを採用しており、超過すると HTTP 429 と、待つべき秒数を示す Retry-After ヘッダーを返します。堅牢なスクリプトは、すぐに再試行するのではなく、このヘッダーを読んで待機すべきです。スクリプトごとにこの再試行ループを手書きするのは、まさにラッパーが取り除いてくれる定型作業です。

より扱いやすいラッパー、atlassian-cli

API を試したり、単発で呼び出したりするには curl が最適です。しかし繰り返し使うものを作り始めると、毎回同じ手間が発生します。ADF のエンコード、ページネーショントークンの受け渡し、429 のバックオフ処理、レスポンスからの JSON の取り出しです。atlassian-cli は、これらのエンドポイントをラップして 1 回のリクエストを 1 つのコマンドに縮める、MIT ライセンスの無料の Rust バイナリです。

Atlassian 自身の CLI との違い:atlassian-cli はコミュニティによる独立したオープンソースプロジェクトです。Atlassian が提供する公式 CLI(acli)ではありません。Atlassian と提携・関連しておらず、Atlassian による承認、推奨、後援、保守のいずれも受けていません。ベンダーによる一次サポートが必要なら公式の acli を使ってください。Jira、Confluence、Bitbucket、Jira Service Management をまたぎ、JSON、CSV、YAML の出力を標準で備えた 1 つのバイナリが欲しい場合は atlassian-cli を使ってください。

生のエンドポイントとコマンドの対応は素直です。

操作 REST API atlassian-cli
課題を取得 GET /issue/DEV-123 jira issue get DEV-123
検索 POST /search/jql jira issue search --jql "..."
作成 POST /issue jira issue create ...
遷移 POST /issue/DEV-123/transitions jira issue transition DEV-123 --transition "Done"
割り当て PUT /issue/DEV-123/assignee jira issue assign DEV-123 --assignee user@example.com

認証は一度きりで、あとはトークン、ベース URL、ADF のエンコード、ページネーションを CLI が処理します。先ほど ADF ブロック全体を必要とした作成コマンドは 1 行になり、検索は jq にそのままパイプできる整った JSON を返します。

# One-time login stores the profile; the API token is the same one from above
atlassian-cli auth login --profile work \
  --base-url https://your-domain.atlassian.net \
  --email you@example.com --token "$JIRA_API_TOKEN" --default

# Create an issue: plain text, no ADF ceremony
atlassian-cli jira issue create --project DEV --issue-type Task \
  --summary "Investigate login 500 errors"

# Search and get JSON out, pagination handled automatically
atlassian-cli jira issue search \
  --jql "project = DEV AND status = 'In Progress'" \
  --format json | jq '.[].key'

# Transition by name instead of hunting for a numeric id
atlassian-cli jira issue transition DEV-123 --transition "Done"

遷移コマンドが名前の "Done" をそのまま受け取っている点に注目してください。遷移 ID の 31 を調べるための別の呼び出しは不要です。CLI が課題のワークフローに照らして解決してくれます。すべてのコマンドは --format json|csv|yaml も受け付けるため、同じ呼び出しの結果を後処理なしでスプレッドシートやスクリプト、別のツールに渡せます。全体像はコマンドリファレンスを、複数のプロファイルの管理は認証ガイドをご覧ください。

どちらの方法が常に優れているというものではありません。デバッグ中、CLI が対応していないエンドポイントを呼ぶとき、既存のプログラムに 1 回のリクエストを埋め込むときは、生の curl を使ってください。日常的な Jira の作業を自動化していて、認証、ADF、ページネーションを毎回解決し直したくないときは CLI を使ってください。ターミナルから Jira を管理する全体像は、Jira CLI 完全ガイドがプロジェクト、スプリント、一括操作を扱っています。

atlassian-cli を試す

Jira、Confluence、Bitbucket、JSM に対応する無料のバイナリ 1 つ。定型作業を省けます。

atlassian-cli をインストール

よくある質問

Jira Cloud の REST API のベース URL は何ですか

Jira Cloud のベース URL は https://your-domain.atlassian.net/rest/api/3/ で、your-domain はサイト名です。バージョン 3 が Cloud における現行の REST API で、リッチテキストのフィールドに Atlassian Document Format を使います。バージョン 2 も /rest/api/2/ で引き続き利用でき、それらのフィールドにはプレーンな wiki マークアップを受け付けます。

Jira REST API の認証はどう行いますか

スクリプトで最も簡単な方法は、Atlassian アカウントのメールアドレスと、パスワードの代わりに API トークンを使う HTTP Basic 認証です。id.atlassian.com の Security でトークンを作成し、-u "you@example.com:$JIRA_API_TOKEN" で curl に渡します。ユーザーの代理で動作するアプリでは、代わりに OAuth 2.0(3LO)を使ってください。アカウントのパスワードを直接使ってはいけません。

v3 の REST API で description フィールドが失敗するのはなぜですか

v3 の API は、description やコメント本文などのリッチテキストのフィールドを、単なる文字列ではなく入れ子の JSON 構造である Atlassian Document Format(ADF)で受け取ります。プレーンな文字列を送ると 400 エラーが返ります。ADF のドキュメントを組み立てるか、それらのフィールドにプレーンテキストを受け付ける v2 の API に切り替えてください。CLI ラッパーはプレーンテキストを受け取って ADF を組み立てるため、この手間を隠してくれます。

Jira REST API の結果をページネーションするにはどうしますか

現行の JQL 検索エンドポイントである POST /rest/api/3/search/jql は、トークンベースのページネーションを使います。結果がまだある場合、各レスポンスには nextPageToken が含まれます。次のリクエストでそれを送り返すと続きのページを取得でき、トークンが無くなったら終了します。古い一覧エンドポイントは、今も startAtmaxResults のオフセットと総件数を使います。

Jira REST API を使うにはコードを書く必要がありますか

いいえ。すべてのエンドポイントはターミナルやシェルスクリプトから curl で呼び出せます。手早い作業や自動化にはそれで十分です。繰り返し行う作業には、atlassian-cli のようなラッパーが同じエンドポイントを短いコマンドに対応付け、認証、ページネーション、ADF を代わりに処理し、JSON、CSV、YAML を直接返してくれます。

関連リソース