atlassian-cli is an independent, community open-source project, not affiliated with, endorsed by, or sponsored by Atlassian, and is not Atlassian's official CLI (acli). Product names are used only to identify compatibility.
The Atlassian REST API is really four APIs
If you have ever gone looking for "the" Atlassian REST API, you have probably noticed there isn't one. Atlassian does not ship a single unified API. Jira Cloud, Confluence Cloud, and Bitbucket Cloud each expose their own REST API, on a different base URL, with a different query language and a different pagination model. Jira Service Management adds a fourth surface layered onto the Jira site. So a script that touches all three products has to speak three dialects at once.
None of these APIs are hard on their own. The friction comes from the seams between them: you authenticate one way for Jira and Confluence, another way for Bitbucket; you page results one way here and another way there; you learn JQL for issues and CQL for pages. Here is the shape of the landscape:
| Product | REST base path | Query language | Pagination | atlassian-cli group |
|---|---|---|---|---|
| Jira Cloud | /rest/api/3 |
JQL | offset (startAt) & cursor on newer endpoints |
jira issue, jira bulk |
| Jira Service Management | /rest/servicedeskapi |
filters (no query language) | offset (start / limit) |
jsm request, jsm queue |
| Confluence Cloud | /wiki/api/v2 |
CQL (search) | cursor (Link header) |
confluence page, confluence search |
| Bitbucket Cloud | api.bitbucket.org/2.0 |
query params (q=) |
page (pagelen + next URL) |
bitbucket repo, bitbucket pr |
Jira also carries a separate Agile API under /rest/agile/1.0 for boards and sprints, and Confluence still serves its older v1 endpoints under /wiki/rest/api alongside v2. The point is not to memorize every path. It is that "call the Atlassian API" is never one job. It is four.
One binary, one command shape
A CLI wrapper collapses those four surfaces into one. atlassian-cli is a single Rust binary that maps every product onto the same command shape: atlassian-cli <product> <target> <verb> [flags]. You learn the pattern once and reuse it everywhere, whether you are searching Jira issues, listing Confluence pages, or reviewing Bitbucket pull requests.
# Same verb, three different APIs, one consistent surface
atlassian-cli jira issue search --jql "project = DEV" --limit 5
atlassian-cli confluence page list --space DEV --limit 5
atlassian-cli bitbucket --workspace myteam repo list --limit 5
Every command accepts the same global flags: --format <table|json|csv|yaml|quiet|markdown>, --profile <name> to pick an auth profile, and --envelope to wrap list output in {"data": [...], "count": N} for cleaner downstream parsing. That uniformity is the whole value: the JSON that comes out of a Jira search and a Bitbucket listing feeds the same jq pipeline.
How this differs from Atlassian's official acli
atlassian-cli is an independent, community open-source project. It is not Atlassian's official CLI (acli) and is not affiliated with Atlassian. Use the official acli if you want first-party vendor support; use atlassian-cli if you want a single free MIT-licensed binary that spans Jira, Confluence, Bitbucket, and Jira Service Management with one command grammar.
Authentication: one token scheme is not enough
The first place the "four APIs" reality bites is credentials. Jira, Confluence, and Jira Service Management all live on the same Atlassian Cloud site, so they accept the same thing: your account email plus an API token, sent as HTTP Basic auth. Bitbucket Cloud is a separate product with its own credential model, historically an app password and now app-scoped access tokens. So a raw script juggles two headers against two hosts.
atlassian-cli folds both into a profile. You authenticate once, and each command reuses the stored credentials for the right product:
# Store an Atlassian Cloud site profile (Jira / Confluence / JSM)
atlassian-cli auth login \
--profile work \
--base-url https://your-site.atlassian.net \
--email you@example.com \
--token "$ATLASSIAN_API_TOKEN" \
--default
# Confirm the profile resolves and the token is valid
atlassian-cli auth whoami --profile work
atlassian-cli auth test --profile work
Bitbucket credentials are stored per profile too, which is why auth logout --bitbucket can drop only the Bitbucket token while leaving the Atlassian Cloud one intact. If you are deciding which credential type to generate in the first place, the trade-offs between an API token and a personal access token are covered in Atlassian API token vs PAT, and the full flow lives in the authentication guide.
Query languages: JQL, CQL, and query params
Search is where the three products diverge the most. Jira filters issues with JQL. Confluence filters pages, blog posts, and attachments with CQL, a close cousin of JQL that targets different objects and fields. Bitbucket has no query language at all; you filter repositories and pull requests with plain query parameters. atlassian-cli surfaces each one where it belongs, so you pass JQL to jira commands and CQL to confluence commands without translating between HTTP shapes:
# Jira: JQL selects issues
atlassian-cli jira issue search \
--jql "project = DEV AND status = 'In Progress' order by updated desc" \
--format json | jq '.[].key'
# Confluence: CQL selects pages and other content
atlassian-cli confluence search cql \
"space = DEV and type = page and title ~ 'runbook'" --limit 10
# Bitbucket: filter pull requests by state, no query language needed
atlassian-cli bitbucket --workspace myteam pr list api-service --state OPEN --limit 10
Because every one of these returns the same structured output under --format json, you can build cross-product reports without special-casing each API. Count open bugs in Jira, list stale pages in Confluence, and tally open PRs in Bitbucket, all with the same | jq reflex. For a deeper CQL walkthrough see the Confluence REST API guide, and for JQL patterns see the Jira REST API guide.
Pagination and rate limits, handled for you
Pagination is the quiet tax on cross-product scripting. Jira's classic endpoints use offset paging with startAt and maxResults. Confluence v2 uses cursor paging and hands you the next page through a Link header. Bitbucket returns a next URL alongside a pagelen. Three products, three loops to write, three off-by-one bugs waiting to happen.
The CLI hides all of it. You ask for a result set with --limit, and it walks whichever pagination model the underlying API uses until it has what you asked for. Bulk subcommands go further and add throttling on top:
# Preview a bulk change first, always
atlassian-cli jira bulk transition \
--jql "project = DEV AND status = Open" \
--transition "In Progress" \
--dry-run
# Bulk export across a whole project, pagination handled automatically
atlassian-cli jira bulk export \
--jql "project = DEV" \
--output issues.json --format json
Atlassian Cloud APIs return a 429 response with a Retry-After hint when you push too hard. atlassian-cli respects that signal and backs off automatically, so a long-running export or a large jira bulk job throttles itself rather than failing. Bulk commands also accept --concurrency <n> (default 4) so you can dial parallelism up on generous plans or down on stricter ones. The bulk transition runbook shows a production-ready version with confirmation prompts.
A cross-product script
Here is where spanning the APIs pays off. A single script can pull a release snapshot from all three products, because each command emits the same JSON regardless of which API answered:
#!/bin/bash
# Release snapshot across Jira, Confluence, and Bitbucket
set -euo pipefail
PROFILE="work"
WS="myteam"
# 1. Open issues still blocking the release (Jira REST API)
atlassian-cli jira issue search --profile "$PROFILE" \
--jql "project = DEV AND fixVersion = '2.0' AND status != Done" \
--format json | jq 'length'
# 2. Release-notes pages tagged for review (Confluence REST API)
atlassian-cli confluence search cql --profile "$PROFILE" \
"space = DEV and label = release-notes" --format json | jq 'length'
# 3. Open pull requests targeting the release branch (Bitbucket REST API)
atlassian-cli bitbucket --profile "$PROFILE" --workspace "$WS" \
pr list api-service --state OPEN --format json | jq 'length'
echo "Release snapshot complete."
Written against the raw REST APIs, that script would carry three auth setups, three base URLs, and three pagination helpers. Through the CLI it is three lines that all speak the same JSON. This is the practical core of the cross-product angle covered in one CLI for Jira, Confluence, and Bitbucket.
When to call the raw REST API directly
A CLI is not a replacement for the API; it is a shortcut for the common paths. There are still good reasons to reach for the raw endpoints:
- An endpoint the CLI does not wrap. The Atlassian REST surface is enormous. For a niche endpoint, call it directly with
curland your API token, then bring the common operations back to the CLI. - Webhook payloads and event handlers. When Atlassian calls you, you are parsing raw JSON regardless of any CLI.
- Fine-grained field control. The CLI exposes the fields most workflows need; a bespoke integration may want the full raw response.
A pragmatic split is to script everyday operations through atlassian-cli and drop to raw HTTP only for the long tail. Because the CLI reads the same profile and token you would use in a curl call, moving between the two costs nothing. The full inventory of what the CLI wraps is in the command reference, and the wider terminal workflow is in the atlassian-cli guide.
FAQ
Is there a single Atlassian REST API for Jira, Confluence, and Bitbucket?
No. Atlassian does not ship one unified API. Jira Cloud, Confluence Cloud, and Bitbucket Cloud each expose their own REST API with a different base URL, its own query language (JQL, CQL, or query parameters), and a different pagination model. Jira Service Management adds a fourth surface under the Jira site. atlassian-cli hides these differences behind one consistent set of commands.
Do I need a separate API token for each Atlassian product?
Jira, Confluence, and Jira Service Management live on the same Atlassian Cloud site and accept the same account email plus API token over Basic auth. Bitbucket Cloud is a separate product with its own credentials, historically an app password and now app-scoped tokens. atlassian-cli stores each in a profile, so you authenticate once and reuse it everywhere.
What is the difference between JQL and CQL?
JQL (Jira Query Language) filters issues in Jira, while CQL (Confluence Query Language) filters pages, blog posts, and attachments in Confluence. They share a similar syntax but target different objects and fields. Bitbucket has no equivalent query language; you filter repositories and pull requests with query parameters instead. With atlassian-cli you pass JQL to jira commands and CQL to confluence commands.
Can one CLI call the Jira, Confluence, and Bitbucket APIs?
Yes. atlassian-cli is a single Rust binary that wraps all four products. The same command shape (verb, target, flags) works whether you are searching Jira issues, listing Confluence pages, or reviewing Bitbucket pull requests, and every command supports --format json for scripting. It is an independent open-source project, not Atlassian's official CLI.
One CLI across every Atlassian REST API
Install the single MIT-licensed binary and script Jira, Confluence, Bitbucket, and JSM from one terminal.
Try atlassian-cli →