This is the abridged developer documentation for Bitbucket CLI
# Bitbucket CLI
> Clone repos, manage PRs, and automate workflows — all from your terminal. If you know GitHub's gh, you'll feel right at home.
## Install [Section titled “Install”](#install) Requires [Bun](https://bun.sh) 1.0+ runtime. * npm
```bash
npm install -g @pilatos/bitbucket-cli
```
* pnpm
```bash
pnpm add -g @pilatos/bitbucket-cli
```
* Bun
```bash
bun install -g @pilatos/bitbucket-cli
```
```bash
bb auth login # authenticate
bb repo clone myworkspace/myrepo # clone a repo
bb pr create -t "My awesome feature" # create a PR
bb pr list # list open PRs
```
*** ## What can you do? [Section titled “What can you do?”](#what-can-you-do) Repository Management Clone, create, list, view, and delete repositories.
```bash
bb repo clone workspace/repo
bb repo create my-new-project
bb repo list -w myworkspace
```
Pull Request Workflows Full PR lifecycle — create, review, approve, merge.
```bash
bb pr create -t "Add feature"
bb pr approve 42
bb pr merge 42 --strategy squash
```
Code Review View diffs, checkout PR branches, inspect checks.
```bash
bb pr diff 42
bb pr checkout 42
bb pr checks 42
```
Jump to the Web UI Open Bitbucket pages — PRs, files, commits, settings — in your browser.
```bash
bb browse 42
bb browse src/cli.ts:20
bb browse --pipelines
```
Scripting & Automation JSON output on every command. Built for CI/CD.
```bash
bb pr list --json | jq '.pullRequests[].title'
```
*** ## PR Workflows [Section titled “PR Workflows”](#pr-workflows) Task-focused guides for the shortest path to a result. [Create and update PRs ](/commands/pr/create-and-edit/)Open pull requests, edit titles and descriptions. [Review and merge ](/commands/pr/review-and-merge/)Approve, decline, mark ready, merge with strategy controls. [Diffs and checkout ](/commands/pr/diff-and-checkout/)View patches, open browser diffs, checkout branches locally. [Comments and reviewers ](/commands/pr/comments/)Script-friendly review comments and reviewer management. [All PR commands ](/commands/pr/) *** ## Explore [Section titled “Explore”](#explore) [Command Reference ](/commands/pr/)All commands and options. [Scripting Guide ](/guides/scripting/)JSON output, exit codes, shell patterns. [CI/CD Integration ](/guides/cicd/)GitHub Actions, GitLab CI, Jenkins, and more. [Troubleshooting ](/help/troubleshooting/)Common issues and solutions. *** ## Community [Section titled “Community”](#community) This is an **unofficial**, community-maintained CLI. Not affiliated with Atlassian. * [GitHub Repository](https://github.com/0pilatos0/bitbucket-cli) * [Report Issues](https://github.com/0pilatos0/bitbucket-cli/issues) * [Contribute](https://github.com/0pilatos0/bitbucket-cli/blob/main/CONTRIBUTING.md)
# Auth Commands
> Authentication commands reference
Manage authentication with Bitbucket. Global options available on all auth commands: `--json`, `--no-color`. ## `bb auth login` [Section titled “bb auth login”](#bb-auth-login) Authenticate with Bitbucket using OAuth (default) or an API token.
```bash
bb auth login [options]
```
### Options [Section titled “Options”](#options) | Option | Description | | -------------------------------- | ----------------------------------------------------------------------------------------------------- | | `-u, --username ` | Bitbucket username (implies API token auth) | | `-p, --password ` | Bitbucket API token (implies API token auth) | | `--app-password` | Use API token authentication instead of OAuth (legacy flag name — uses API tokens, not app passwords) | | `--client-id ` | Custom OAuth consumer client ID | | `--client-secret ` | Custom OAuth consumer client secret | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples)
```bash
# Login with OAuth (opens browser)
bb auth login
# Login with a custom OAuth consumer
bb auth login --client-id YOUR_KEY --client-secret YOUR_SECRET
# Login with API token
bb auth login -u myuser -p your-api-token
# Login using environment variables (API token)
export BB_USERNAME=myuser
export BB_API_TOKEN=your-api-token
bb auth login
```
### How It Works [Section titled “How It Works”](#how-it-works) **OAuth flow (default):** 1. The CLI starts a local callback server and opens your browser 2. You authorize the CLI on Bitbucket’s consent screen 3. Bitbucket redirects back to the CLI with an authorization code 4. The CLI exchanges the code for access and refresh tokens 5. Tokens are stored in your config file 6. Access tokens expire after 2 hours and are refreshed automatically **API token flow (with `-u`/`-p` or `--app-password`):** 1. You provide your Bitbucket username and API token 2. The CLI stores the credentials in your config file 3. The CLI verifies the credentials by fetching your user information 4. If verification fails, credentials are not saved ### Auth Method Detection [Section titled “Auth Method Detection”](#auth-method-detection) The CLI determines which flow to use based on flags: | Condition | Auth Method | | -------------------------- | ----------- | | No flags | OAuth | | `-u` or `-p` provided | API Token | | `--app-password` flag | API Token | | `BB_API_TOKEN` env var set | API Token | ### Required Scopes (API Token) [Section titled “Required Scopes (API Token)”](#required-scopes-api-token) When using API tokens, your token needs these scopes: * `read:user:bitbucket` — verify your identity * `read:repository:bitbucket` — list and view repositories * `write:repository:bitbucket` — create repositories * `admin:repository:bitbucket` — delete repositories (optional) * `read:pullrequest:bitbucket` — list and view pull requests * `write:pullrequest:bitbucket` — create, edit, merge, approve, decline pull requests OAuth scopes are requested automatically during authorization. See the [Authentication guide](/getting-started/authentication/) for detailed setup instructions. *** ## `bb auth logout` [Section titled “bb auth logout”](#bb-auth-logout) Log out of Bitbucket and remove stored credentials.
```bash
bb auth logout [options]
```
### Options [Section titled “Options”](#options-1) | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
bb auth logout
```
### What Gets Removed [Section titled “What Gets Removed”](#what-gets-removed) * **OAuth**: Revokes the token on Bitbucket’s side, then removes `oauthAccessToken`, `oauthRefreshToken`, `oauthExpiresAt`, `authMethod`, and custom OAuth consumer credentials from the config file. * **API Token**: Removes `username` and `apiToken` from the config file. Other settings like `defaultWorkspace`, `skipVersionCheck`, and `versionCheckInterval` are preserved. *** ## `bb auth status` [Section titled “bb auth status”](#bb-auth-status) Show current authentication status and account information.
```bash
bb auth status [options]
```
### Options [Section titled “Options”](#options-2) | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-2)
```bash
# Check authentication status
bb auth status
# Get status as JSON
bb auth status --json
```
### Output [Section titled “Output”](#output) When authenticated with OAuth:
```plaintext
✓ Logged in to Bitbucket
Authentication: OAuth
Username: myuser
Display name: My Name
Account ID: 123456789
Token expires: in 1h 42m
```
When authenticated with API token:
```plaintext
✓ Logged in to Bitbucket
Authentication: API Token
Username: myuser
Display name: My Name
Account ID: 123456789
```
When not authenticated:
```plaintext
ℹ Not logged in
Run bb auth login to authenticate.
```
*** ## `bb auth token` [Section titled “bb auth token”](#bb-auth-token) Print the current access token.
```bash
bb auth token [options]
```
### Options [Section titled “Options”](#options-3) | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-3)
```bash
# Print the token
bb auth token
# Get token as JSON
bb auth token --json
```
### Output [Section titled “Output”](#output-1) * **OAuth**: Prints the bearer access token (automatically refreshes if expired). * **API Token**: Prints a base64-encoded `username:apiToken` string suitable for HTTP Basic auth headers. ### Use Cases [Section titled “Use Cases”](#use-cases) This is useful for: * Debugging authentication issues * Using the token with other tools or scripts * Verifying token format Caution Keep your token secure! Anyone with this token can access your Bitbucket account with the scopes you’ve granted.
# Browse Command — Open Bitbucket Pages from the Terminal
> Open Bitbucket Cloud web pages — repo home, files, branches, commits, pull requests, pipelines, settings — directly from the CLI, or print the URL for scripts.
`bb browse` opens Bitbucket Cloud web pages — repo home, files, branches, commits, pull requests, pipelines, settings, and more — in your default browser. Mirrors `gh browse`. It also doubles as a script-friendly URL builder: pass `--no-browser` to print the URL instead, or `--json url` for machine-readable output. Global options: `--json [fields]`, `--jq `, `--no-color`, `-w, --workspace`, `-r, --repo`. ## `bb browse` [Section titled “bb browse”](#bb-browse)
```bash
bb browse [target] [options]
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `target` | Optional positional. Resolved by shape: pure digits → PR id, 7–40 hex chars → commit SHA, anything else → file/dir path. Append `:` to a path for a line anchor (e.g. `src/cli.ts:42`). | ### Resource flags [Section titled “Resource flags”](#resource-flags) Resource flags are mutually exclusive — pick at most one. They cannot be combined with a positional `target` (except `--branch`, which is a modifier that pairs with a path target). | Option | Opens | | ----------------- | --------------------------------------------------------------------- | | `--pr ` | A specific pull request | | `--prs` | The pull-requests list | | `--pull-requests` | Alias for `--prs` | | `--branch ` | The branch source tree (or, with ``, that path on the branch) | | `--branches` | The branches list | | `--commit [sha]` | A specific commit (defaults to current HEAD when no SHA is given) | | `--commits` | The commits list | | `--pipelines` | The pipelines page | | `--pipeline ` | A specific pipeline run | | `--downloads` | The downloads page | | `--issue ` | A specific issue | | `--issues` | The issue tracker | | `--wiki` | The wiki | | `--settings` | Repository admin / settings | ### Behavior flags [Section titled “Behavior flags”](#behavior-flags) | Option | Description | | ------------------ | --------------------------------------------------- | | `-n, --no-browser` | Print the URL to stdout instead of opening it | | `--json [fields]` | Emit `{ "url": "..." }` (does not open the browser) | ### Examples [Section titled “Examples”](#examples)
```bash
# Repo home
bb browse
# A file at the current branch
bb browse src/cli.ts
# A file at a specific line
bb browse src/cli.ts:42
# A file on a specific branch
bb browse --branch release/2.0 src/cli.ts
# Just the branch tree
bb browse --branch release/2.0
# Pull request #217 (positional shorthand)
bb browse 217
# Pull request #217 (explicit)
bb browse --pr 217
# Pull-request list
bb browse --prs
# A commit by SHA
bb browse abc1234
# Current HEAD commit
bb browse --commit
# Pipelines tab
bb browse --pipelines
# Repo settings
bb browse --settings
# Print the URL only — useful in scripts and pipes
bb browse --pr 217 --no-browser
# Script-friendly URL retrieval
bb browse --pr 217 --json url
```
### Notes [Section titled “Notes”](#notes) * **Positional disambiguation.** A bare `` is treated as a pull request id (the most common case). Use `--issue ` to open an issue with the same number. * **Branch defaulting.** When you give a path target without `--branch`, the CLI uses your current git branch (`git rev-parse --abbrev-ref HEAD`). Outside a git checkout (when using `--workspace`/`--repo` overrides), it falls back to the literal `HEAD` segment, which Bitbucket resolves server-side to the repository’s default branch. * **URL encoding.** Workspace and repo slugs, branch names, and path segments are URL-encoded individually, so branches with slashes (`feature/foo`) and paths or names with spaces still produce valid URLs. Path separators (`/` between segments) are preserved. * **No API call required for most variants.** `bb browse` is primarily a URL-construction command; only `--commit` (no SHA) makes a local `git rev-parse HEAD` call. * **`--json` does not open the browser.** Either output mode (JSON or `--no-browser`) suppresses the open action, so scripts can capture the URL deterministically. ### Output [Section titled “Output”](#output) In default mode, `bb browse` prints a short status line and shells out to the [`open`](https://www.npmjs.com/package/open) helper to launch the URL. With `--no-browser`:
```text
https://bitbucket.org/myworkspace/myrepo/pull-requests/217
```
With `--json`:
```json
{
"url": "https://bitbucket.org/myworkspace/myrepo/pull-requests/217"
}
```
Combine with `--jq` to pluck just the URL string:
```bash
bb browse --pr 217 --json url --jq '.url'
```
### Related [Section titled “Related”](#related) * [`bb pr diff --web`](/commands/pr/diff-and-checkout/) — open the PR diff page directly in the browser. * [Repository Context](/guides/repository-context/) — how the CLI infers workspace and repo from your current directory. * [Scripting & Automation](/guides/scripting/) — capture URLs from `bb browse` to feed other tools.
# Completion Commands
> Shell completion utilities reference
Enable tab completion for bash, zsh, or fish shells. Global options available on completion commands: `--json`, `--no-color`. ## Supported Shells [Section titled “Supported Shells”](#supported-shells) | Shell | Config File | | ----- | ---------------------------- | | bash | `~/.bashrc` | | zsh | `~/.zshrc` | | fish | `~/.config/fish/config.fish` | ## `bb completion install` [Section titled “bb completion install”](#bb-completion-install) Install shell completions for your current shell.
```bash
bb completion install [options]
```
### Options [Section titled “Options”](#options) | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | The installer auto-detects your shell and adds the necessary configuration. ### Post-Installation [Section titled “Post-Installation”](#post-installation) After installing, restart your shell or source your config:
```bash
# Bash
source ~/.bashrc
# Zsh
source ~/.zshrc
# Fish
source ~/.config/fish/config.fish
```
### Examples [Section titled “Examples”](#examples)
```bash
# Install completions
bb completion install
# Install with JSON output
bb completion install --json
# Test it works
bb # Shows: auth, repo, pr, snippet, browse, config, completion
bb repo # Shows: clone, create, list, view, delete, default-reviewers
```
*** ## `bb completion uninstall` [Section titled “bb completion uninstall”](#bb-completion-uninstall) Remove shell completions.
```bash
bb completion uninstall [options]
```
### Options [Section titled “Options”](#options-1) | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
# Remove completions
bb completion uninstall
# Remove completions with JSON output
bb completion uninstall --json
```
*** ## What Gets Completed [Section titled “What Gets Completed”](#what-gets-completed) Tab completion works for: * **Commands**: `auth`, `repo`, `pr`, `snippet`, `browse`, `config`, `completion` * **Subcommands**: `login`, `clone`, `create`, `list`, etc. * **Options**: `--json`, `--no-color`, `--workspace`, `--repo`, `--help` `-w` is reserved as the global shorthand for `--workspace`. ### Example Session [Section titled “Example Session”](#example-session)
```bash
$ bb pr
pr
$ bb pr
activity approve checks checkout comments create decline
diff edit list merge ready reviewers view
$ bb pr create --
--body --close-source-branch --destination
--draft --help --repo
--source --title --workspace
```
# Config Commands
> Configuration commands reference
Manage CLI configuration settings. Global options available on all config commands: `--json`, `--no-color`. ## Configuration File [Section titled “Configuration File”](#configuration-file) Configuration is stored in a JSON file at: * **Linux/macOS**: `~/.config/bb/config.json` * **Windows**: `%APPDATA%\bb\config.json` ## Available Settings [Section titled “Available Settings”](#available-settings) The configuration file stores your CLI settings and authentication credentials. | Key | Description | | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | `username` | Bitbucket username (set during `auth login`) | | `apiToken` | Bitbucket API token (set during `auth login`, masked in output) | | `defaultWorkspace` | Default workspace for commands | | `skipVersionCheck` | Disable update notifications (default: false) | | `versionCheckInterval` | Days between update checks (default: 1) | | `prCreateIncludeDefaultReviewers` | Auto-add the repo’s default reviewers on `bb pr create` (default: false) | | `lastVersionCheck` | Timestamp of the last update check. Auto-managed by the CLI; read-only from a user’s perspective (do not set manually) | ### Configuration File Format [Section titled “Configuration File Format”](#configuration-file-format) The config file is stored as JSON:
```json
{
"username": "myuser",
"apiToken": "***",
"defaultWorkspace": "myworkspace",
"skipVersionCheck": false,
"versionCheckInterval": 1,
"prCreateIncludeDefaultReviewers": false
}
```
## `bb config get` [Section titled “bb config get”](#bb-config-get) Get a configuration value.
```bash
bb config get
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | ----------------------------- | | `key` | Configuration key to retrieve | ### Examples [Section titled “Examples”](#examples)
```bash
# Get default workspace
bb config get defaultWorkspace
# Get username
bb config get username
# Get output as JSON
bb config get defaultWorkspace --json
```
### Options [Section titled “Options”](#options) | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | *** ## `bb config set` [Section titled “bb config set”](#bb-config-set) Set a configuration value.
```bash
bb config set
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | -------- | --------------------------------- | | `key` | Configuration key to set | | `value` | Value to set (parsed by key type) | ### Typed Value Parsing [Section titled “Typed Value Parsing”](#typed-value-parsing) `bb config set` validates and stores typed values for known typed keys: | Key | Accepted values | Stored type | | --------------------------------- | ------------------------- | ----------- | | `defaultWorkspace` | Any string | string | | `skipVersionCheck` | `true` or `false` | boolean | | `versionCheckInterval` | Positive integer (`>= 1`) | number | | `prCreateIncludeDefaultReviewers` | `true` or `false` | boolean | ### Examples [Section titled “Examples”](#examples-1)
```bash
# Set default workspace
bb config set defaultWorkspace myworkspace
# Disable update notifications
bb config set skipVersionCheck true
# Check for updates weekly instead of daily
bb config set versionCheckInterval 7
# Invalid values are rejected
bb config set skipVersionCheck maybe
# Get output as JSON
bb config set defaultWorkspace myworkspace --json
```
Example JSON output for typed keys:
```json
{ "success": true, "key": "skipVersionCheck", "value": true }
```
### Options [Section titled “Options”](#options-1) | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | Caution Use `bb auth login` to set credentials instead of manually setting `username` and `apiToken`. *** ## `bb config list` [Section titled “bb config list”](#bb-config-list) List all configuration values.
```bash
bb config list [options]
```
### Options [Section titled “Options”](#options-2) | Option | Description | | -------- | -------------- | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-2)
```bash
# List all config
bb config list
# List as JSON for scripting
bb config list --json
```
### Output [Section titled “Output”](#output)
```plaintext
Config file: /Users/you/.config/bb/config.json
KEY VALUE
---------------- ------------------------
username myuser
apiToken ********
defaultWorkspace myworkspace
skipVersionCheck false
```
# PR Commands
> Task-based reference for creating, reviewing, and merging pull requests
Manage pull requests in Bitbucket repositories. Global options available on all PR commands: `--json [fields]`, `--jq `, `--no-color`, `-w, --workspace`, `-r, --repo`. `--json` accepts an optional comma-separated field list to project the output, and `--jq` filters the JSON in-process — see [JSON Output](/reference/json-output/) for the full reference. ## Choose a Workflow Task-based [Section titled “Choose a Workflow ”](#choose-a-workflow-) [Create, edit, and view ](/commands/pr/create-and-edit/)Open pull requests, update metadata, and inspect details with JSON output support. [Activity and checks ](/commands/pr/activity-and-checks/)Inspect activity history and CI/build status before approving or merging. [Diff and checkout ](/commands/pr/diff-and-checkout/)Review patch output, fetch PR branches locally, and open browser diffs. [Review and merge ](/commands/pr/review-and-merge/)Approve, decline, mark drafts ready, and merge with explicit strategy control. [Comments ](/commands/pr/comments/)List, add, edit, and delete general or inline review comments. [Reviewers ](/commands/pr/reviewers/)Assign and remove reviewers with clear behavior in idempotent cases. [Start with PR creation ](/commands/pr/create-and-edit/) ## Most-Used Commands [Section titled “Most-Used Commands”](#most-used-commands) | Task | Command | | --------------------------------------------- | --------------------------------------------------- | | Create a PR | `bb pr create -t "Add feature"` | | Create a PR with the repo’s default reviewers | `bb pr create -t "Add feature" --default-reviewers` | | List open PRs | `bb pr list` | | List all PRs (ignore the default limit) | `bb pr list --all` | | List PRs where you are a reviewer | `bb pr list --mine` | | View PR details | `bb pr view 42` | | View checks | `bb pr checks 42` | | Review diff | `bb pr diff 42 --stat` | | Checkout PR locally | `bb pr checkout 42` | | Approve PR | `bb pr approve 42` | | Merge PR | `bb pr merge 42 --strategy squash` | ## JSON for Automation [Section titled “JSON for Automation”](#json-for-automation) Use `--json` when scripting. The optional field list (`--json id,title,state`) projects to just those fields, and `--jq` filters in-process — no external `jq` binary required:
```bash
# Project to specific fields (returns a flat array)
bb pr list --json id,title,author.display_name
# Filter with built-in --jq
bb pr list --json --jq '.pullRequests[] | select(.state == "OPEN") | .title'
# Combine projection + filter (jq runs after projection)
bb pr list --json id,title,state --jq '.[] | select(.state == "OPEN") | .title'
# Grab a PR URL from view output
bb pr view 42 --json --jq '.links.html.href'
# Capture diffstat totals
bb pr diff 42 --stat --json --jq '{filesChanged, totalAdditions, totalDeletions}'
```
# Activity and Checks
> Inspect pull request activity history and CI/CD check status
Inspect pull request activity and build checks. Global options available on all PR commands: `--json`, `--no-color`, `-w, --workspace`, `-r, --repo`. ## `bb pr activity` [Section titled “bb pr activity”](#bb-pr-activity) Show a pull request activity log.
```bash
bb pr activity [options]
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options) | Option | Description | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | `--limit ` | Maximum number of activity entries (default: 25) | | `--all` | Show all activity entries (overrides `--limit`) | | `--type ` | Filter by activity type (comma-separated): `comment`, `approval`, `changes_requested`, `merge`, `decline`, `commit`, `update` | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples)
```bash
# View activity for PR #42
bb pr activity 42
# Filter to comment and approval events
bb pr activity 42 --type comment,approval
# Limit results
bb pr activity 42 --limit 10
# Show the full activity history
bb pr activity 42 --all
# Get activity as JSON
bb pr activity 42 --json
```
### Notes [Section titled “Notes”](#notes) * `--limit` is enforced across paginated activity responses * When the result is capped by `--limit`, a hint shows how many were listed; use a higher `--limit` or `--all` to see the rest (suppressed with `--json`) * Valid `--type` values: `comment`, `approval`, `changes_requested`, `merge`, `decline`, `commit`, `update` * Multiple types can be combined: `--type comment,approval` *** ## `bb pr checks` [Section titled “bb pr checks”](#bb-pr-checks) Show CI/CD checks and build status for a pull request.
```bash
bb pr checks [options]
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options-1) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
# View checks for PR #42
bb pr checks 42
# View checks in a specific repository
bb pr checks 42 -w myworkspace -r myrepo
# Get checks as JSON
bb pr checks 42 --json
```
# Comments
> List, add, edit, and delete pull request comments
Manage pull request comments. Global options available on all PR commands: `--json`, `--no-color`, `-w, --workspace`, `-r, --repo`. ## `bb pr comments` [Section titled “bb pr comments”](#bb-pr-comments) ### Subcommands [Section titled “Subcommands”](#subcommands) | Subcommand | Description | | ------------------------------------- | ---------------------------------- | | `list ` | List comments on a pull request | | `add ` | Add a comment to a pull request | | `edit ` | Edit a comment on a pull request | | `delete ` | Delete a comment on a pull request | *** ## `bb pr comments list` [Section titled “bb pr comments list”](#bb-pr-comments-list) List comments on a pull request.
```bash
bb pr comments list
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options) | Option | Description | | ----------------------------- | -------------------------------------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--limit ` | Maximum number of comments (default: 25) | | `--all` | List all comments (overrides `--limit`) | | `--no-truncate` | Show full comment content without truncation | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples)
```bash
# List comments on PR #42
bb pr comments list 42
# List more comments
bb pr comments list 42 --limit 50
# List every comment
bb pr comments list 42 --all
# Show full comment content (not truncated)
bb pr comments list 42 --no-truncate
# List comments in specific repository
bb pr comments list 42 -w myworkspace -r myrepo
# Get comments as JSON
bb pr comments list 42 --json
```
### Notes [Section titled “Notes”](#notes) * By default, comment content is truncated to 60 characters in the table view * Use `--no-truncate` to display the full comment text * `--limit` is enforced across paginated comment responses * When the result is capped by `--limit`, a hint shows how many were listed; use a higher `--limit` or `--all` to see the rest (suppressed with `--json`) *** ## `bb pr comments add` [Section titled “bb pr comments add”](#bb-pr-comments-add) Add a comment to a pull request. Supports both general comments and inline comments on specific file lines.
```bash
bb pr comments add [options]
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | --------- | --------------- | | `id` | Pull request ID | | `message` | Comment message | ### Options [Section titled “Options”](#options-1) | Option | Description | | ----------------------------- | --------------------------------------------------------------------------- | | `--file ` | File path for an inline comment (requires `--line-to` and/or `--line-from`) | | `--line-to ` | Line number in the new version of the file (requires `--file`) | | `--line-from ` | Line number in the old version of the file (requires `--file`) | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
# Add a general comment to PR #42
bb pr comments add 42 "LGTM! This looks great."
# Add an inline comment on a specific line in the new file
bb pr comments add 42 "Consider renaming this variable" --file src/index.ts --line-to 15
# Add an inline comment on a line in the old (removed) version of the file
bb pr comments add 42 "Why was this removed?" --file src/utils.ts --line-from 10
# Add an inline comment spanning old and new lines
bb pr comments add 42 "This logic changed" --file src/app.ts --line-from 5 --line-to 8
# Add a comment to PR in specific repository
bb pr comments add 42 "Please review this." -w myworkspace -r myrepo
# Get comment as JSON
bb pr comments add 42 "Good job!" --json
```
### Notes [Section titled “Notes”](#notes-1) * `--file` is required when using `--line-to` or `--line-from` * At least one of `--line-to` or `--line-from` is required when using `--file` * Line numbers must be positive integers *** ## `bb pr comments edit` [Section titled “bb pr comments edit”](#bb-pr-comments-edit) Edit a comment on a pull request.
```bash
bb pr comments edit
```
### Arguments [Section titled “Arguments”](#arguments-2) | Argument | Description | | ------------ | ------------------- | | `pr-id` | Pull request ID | | `comment-id` | Comment ID | | `message` | New comment message | ### Options [Section titled “Options”](#options-2) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-2)
```bash
# Edit comment #123 on PR #42
bb pr comments edit 42 123 "Updated: I noticed something else..."
# Edit comment in specific repository
bb pr comments edit 42 123 "Revised feedback" -w myworkspace -r myrepo
# Get updated comment as JSON
bb pr comments edit 42 123 "Final comment" --json
```
*** ## `bb pr comments delete` [Section titled “bb pr comments delete”](#bb-pr-comments-delete) Delete a comment from a pull request.
```bash
bb pr comments delete
```
### Arguments [Section titled “Arguments”](#arguments-3) | Argument | Description | | ------------ | --------------- | | `pr-id` | Pull request ID | | `comment-id` | Comment ID | ### Options [Section titled “Options”](#options-3) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-3)
```bash
# Delete comment #123 from PR #42
bb pr comments delete 42 123
# Delete comment in specific repository
bb pr comments delete 42 456 -w myworkspace -r myrepo
# Delete comment with JSON output
bb pr comments delete 42 456 --json
```
### Notes [Section titled “Notes”](#notes-2) * Deleting a comment is permanent and cannot be undone
# Create, Edit, and View PRs
> Create pull requests, edit metadata, and inspect PR details
Create and inspect pull requests. Global options available on all PR commands: `--json [fields]`, `--jq `, `--no-color`, `-w, --workspace`, `-r, --repo`. ## `bb pr create` [Section titled “bb pr create”](#bb-pr-create) Create a new pull request.
```bash
bb pr create [options]
```
### Options [Section titled “Options”](#options) | Option | Description | | ----------------------------- | ------------------------------------------------------------ | | `-t, --title ` | Pull request title (required) | | `-b, --body ` | Pull request description | | `-s, --source ` | Source branch (default: current branch) | | `-d, --destination ` | Destination branch (default: main) | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--close-source-branch` | Close source branch after merge | | `--draft` | Create the pull request as draft | | `--reviewer ` | Add a reviewer by account ID or `{uuid}` (repeatable) | | `--default-reviewers` | Include the repository’s default reviewers (opt-in) | | `--no-default-reviewers` | Skip default reviewers even when the config key enables them | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples)
```bash
# Create a PR from current branch to main
bb pr create -t "Add new feature"
# Create a PR with full details
bb pr create -t "Add login page" -b "Implements user login functionality" -d develop
# Create a PR that will close the source branch after merging
bb pr create -t "Hotfix: Critical bug" --close-source-branch
# Create a draft PR
bb pr create -t "WIP: Add feature" --draft
# Auto-add the repo's default reviewers (matches the Bitbucket web UI)
bb pr create -t "Add new feature" --default-reviewers
# Add specific reviewers (repeatable; accepts account ID or {uuid})
bb pr create -t "Add new feature" \
--reviewer "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f" \
--reviewer "{c1cb1bb5-2e32-456e-a373-43978dc12aa1}"
# Combine defaults + explicit additions (duplicates are de-duped)
bb pr create -t "Add new feature" --default-reviewers \
--reviewer "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f"
# Capture the new PR's URL from JSON output for scripting
bb pr create -t "Add new feature" --json --jq '.links.html.href'
# Project the response to just the fields you need
bb pr create -t "Add new feature" --json id,title,links.html.href
```
### Reviewers [Section titled “Reviewers”](#reviewers) By default `bb pr create` does **not** attach reviewers to the PR — this differs from the Bitbucket web UI, which auto-populates the repository’s default reviewers. * `--default-reviewers` opts in per-invocation. The command fetches the repository’s *effective* default reviewers (repo-level + project-inherited) and attaches them. * `--reviewer ` adds specific reviewers regardless of the defaults and can be passed multiple times. Accepts an **account ID** (e.g. `712020:3cfed7e0-...`) or a **UUID** in curly braces (e.g. `{c1cb1bb5-...}`). Bitbucket Cloud’s GDPR changes retired username lookups, so nicknames are not accepted. * The PR author is automatically excluded from the reviewer list — Bitbucket rejects PRs that list the author as a reviewer. * To make `--default-reviewers` the default behavior, set the config key:
```bash
bb config set prCreateIncludeDefaultReviewers true
```
Pass `--no-default-reviewers` to skip defaults for a single invocation when this is enabled. * If the default-reviewer fetch fails (network error, permission issue, etc.), the PR is still created without reviewers and a warning is printed — the failure does not block the creation. See [`bb repo default-reviewers`](/commands/repo/#bb-repo-default-reviewers) to inspect or manage the underlying default reviewer list. *** ## `bb pr edit` [Section titled “bb pr edit”](#bb-pr-edit) Edit an existing pull request’s title or description.
```bash
bb pr edit [id] [options]
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | ------------------------------------------------------------- | | `id` | Pull request ID (optional - auto-detects from current branch) | ### Options [Section titled “Options”](#options-1) | Option | Description | | ----------------------------- | ---------------------------- | | `-t, --title ` | New pull request title | | `-b, --body ` | New pull request description | | `-F, --body-file ` | Read description from file | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
# Edit PR title by ID
bb pr edit 42 -t "Updated: Add new feature"
# Edit PR description
bb pr edit 42 -b "This PR implements the new login flow"
# Edit both title and description
bb pr edit 42 -t "New title" -b "New description"
# Auto-detect PR from current branch and update title
bb pr edit -t "Updated title"
# Read description from a file
bb pr edit 42 -F description.md
# Get updated PR as JSON
bb pr edit 42 -t "New title" --json
```
### Notes [Section titled “Notes”](#notes) * When no ID is provided, the command searches for an open PR where the source branch matches your current git branch * At least one of `--title`, `--body`, or `--body-file` must be provided * The `--body-file` option reads the entire file contents as the new description *** ## `bb pr list` [Section titled “bb pr list”](#bb-pr-list) List pull requests.
```bash
bb pr list [options]
```
### Options [Section titled “Options”](#options-2) | Option | Description | | ----------------------------- | ------------------------------------------------------------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `-s, --state ` | Filter by state: OPEN, MERGED, DECLINED, SUPERSEDED (default: OPEN) | | `--limit ` | Maximum number of PRs (default: 25) | | `--mine` | Show only pull requests where you are a reviewer | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-2)
```bash
# List open PRs in current repository
bb pr list
# List merged PRs
bb pr list -s MERGED
# List declined PRs
bb pr list -s DECLINED
# List PRs in specific repository
bb pr list -w myworkspace -r myrepo
# List with JSON output for scripting
bb pr list --json
# Project to specific fields (returns a flat array)
bb pr list --json id,title,author.display_name
# Filter with built-in --jq (no external jq binary needed)
bb pr list --json --jq '.pullRequests[] | select(.state == "OPEN") | .title'
# List more results
bb pr list --limit 50
# Show only pull requests assigned to you for review
bb pr list --mine
```
### Notes [Section titled “Notes”](#notes-1) * Draft PRs are shown with a `[DRAFT]` prefix in the title * `--limit` is enforced across paginated API responses `--mine` does not mean “my PRs” `--mine` filters PRs where you are assigned as a **reviewer**, not PRs you authored. It uses the Bitbucket API’s `reviewers.uuid` filter. To find PRs you created, use `--json` with `jq`:
```bash
bb pr list --json | jq '.pullRequests[] | select((.author.nickname // .author.display_name) == "your-username")'
```
*** ## `bb pr view` [Section titled “bb pr view”](#bb-pr-view) View pull request details.
```bash
bb pr view [options]
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options-3) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-3)
```bash
# View PR #42 in current repository
bb pr view 42
# View PR in specific repository
bb pr view 42 -w myworkspace -r myrepo
# Get PR details as JSON
bb pr view 42 --json
# Project to specific fields
bb pr view 42 --json id,title,state,author.display_name
# Extract just the web URL with built-in --jq
bb pr view 42 --json --jq '.links.html.href'
```
# Diff and Checkout
> Checkout pull request branches locally and inspect diff output
Review pull request changes with local checkout and diff tooling. Global options available on all PR commands: `--json`, `--no-color`, `-w, --workspace`, `-r, --repo`. ## `bb pr checkout` [Section titled “bb pr checkout”](#bb-pr-checkout) Checkout a pull request locally. This command fetches the PR’s source branch and checks it out, creating a local tracking branch if needed.
```bash
bb pr checkout [options]
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples)
```bash
# Checkout PR #42 to review locally
bb pr checkout 42
# Checkout PR from specific repository
bb pr checkout 42 -w myworkspace -r myrepo
```
### Notes [Section titled “Notes”](#notes) The command will: 1. Fetch the latest changes from the remote 2. Try to checkout the PR’s source branch 3. If the branch doesn’t exist locally, create a new branch named `pr-` tracking `origin/` *** ## `bb pr diff` [Section titled “bb pr diff”](#bb-pr-diff) View the diff of a pull request. Shows the changes introduced by the PR in unified diff format with syntax highlighting.
```bash
bb pr diff [id] [options]
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | -------- | ------------------------------------------------------------- | | `id` | Pull request ID (optional - auto-detects from current branch) | ### Options [Section titled “Options”](#options-1) | Option | Description | | ----------------------------- | ---------------------------------------------------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--color ` | Colorize output: `auto`, `always`, `never` (default: auto) | | `--name-only` | Show only names of changed files | | `--stat` | Show diffstat (files changed, insertions, deletions) | | `--web` | Open diff in web browser | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
# View diff for PR #42
bb pr diff 42
# Auto-detect PR from current branch
bb pr diff
# Show only changed file names
bb pr diff 42 --name-only
# Show statistics (like git diff --stat)
bb pr diff 42 --stat
# Open diff in browser
bb pr diff 42 --web
# Return browser URL as JSON
bb pr diff 42 --web --json
# Disable colors for piping to file or other commands
bb pr diff 42 --color never > pr-42.patch
# Get diffstat as JSON for scripting
bb pr diff 42 --stat --json
```
### Notes [Section titled “Notes”](#notes-1) * When no ID is provided, the command searches for an open PR where the source branch matches your current git branch * The `--stat` output shows files changed with insertions (+) and deletions (-) * `-w` remains the global short alias for `--workspace`; use `--web` (long form) to open the diff in a browser * Use `--color never` when piping output to files or other commands * Use the global `--no-color` flag to disable color output for all command formatting * The diff is colorized by default when output is a terminal (green for additions, red for deletions, cyan for hunk headers) * For opening other Bitbucket pages (PR detail, files, commits, pipelines, settings) in the browser, see [`bb browse`](/commands/browse/)
# Review and Merge
> Approve, decline, mark ready, and merge pull requests
Complete review and merge pull request workflows. Global options available on all PR commands: `--json`, `--no-color`, `-w, --workspace`, `-r, --repo`. ## `bb pr merge` [Section titled “bb pr merge”](#bb-pr-merge) Merge a pull request.
```bash
bb pr merge [options]
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options) | Option | Description | | ----------------------------- | -------------------------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `-m, --message ` | Merge commit message | | `--close-source-branch` | Delete source branch after merge | | `--strategy ` | Merge strategy (see table below) | | `--json` | Output as JSON | ### Merge Strategies [Section titled “Merge Strategies”](#merge-strategies) | Strategy | Description | | --------------------- | ---------------------------------------------------------------- | | `merge_commit` | Create a merge commit (default) | | `squash` | Squash all commits into a single commit | | `fast_forward` | Fast-forward if possible, fail otherwise | | `squash_fast_forward` | Squash commits and fast-forward | | `rebase_fast_forward` | Rebase source commits onto destination and fast-forward | | `rebase_merge` | Rebase source commits onto destination and create a merge commit | ### Examples [Section titled “Examples”](#examples)
```bash
# Merge PR #42
bb pr merge 42
# Merge with squash strategy and delete source branch
bb pr merge 42 --strategy squash --close-source-branch
# Merge with custom commit message
bb pr merge 42 -m "Merge feature: Add user authentication"
# Rebase and fast-forward
bb pr merge 42 --strategy rebase_fast_forward
```
*** ## `bb pr approve` [Section titled “bb pr approve”](#bb-pr-approve) Approve a pull request.
```bash
bb pr approve [options]
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options-1) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
# Approve PR in current repository
bb pr approve 42
# Approve PR in specific repository
bb pr approve 42 -w myworkspace -r myrepo
```
*** ## `bb pr decline` [Section titled “bb pr decline”](#bb-pr-decline) Decline a pull request.
```bash
bb pr decline [options]
```
### Arguments [Section titled “Arguments”](#arguments-2) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options-2) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-2)
```bash
# Decline PR in current repository
bb pr decline 42
# Decline PR in specific repository
bb pr decline 42 -w myworkspace -r myrepo
```
*** ## `bb pr ready` [Section titled “bb pr ready”](#bb-pr-ready) Mark a draft pull request as ready for review.
```bash
bb pr ready [options]
```
### Arguments [Section titled “Arguments”](#arguments-3) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options-3) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-3)
```bash
# Mark draft PR as ready
bb pr ready 42
# Mark draft PR in specific repository
bb pr ready 42 -w myworkspace -r myrepo
```
# Reviewers
> List, add, and remove pull request reviewers
Manage pull request reviewers. Global options available on all PR commands: `--json`, `--no-color`, `-w, --workspace`, `-r, --repo`. ## Identifying users [Section titled “Identifying users”](#identifying-users) Bitbucket Cloud no longer accepts the legacy `username` (login name) when modifying reviewers. The `` positional accepts either: * An **account ID**, e.g. `712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f` * A **UUID** wrapped in braces, e.g. `{c1cb1bb5-2e32-456e-a373-43978dc12aa1}` Both forms are returned by `bb pr reviewers list --json` (the `account_id` and `uuid` fields), so you can pipe the output of one command into another to script reviewer changes. See [`bb pr create`](/commands/pr/create-and-edit/#bb-pr-create) for matching `--reviewer` examples. ## `bb pr reviewers` [Section titled “bb pr reviewers”](#bb-pr-reviewers) ### Subcommands [Section titled “Subcommands”](#subcommands) | Subcommand | Description | | -------------------- | ------------------------------------- | | `list ` | List reviewers on a pull request | | `add ` | Add a reviewer to a pull request | | `remove ` | Remove a reviewer from a pull request | *** ## `bb pr reviewers list` [Section titled “bb pr reviewers list”](#bb-pr-reviewers-list) List reviewers assigned to a pull request.
```bash
bb pr reviewers list
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | --------------- | | `id` | Pull request ID | ### Options [Section titled “Options”](#options) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples)
```bash
# List reviewers on PR #42
bb pr reviewers list 42
# List reviewers in specific repository
bb pr reviewers list 42 -w myworkspace -r myrepo
# Get reviewers as JSON for scripting
bb pr reviewers list 42 --json
```
### Notes [Section titled “Notes”](#notes) * Displays reviewers in a table with display name and account ID * Shows a message if no reviewers are assigned * Due to Bitbucket Cloud GDPR changes, the deprecated `username` field is not displayed *** ## `bb pr reviewers add` [Section titled “bb pr reviewers add”](#bb-pr-reviewers-add) Add a reviewer to a pull request by account ID or UUID. The legacy `username` (login name) is not accepted by Bitbucket Cloud — see [Identifying users](#identifying-users).
```bash
bb pr reviewers add
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | -------- | --------------------------------------------------------------------------------- | | `id` | Pull request ID | | `user` | Account ID (e.g. `712020:3cfed7e0-…`) or UUID (`{c1cb1bb5-…}`) of the user to add | ### Options [Section titled “Options”](#options-1) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
# Add reviewer by account ID
bb pr reviewers add 42 "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f"
# Add reviewer by UUID (note the braces)
bb pr reviewers add 42 "{c1cb1bb5-2e32-456e-a373-43978dc12aa1}"
# Add reviewer in specific repository
bb pr reviewers add 42 "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f" -w myworkspace -r myrepo
# Add reviewer and get result as JSON
bb pr reviewers add 42 "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f" --json
```
### Notes [Section titled “Notes”](#notes-1) * The user must exist in Bitbucket; you’ll get a clear error message if the user is not found * If the user is already a reviewer, the command succeeds without making changes * Uses UUID for identification (GDPR-compliant) *** ## `bb pr reviewers remove` [Section titled “bb pr reviewers remove”](#bb-pr-reviewers-remove) Remove a reviewer from a pull request by account ID or UUID. The legacy `username` (login name) is not accepted by Bitbucket Cloud — see [Identifying users](#identifying-users).
```bash
bb pr reviewers remove
```
### Arguments [Section titled “Arguments”](#arguments-2) | Argument | Description | | -------- | ---------------------------------------------------------------------------------------- | | `id` | Pull request ID | | `user` | Account ID (e.g. `712020:3cfed7e0-…`) or UUID (`{c1cb1bb5-…}`) of the reviewer to remove | ### Options [Section titled “Options”](#options-2) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `-r, --repo ` | Repository | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-2)
```bash
# Remove reviewer by account ID
bb pr reviewers remove 42 "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f"
# Remove reviewer by UUID (note the braces)
bb pr reviewers remove 42 "{c1cb1bb5-2e32-456e-a373-43978dc12aa1}"
# Remove reviewer in specific repository
bb pr reviewers remove 42 "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f" -w myworkspace -r myrepo
# Remove reviewer and get result as JSON
bb pr reviewers remove 42 "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f" --json
```
### Notes [Section titled “Notes”](#notes-2) * The user must exist in Bitbucket; you’ll get a clear error message if the user is not found * If the user is not a reviewer on the PR, the command succeeds without making changes * Uses UUID for identification (GDPR-compliant)
# Repo Commands - Clone, Create & Manage Bitbucket Repositories
> Complete reference for Bitbucket CLI repository commands. Learn to clone, create, list, view, and delete repositories from the command line with examples.
Manage Bitbucket repositories. Global options available on all repo commands: `--json [fields]`, `--jq `, `--no-color`, `-w, --workspace`, `-r, --repo`. ## `bb repo clone` [Section titled “bb repo clone”](#bb-repo-clone) Clone a Bitbucket repository.
```bash
bb repo clone [options]
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | ------------ | -------------------------------------------------- | | `repository` | Repository to clone (`workspace/repo` or full URL) | ### Options [Section titled “Options”](#options) | Option | Description | | ----------------------- | ----------------------- | | `-d, --directory ` | Directory to clone into | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples)
```bash
# Clone using workspace/repo format
bb repo clone myworkspace/myrepo
# Clone into a specific directory
bb repo clone myworkspace/myrepo -d my-local-dir
# Clone using full URL
bb repo clone git@bitbucket.org:myworkspace/myrepo.git
```
*** ## `bb repo create` [Section titled “bb repo create”](#bb-repo-create) Create a new repository.
```bash
bb repo create [options]
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | -------- | --------------------------- | | `name` | Name for the new repository | ### Options [Section titled “Options”](#options-1) | Option | Description | | --------------------------------- | ------------------------------------- | | `-w, --workspace ` | Workspace to create repository in | | `-d, --description ` | Repository description | | `--private` | Create a private repository (default) | | `--public` | Create a public repository | | `-p, --project ` | Project key | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
# Create a private repository
bb repo create my-new-repo -w myworkspace
# Create a public repository with description
bb repo create my-new-repo -w myworkspace --public -d "My awesome project"
# Create in a specific project
bb repo create my-new-repo -w myworkspace -p PROJ
```
*** ## `bb repo list` [Section titled “bb repo list”](#bb-repo-list) List repositories in a workspace.
```bash
bb repo list [options]
```
### Options [Section titled “Options”](#options-2) | Option | Description | | ----------------------------- | -------------------------------------------- | | `-w, --workspace ` | Workspace to list repositories from | | `--limit ` | Maximum number of repositories (default: 25) | | `--all` | List all repositories (overrides `--limit`) | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-2)
```bash
# List repositories in a workspace
bb repo list -w myworkspace
# List more repositories
bb repo list -w myworkspace --limit 50
# List every repository in the workspace
bb repo list -w myworkspace --all
# List with JSON output for scripting
bb repo list -w myworkspace --json
# Project to specific fields (returns a flat array)
bb repo list -w myworkspace --json full_name,is_private,language
# Filter with built-in --jq — print just public repo names
bb repo list -w myworkspace --json --jq '.repositories[] | select(.is_private == false) | .full_name'
```
### Notes [Section titled “Notes”](#notes) * `--limit` is enforced across paginated repository responses * When the result is capped by `--limit`, a hint is printed showing how many were listed; use a higher `--limit` or `--all` to see the rest (suppressed with `--json`) *** ## `bb repo view` [Section titled “bb repo view”](#bb-repo-view) View repository details.
```bash
bb repo view [repository] [options]
```
### Arguments [Section titled “Arguments”](#arguments-2) | Argument | Description | | ------------ | ------------------------------------------------------------------------------- | | `repository` | Repository to view in `workspace/repo` format (optional if in a repo directory) | ### Options [Section titled “Options”](#options-3) | Option | Description | | ----------------------------- | -------------- | | `-w, --workspace ` | Workspace | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-3)
```bash
# View current repository (from within repo directory)
bb repo view
# View specific repository using workspace/repo format
bb repo view myworkspace/myrepo
# View with explicit workspace option
bb repo view myrepo -w myworkspace
# Get repository details as JSON
bb repo view --json
```
### Notes [Section titled “Notes”](#notes-1) * The positional `[repository]` argument is the primary way to specify the repo (e.g., `bb repo view myworkspace/myrepo`). The global `-w` and `-r` flags also work as an alternative. * The command will automatically detect the repository from your current directory’s git remote if you don’t specify one. *** ## `bb repo delete` [Section titled “bb repo delete”](#bb-repo-delete) Delete a repository. This action is permanent and cannot be undone.
```bash
bb repo delete [options]
```
### Arguments [Section titled “Arguments”](#arguments-3) | Argument | Description | | ------------ | ----------------------------------------------- | | `repository` | Repository to delete in `workspace/repo` format | ### Options [Section titled “Options”](#options-4) | Option | Description | | ----------------------------- | --------------------------- | | `-w, --workspace ` | Workspace | | `-y, --yes` | Confirm deletion (required) | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-4)
```bash
# Delete a repository (--yes is required to confirm)
bb repo delete myworkspace/myrepo --yes
# Delete using explicit workspace option
bb repo delete myrepo -w myworkspace --yes
```
Danger This action is permanent and cannot be undone! All repository data, including code, issues, and pull requests will be deleted. *** []() ## `bb repo default-reviewers` [Section titled “bb repo default-reviewers”](#bb-repo-default-reviewers) Inspect and manage the default reviewers configured on a repository. Default reviewers in Bitbucket Cloud are automatically suggested when someone opens a pull request through the web UI; this command group lets you see and edit that list from the CLI. ### Subcommands [Section titled “Subcommands”](#subcommands) | Subcommand | Description | | --------------- | ---------------------------------------------------------------------------- | | `list` | List the default reviewers for a repository | | `add ` | Add a default reviewer (accepts account ID or `{uuid}`) | | `remove ` | Remove a default reviewer (accepts account ID or `{uuid}`, requires `--yes`) | ### `bb repo default-reviewers list` [Section titled “bb repo default-reviewers list”](#bb-repo-default-reviewers-list)
```bash
bb repo default-reviewers list [options]
```
By default the **effective** reviewer list is shown — this includes reviewers configured directly on the repository *and* reviewers inherited from the parent project, matching what Bitbucket’s web UI would auto-populate. | Option | Description | | ------------- | ---------------------------------------------------------------------------- | | `--repo-only` | Only show reviewers configured on the repository (exclude project-inherited) | | `--json` | Output as JSON |
```bash
# Effective list (repo + project-inherited)
bb repo default-reviewers list
# Only repo-level entries
bb repo default-reviewers list --repo-only
# JSON for scripting
bb repo default-reviewers list --json
```
### `bb repo default-reviewers add` [Section titled “bb repo default-reviewers add”](#bb-repo-default-reviewers-add)
```bash
bb repo default-reviewers add
```
Adds a user as a default reviewer on the repository. Requires repository admin permission. The `` argument accepts either an **account ID** (e.g. `712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f`) or a **UUID** in curly braces (e.g. `{c1cb1bb5-2e32-456e-a373-43978dc12aa1}`). Bitbucket Cloud’s GDPR changes retired username lookups, so nicknames like `jdoe` are no longer accepted. You can find a user’s account ID from the Bitbucket web UI under their profile, or by running `bb pr reviewers list --json` on a PR they’ve reviewed.
```bash
bb repo default-reviewers add "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f"
bb repo default-reviewers add "{c1cb1bb5-2e32-456e-a373-43978dc12aa1}"
```
### `bb repo default-reviewers remove` [Section titled “bb repo default-reviewers remove”](#bb-repo-default-reviewers-remove)
```bash
bb repo default-reviewers remove --yes
```
Removes a user from the repository’s default reviewers. `--yes` is required to confirm. Requires repository admin permission. `` accepts the same identifiers as `add` (account ID or `{uuid}`).
```bash
bb repo default-reviewers remove "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f" --yes
```
### Notes [Section titled “Notes”](#notes-2) * Project-inherited reviewers can only be removed by editing the parent project, not the repository. * Related: [`bb pr create --default-reviewers`](/commands/pr/create-and-edit/) applies these reviewers when opening a pull request.
# Snippet Commands - Manage Bitbucket Snippets
> Reference for Bitbucket CLI snippet commands. Create, view, edit, delete, watch, and comment on Bitbucket Cloud snippets from the command line.
Manage Bitbucket Cloud snippets — workspace-scoped code/text pastes. Snippet commands operate at **workspace** scope (no repo context required). Use `-w, --workspace ` or set a default with `bb config set defaultWorkspace `. Global options available on all snippet commands: `--json [fields]`, `--jq `, `--no-color`, `-w, --workspace`. *** ## `bb snippet list` [Section titled “bb snippet list”](#bb-snippet-list) List snippets in a workspace.
```bash
bb snippet list [options]
```
### Options [Section titled “Options”](#options) | Option | Description | | ----------------------------- | ------------------------------------------------------------------------ | | `-w, --workspace ` | Workspace | | `--role ` | Filter by authenticated user’s role: `owner`, `contributor`, or `member` | | `--limit ` | Maximum number of snippets (default: 25) | | `--all` | List all snippets (overrides `--limit`) | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples)
```bash
bb snippet list
bb snippet list --role owner
bb snippet list --limit 50 --json
bb snippet list --all
# Project to specific fields (returns a flat array)
bb snippet list --json id,title,is_private
# Filter with built-in --jq — public snippets only
bb snippet list --json --jq '.snippets[] | select(.is_private == false) | .title'
```
### Notes [Section titled “Notes”](#notes) * `--limit` is enforced across paginated responses. * When the result is capped by `--limit`, a hint shows how many were listed; use a higher `--limit` or `--all` to see the rest (suppressed with `--json`). *** ## `bb snippet view` [Section titled “bb snippet view”](#bb-snippet-view) View snippet details. Optionally print file contents.
```bash
bb snippet view [options]
```
### Arguments [Section titled “Arguments”](#arguments) | Argument | Description | | -------- | -------------------------------- | | `id` | Snippet encoded ID (e.g. `kypj`) | ### Options [Section titled “Options”](#options-1) | Option | Description | | ----------------------------- | ------------------------------------------------ | | `-w, --workspace ` | Workspace | | `-f, --file ` | Print contents of a specific file in the snippet | | `--files` | Print contents of all files in the snippet | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-1)
```bash
bb snippet view kypj
bb snippet view kypj --json
bb snippet view kypj --file config.yml
bb snippet view kypj --files
```
*** ## `bb snippet create` [Section titled “bb snippet create”](#bb-snippet-create) Create a snippet. The files you pass are uploaded as `multipart/form-data` to Bitbucket — their contents are the snippet body.
```bash
bb snippet create [options]
```
### Options [Section titled “Options”](#options-2) | Option | Description | | ----------------------------- | -------------------------------------------- | | `-w, --workspace ` | Workspace | | `-t, --title ` | Snippet title (required) | | `-f, --file ` | One or more file paths to include (required) | | `--private` | Create a private snippet (default) | | `--public` | Create a public snippet | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-2)
```bash
bb snippet create -t "My snippet" -f file.txt
bb snippet create -t "Config files" -f config.yml -f setup.sh --public
```
### Notes [Section titled “Notes”](#notes-1) * Snippets are private by default. * `--private` and `--public` cannot both be set. * Each `--file` must exist on disk; missing files fail the command before any upload. *** ## `bb snippet edit` [Section titled “bb snippet edit”](#bb-snippet-edit) Update a snippet’s title, visibility, or files.
```bash
bb snippet edit [options]
```
### Arguments [Section titled “Arguments”](#arguments-1) | Argument | Description | | -------- | ------------------ | | `id` | Snippet encoded ID | ### Options [Section titled “Options”](#options-3) | Option | Description | | ----------------------------- | ------------------------------------------------ | | `-w, --workspace ` | Workspace | | `-t, --title ` | New title | | `--private` | Make snippet private | | `--public` | Make snippet public | | `-f, --file ` | Replace or add file(s); sends a multipart update | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-3)
```bash
bb snippet edit kypj -t "New title"
bb snippet edit kypj --public
bb snippet edit kypj -f updated.txt
```
### Notes [Section titled “Notes”](#notes-2) * Metadata-only edits (title, visibility) send a JSON PUT. * Passing `--file` switches to a multipart PUT and uploads the given files. * At least one of `--title`, `--private`, `--public`, or `--file` is required. *** ## `bb snippet delete` [Section titled “bb snippet delete”](#bb-snippet-delete) Delete a snippet. Permanent.
```bash
bb snippet delete [options]
```
### Options [Section titled “Options”](#options-4) | Option | Description | | ----------------------------- | --------------------------- | | `-w, --workspace ` | Workspace | | `-y, --yes` | Confirm deletion (required) | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-4)
```bash
bb snippet delete kypj --yes
```
Danger This action is permanent and cannot be undone. *** ## `bb snippet watch` / `bb snippet unwatch` [Section titled “bb snippet watch / bb snippet unwatch”](#bb-snippet-watch--bb-snippet-unwatch) Subscribe or unsubscribe the authenticated user to/from a snippet.
```bash
bb snippet watch [options]
bb snippet unwatch [options]
```
### Examples [Section titled “Examples”](#examples-5)
```bash
bb snippet watch kypj
bb snippet unwatch kypj
```
*** ## `bb snippet comments list` [Section titled “bb snippet comments list”](#bb-snippet-comments-list) List comments on a snippet.
```bash
bb snippet comments list [options]
```
### Options [Section titled “Options”](#options-5) | Option | Description | | ----------------------------- | ---------------------------------------- | | `-w, --workspace ` | Workspace | | `--limit ` | Maximum number of comments (default: 25) | | `--all` | List all comments (overrides `--limit`) | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-6)
```bash
bb snippet comments list kypj
bb snippet comments list kypj --all
bb snippet comments list kypj --limit 50 --json
```
*** ## `bb snippet comments add` [Section titled “bb snippet comments add”](#bb-snippet-comments-add) Add a comment to a snippet.
```bash
bb snippet comments add [options]
```
### Options [Section titled “Options”](#options-6) | Option | Description | | ----------------------------- | ----------------------- | | `-w, --workspace ` | Workspace | | `-m, --message ` | Comment body (required) | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-7)
```bash
bb snippet comments add kypj -m "Great snippet!"
```
*** ## `bb snippet comments edit` [Section titled “bb snippet comments edit”](#bb-snippet-comments-edit) Edit a comment on a snippet.
```bash
bb snippet comments edit [options]
```
### Examples [Section titled “Examples”](#examples-8)
```bash
bb snippet comments edit kypj 123 "Updated comment"
```
*** ## `bb snippet comments delete` [Section titled “bb snippet comments delete”](#bb-snippet-comments-delete) Delete a comment on a snippet.
```bash
bb snippet comments delete [options]
```
### Options [Section titled “Options”](#options-7) | Option | Description | | ----------------------------- | --------------------------- | | `-w, --workspace ` | Workspace | | `-y, --yes` | Confirm deletion (required) | | `--json` | Output as JSON | ### Examples [Section titled “Examples”](#examples-9)
```bash
bb snippet comments delete kypj 123 --yes
```
# Authentication
> How to authenticate with Bitbucket
The Bitbucket CLI supports two authentication methods: **OAuth** (recommended) and **API Tokens**. ## OAuth (Recommended) [Section titled “OAuth (Recommended)”](#oauth-recommended) The simplest way to authenticate. Just run:
```bash
bb auth login
```
This opens your browser where you authorize the CLI with your Bitbucket account. No tokens to copy, no scopes to select manually. ### Using a Custom OAuth Consumer [Section titled “Using a Custom OAuth Consumer”](#using-a-custom-oauth-consumer) Organizations can use their own OAuth consumer instead of the built-in default:
```bash
bb auth login --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
```
To set up a custom OAuth consumer: 1. Go to **Workspace settings** > **Apps and features** > **OAuth consumers** 2. Click **Add consumer** 3. Set **Callback URL** to `http://localhost:19872/callback` 4. Grant permissions: Account (Read), Repositories (Read, Write, Admin), Pull requests (Read, Write) 5. Save and use the generated **Key** as `--client-id` and **Secret** as `--client-secret` Custom credentials are stored in your config file for subsequent logins. *** ## API Token (for CI/CD and headless environments) [Section titled “API Token (for CI/CD and headless environments)”](#api-token-for-cicd-and-headless-environments) Use API tokens when a browser is not available (SSH sessions, Docker containers, CI/CD pipelines). 1. **Create an API Token** 1. Log in to [Bitbucket](https://bitbucket.org) 2. Go to **Personal settings** (click your avatar in the bottom left) 3. Navigate to **API tokens** under “Access management” 4. Click **Create API token** 5. Give it a descriptive name (e.g., “Bitbucket CLI”) 6. Select the required scopes: * `read:user:bitbucket` — verify your identity * `read:repository:bitbucket` — list and view repositories * `write:repository:bitbucket` — create repositories * `admin:repository:bitbucket` — delete repositories (optional) * `read:pullrequest:bitbucket` — list and view pull requests * `write:pullrequest:bitbucket` — create, edit, merge, approve, decline pull requests See [Token Scopes](/reference/token-scopes/) for a per-command breakdown if you want to mint a token with the minimum scope set for your workflow. 7. Click **Create** 8. **Copy the generated token** - you won’t be able to see it again! 2. **Authenticate**
```bash
bb auth login -u your-username -p your-api-token
```
Or using environment variables:
```bash
export BB_USERNAME=your-username
export BB_API_TOKEN=your-api-token
bb auth login
```
See [Environment Variables Reference](/reference/environment-variables/) for more details on using environment variables in scripts and CI/CD. *** ## Check Auth Status [Section titled “Check Auth Status”](#check-auth-status)
```bash
bb auth status
```
This shows your current authentication method, account information, and token expiry (for OAuth). ## Logout [Section titled “Logout”](#logout)
```bash
bb auth logout
```
This removes stored credentials and revokes your OAuth token (if using OAuth). Non-auth settings are preserved. ## Configuration Storage [Section titled “Configuration Storage”](#configuration-storage) Credentials are stored in: * **Linux/macOS**: `~/.config/bb/config.json` * **Windows**: `%APPDATA%\bb\config.json` See [Configuration File Reference](/reference/configuration/) for details on the config file format. Caution Never share your credentials or config file. Keep them secure! ## Next Steps [Section titled “Next Steps”](#next-steps) * [Quick Start Guide](/getting-started/quickstart/) - Get up and running in 60 seconds * [Repository Context](/guides/repository-context/) - How the CLI detects your workspace/repo * [Troubleshooting](/help/troubleshooting/) - Common authentication issues and solutions
# Install Bitbucket CLI - npm, pnpm, Bun Setup Guide
> Step-by-step installation guide for Bitbucket CLI using npm, pnpm, or Bun. Learn prerequisites, global installation, and build from source. Get started in minutes.
## Prerequisites [Section titled “Prerequisites”](#prerequisites) * [Bun](https://bun.sh) runtime 1.0 or higher (required to run the CLI) * Git ## Install [Section titled “Install”](#install) You can install the CLI using any package manager, but **Bun runtime is required** to execute it. ### Using npm [Section titled “Using npm”](#using-npm)
```bash
npm install -g @pilatos/bitbucket-cli
```
### Using pnpm [Section titled “Using pnpm”](#using-pnpm)
```bash
pnpm add -g @pilatos/bitbucket-cli
```
### Using Bun [Section titled “Using Bun”](#using-bun)
```bash
bun install -g @pilatos/bitbucket-cli
```
## Build from Source [Section titled “Build from Source”](#build-from-source)
```bash
# Clone the repository
git clone https://github.com/0pilatos0/bitbucket-cli.git
cd bitbucket-cli
# Install dependencies
bun install
# Build
bun run build
# Link globally
bun link
```
## Verify Installation [Section titled “Verify Installation”](#verify-installation)
```bash
bb --version
```
## Next Steps [Section titled “Next Steps”](#next-steps) After installation, you’ll need to [authenticate](/getting-started/authentication/) with your Bitbucket account.
# Quick Start
> Get up and running with Bitbucket CLI in 60 seconds
Get productive with the Bitbucket CLI in under a minute. ## TL;DR [Section titled “TL;DR”](#tldr)
```bash
npm install -g @pilatos/bitbucket-cli
bb auth login
bb repo clone myworkspace/myrepo
bb pr create -t "My feature"
```
*** ## Prerequisites [Section titled “Prerequisites”](#prerequisites) Before you begin, you’ll need: * **[Bun](https://bun.sh) runtime 1.0+** installed (required to run the CLI) * A **Bitbucket Cloud** account Caution The CLI requires Bun runtime to execute. You can install the package via npm/pnpm/bun, but Bun must be available on your system to run `bb` commands. *** ## Step-by-Step Setup [Section titled “Step-by-Step Setup”](#step-by-step-setup) 1. **Install the CLI**
```bash
npm install -g @pilatos/bitbucket-cli
```
Verify the installation:
```bash
bb --version
```
2. **Authenticate**
```bash
bb auth login
```
This opens your browser to authorize the CLI with your Bitbucket account. No token setup needed. For CI/CD or headless environments, use an API token instead:
```bash
bb auth login -u your-username -p your-api-token
```
Verify it worked:
```bash
bb auth status
```
See the [Authentication guide](/getting-started/authentication/) for full details. 3. **Clone a Repository**
```bash
bb repo clone myworkspace/myrepo
cd myrepo
```
4. **Create Your First PR**
```bash
git checkout -b feature/my-feature
# Make some changes...
git add .
git commit -m "Add my feature"
git push -u origin feature/my-feature
bb pr create -t "Add my feature"
```
*** ## Common Commands [Section titled “Common Commands”](#common-commands) Here are the commands you’ll use most often: | Command | Description | | ------------------------- | ---------------------------------------------- | | `bb pr list` | List open pull requests | | `bb pr view 42` | View PR #42 details | | `bb pr activity 42` | View PR #42 activity log | | `bb pr create -t "Title"` | Create a new PR | | `bb pr merge 42` | Merge PR #42 | | `bb pr checkout 42` | Checkout PR #42 locally | | `bb pr diff 42` | View PR #42 diff | | `bb repo list` | List repositories | | `bb browse 42` | Open PR #42 in your browser | | `bb browse src/cli.ts:20` | Open a file at a specific line in your browser | *** ## Set a Default Workspace [Section titled “Set a Default Workspace”](#set-a-default-workspace) If you work primarily in one workspace, set it as default:
```bash
bb config set defaultWorkspace myworkspace
```
Now commands will use this workspace automatically:
```bash
bb repo list # Lists repos in "myworkspace"
bb pr list -r myrepo # Lists PRs in "myworkspace/myrepo"
```
*** ## Enable Tab Completion [Section titled “Enable Tab Completion”](#enable-tab-completion) Get intelligent tab completion for commands and options:
```bash
bb completion install
```
Restart your shell, then try:
```bash
bb pr # Shows: activity, approve, checkout, create, decline, diff, list, merge, ready, view
bb pr create - # Shows available flags
bb # Shows: auth, repo, pr, snippet, browse, config, completion
```
*** ## Scripting with JSON [Section titled “Scripting with JSON”](#scripting-with-json) Every command accepts `--json` for machine-readable output. You can project to a comma-separated field list and filter results through a built-in `jq` engine — no external `jq` binary required:
```bash
# Project to specific fields
bb pr list --json id,title,state
# Filter through built-in jq
bb pr list --json --jq '.pullRequests[] | select(.state == "OPEN") | .title'
```
*** ## Update notifications [Section titled “Update notifications”](#update-notifications) When a newer version is available on npm, `bb` prints a one-time nudge after the next command finishes:
```text
⚠ A new version is available: 1.14.0 (you have 1.13.0)
Run 'npm install -g @pilatos/bitbucket-cli' to update
Or disable with 'bb config set skipVersionCheck true'
```
The check runs at most once per `versionCheckInterval` (default: 24 hours) and is skipped automatically in CI environments. Disable it permanently with:
```bash
bb config set skipVersionCheck true
```
See the [Configuration File reference](/reference/configuration/) for related settings. *** ## Next Steps [Section titled “Next Steps”](#next-steps) You’re all set! Here’s where to go next: * **[Command Reference](/commands/auth/)** - Full documentation for all commands * **[Repository Context](/guides/repository-context/)** - How the CLI detects your workspace/repo * **[Scripting & Automation](/guides/scripting/)** - Use bb in scripts and CI/CD * **[JSON Output Reference](/reference/json-output/)** - Field projection, `--jq` filtering, output shapes * **[AI Agent Integration](/guides/ai-agents/)** - Wire the CLI into Claude Code, Cursor, or Windsurf * **[Changelog](/help/changelog/)** - What’s new in recent releases * **[Troubleshooting](/help/troubleshooting/)** - Common issues and solutions
# AI Agent Integration - Claude Code, Cursor, Windsurf & More
> Set up the Bitbucket CLI with Claude Code, opencode, Cursor, Windsurf, and other AI coding assistants. Skill files, quick-start guides, and real-world workflow examples.
Manage pull requests, repositories, and code reviews through natural conversation. Tell your AI assistant “Create a PR for this branch” and it handles the commands, flags, and context automatically. ## Quick Start [Section titled “Quick Start”](#quick-start) Pick your editor and paste the command: * Claude Code Run this in your project root:
```bash
mkdir -p .claude/skills/bb-cli && cat > .claude/skills/bb-cli/SKILL.md << 'SKILL'
---
name: bb-cli
description: >
Bitbucket Cloud CLI. Use when the user wants to create, list, review,
merge, or manage pull requests, repositories, authentication, or
configuration via the `bb` command.
argument-hint: "[command or question]"
allowed-tools: Bash(bb *), Read, Grep, Glob
---
# Bitbucket CLI (`bb`)
CLI for Bitbucket Cloud. Package: `@pilatos/bitbucket-cli`.
## Available commands
!`bb --help`
## Key workflows
**Create PR:** `bb pr create -t "title" -b "description"`
**List PRs:** `bb pr list` (add `--mine` for your reviews, `--json` for scripts)
**Review:** `bb pr checkout ` → `bb pr diff ` → `bb pr approve `
**Merge:** `bb pr merge --strategy squash --close-source-branch`
**Draft:** `bb pr create -t "WIP" --draft` → later `bb pr ready `
**Comments:** `bb pr comments list ` / `bb pr comments add "text"`
**Repos:** `bb repo list`, `bb repo clone workspace/repo`, `bb repo view`
## Tips
- Auto-detects workspace/repo from git remotes; override with `-w` / `-r`
- All commands support `--json` for structured output
- Merge strategies: `merge_commit`, `squash`, `fast_forward`, `squash_fast_forward`, `rebase_fast_forward`, `rebase_merge`
SKILL
echo "✓ Skill installed. Restart Claude Code to activate."
```
Restart Claude Code and try: **“List my open PRs”** * opencode Add this to `AGENTS.md` in your project root (create the file if it doesn’t exist):
```markdown
## Bitbucket CLI (`bb`)
Use `bb` (`@pilatos/bitbucket-cli`) for all Bitbucket operations.
Requires Bun 1.0+ runtime. Install: `npm install -g @pilatos/bitbucket-cli`
### Commands
**Pull Requests:**
- `bb pr create -t "title" -b "body"` - Create PR from current branch
- `bb pr create --default-reviewers` - Also attach the repo's default reviewers
- `bb pr create --reviewer ` - Add a specific reviewer (repeatable)
- `bb pr list` - List open PRs (`--mine` for your reviews, `--json` for scripts)
- `bb pr view ` / `bb pr diff ` - Inspect a PR
- `bb pr checkout ` - Check out PR locally
- `bb pr approve ` / `bb pr decline ` - Review
- `bb pr merge --strategy squash --close-source-branch` - Merge
- `bb pr ready ` - Mark draft as ready
- `bb pr comments add "text"` - Add comment
- `bb pr reviewers add ` - Add reviewer to an existing PR
**Repositories:**
- `bb repo list` / `bb repo view` / `bb repo clone workspace/repo`
- `bb repo default-reviewers list` / `add ` / `remove --yes` - Manage repo default reviewers
**Configuration:**
- `bb config set defaultWorkspace myworkspace`
- `bb auth status` - Check authentication
### Tips
- Auto-detects workspace/repo from git remotes; override with `-w` / `-r`
- All commands support `--json` for machine-readable output
- Run `bb --help` or `bb --help` for full usage
```
Run opencode in your project and try: **“What PRs are open?”** * Cursor Run this in your project root:
```bash
mkdir -p .cursor/rules && cat > .cursor/rules/bb-cli.mdc << 'RULE'
---
description: Bitbucket CLI - use `bb` for PR and repo operations
globs:
alwaysApply: true
---
# Bitbucket CLI (`bb`)
Use `bb` (`@pilatos/bitbucket-cli`) for Bitbucket operations.
## Key commands
- `bb pr create -t "title" -b "body"` - Create PR
- `bb pr list` - List open PRs (`--mine` for reviews, `--json` for scripts)
- `bb pr view/diff/checkout ` - Inspect PR
- `bb pr approve/decline/merge ` - Review and merge
- `bb pr merge --strategy squash --close-source-branch`
- `bb pr ready ` - Mark draft as ready
- `bb pr comments add "text"` - Comment on PR
- `bb repo list/view/clone` - Repository operations
- `bb config set defaultWorkspace ` - Set defaults
## Context
Auto-detects workspace/repo from git remotes. Override with `-w`/`-r` flags.
Use `--json` for machine-readable output. Run `bb --help` for full usage.
RULE
echo "✓ Rule created. Restart Cursor to activate."
```
* Windsurf Create `.windsurfrules` in your project root:
```markdown
## Bitbucket CLI (`bb`)
Use `bb` (`@pilatos/bitbucket-cli`) for Bitbucket operations.
**Key commands:**
- `bb pr create -t "title" -b "body"` - Create PR
- `bb pr list` - List open PRs (`--mine` for reviews, `--json` for scripts)
- `bb pr view/diff/checkout ` - Inspect PR
- `bb pr approve/decline/merge ` - Review and merge
- `bb pr merge --strategy squash --close-source-branch`
- `bb pr ready ` - Mark draft as ready
- `bb pr comments add "text"` - Comment on PR
- `bb repo list/view/clone` - Repository operations
- `bb config set defaultWorkspace ` - Set defaults
**Context:** Auto-detects workspace/repo from git remotes. Use `-w`/`-r` to override.
**Output:** Use `--json` for machine-readable output.
**Help:** Run `bb --help` or `bb --help` for full usage.
```
*** ## Example Workflows [Section titled “Example Workflows”](#example-workflows) These show what’s possible once your AI assistant knows about `bb`. Natural language works — exact phrasing doesn’t matter. ### Create and submit a PR [Section titled “Create and submit a PR”](#create-and-submit-a-pr)
```plaintext
You: Push my changes and create a PR titled "Add input validation"
with a description of what changed
AI: [Runs: git push -u origin feat/input-validation]
[Runs: bb pr create -t "Add input validation" \
-b "Adds server-side validation for email and password fields.
Includes unit tests and updates the API docs."]
✅ Created PR #47
https://bitbucket.org/acme/api/pull-requests/47
```
### Review multiple PRs at once [Section titled “Review multiple PRs at once”](#review-multiple-prs-at-once)
```plaintext
You: Show me all open PRs and summarize which ones are ready to merge
AI: [Runs: bb pr list --json]
[Runs: bb pr diff 42, bb pr diff 45, bb pr diff 46]
3 open PRs:
• #42 "Fix login timeout" — 12 lines, 2 approvals, CI passing. Ready.
• #45 "Refactor auth module" — 340 lines, no reviews, CI failing. Needs work.
• #46 "Update README" — 3 lines, 1 approval. Ready.
Want me to merge #42 and #46?
```
### Full review-and-merge cycle [Section titled “Full review-and-merge cycle”](#full-review-and-merge-cycle)
```plaintext
You: Check out PR 42, review the diff, and if it looks good,
approve and squash-merge it
AI: [Runs: bb pr checkout 42]
Checked out PR #42 on branch fix/login-timeout.
[Runs: bb pr diff 42]
Changes look clean — fixes the timeout by increasing the
retry limit from 3 to 5, with a new test covering the edge case.
[Runs: bb pr approve 42]
✅ Approved.
[Runs: bb pr merge 42 --strategy squash --close-source-branch]
✅ Merged PR #42 with squash strategy. Source branch deleted.
```
### Draft PR workflow [Section titled “Draft PR workflow”](#draft-pr-workflow)
```plaintext
You: Create a draft PR for my work-in-progress
AI: [Runs: bb pr create -t "WIP: New dashboard" --draft]
✅ Created draft PR #48
You: Mark PR 48 as ready and add Alice as reviewer
AI: [Runs: bb pr ready 48]
[Runs: bb pr reviewers add 48 {alice-uuid}]
✅ PR #48 is ready for review. Alice added as a reviewer.
```
*** ## Security [Section titled “Security”](#security) Caution Never commit API tokens to version control. Use environment variables or `bb auth login`. Your AI assistant never sees the raw token — it calls `bb` commands, and the CLI handles authentication internally. The `allowed-tools` field in the Claude Code skill restricts the AI to only running `bb` commands and reading files — no arbitrary shell access. For CI/CD or shared environments, use environment variables:
```bash
export BB_USERNAME="your-username"
export BB_API_TOKEN="your-api-token"
bb auth login # Reads from env vars automatically
```
### Required API token scopes [Section titled “Required API token scopes”](#required-api-token-scopes) | Scope | Required for | | ----------------------------- | ----------------------------------------------------------- | | `read:user:bitbucket` | `bb auth status` — verify identity | | `read:repository:bitbucket` | `bb repo list`, `bb repo view` — browse repos | | `write:repository:bitbucket` | `bb repo create` — create repos | | `admin:repository:bitbucket` | `bb repo delete` — delete repos (optional) | | `read:pullrequest:bitbucket` | `bb pr list`, `bb pr view`, `bb pr diff` — browse PRs | | `write:pullrequest:bitbucket` | `bb pr create`, `bb pr merge`, `bb pr approve` — manage PRs | *** ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) | Issue | Solution | | ----------------------------- | ------------------------------------------------------------------------------------------------- | | ”Not authenticated” | Run `bb auth login` or set `BB_USERNAME` + `BB_API_TOKEN` env vars | | Claude doesn’t use `bb` | Restart Claude Code after creating the skill file. Check `/bb-cli` shows in the slash menu | | ”Could not determine repo” | Run from a git repo with a Bitbucket remote, or pass `-w`/`-r` flags explicitly | | Skill not auto-activating | Invoke manually with `/bb-cli`, or check the `description` field in SKILL.md | | Cursor rule not loading | Ensure the file is at `.cursor/rules/bb-cli.mdc` with valid frontmatter. Restart Cursor | | opencode ignoring AGENTS.md | Ensure the file is in the project root (not a subdirectory). Restart opencode | | `bb` command not found | Install with `npm install -g @pilatos/bitbucket-cli`. Requires [Bun 1.0+](https://bun.sh) runtime | | AI using wrong flags | Tell the AI to run `bb --help` first | | Windsurf not picking up rules | Ensure `.windsurfrules` is in the project root. Restart Windsurf | *** ## `llms.txt` for IDE agents [Section titled “llms.txt for IDE agents”](#llmstxt-for-ide-agents) The docs site publishes the [`llms.txt`](https://llmstxt.org/) convention so agents that fetch documentation on demand (Cursor, Cline, Continue, Aider, and similar) can pull a clean markdown view of the full reference instead of scraping HTML: | URL | Contents | | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | [`/llms.txt`](https://bitbucket-cli.paulvanderlei.com/llms.txt) | Index pointing to the two content files below | | [`/llms-full.txt`](https://bitbucket-cli.paulvanderlei.com/llms-full.txt) | Every doc page concatenated as markdown | | [`/llms-small.txt`](https://bitbucket-cli.paulvanderlei.com/llms-small.txt) | Abridged subset (excludes Help / FAQ / Changelog) for tight context windows | All three are generated at build time, so they always match the live docs. You don’t need to do anything to consume them — tools that support `llms.txt` will discover them automatically. If your tool doesn’t, paste the URL into the chat (`@https://bitbucket-cli.paulvanderlei.com/llms-full.txt` in Cursor, for example). *** ## Related Guides [Section titled “Related Guides”](#related-guides) * [Scripting & Automation](/guides/scripting/) — JSON output, exit codes, and shell scripting patterns * [CI/CD Integration](/guides/cicd/) — Use `bb` in GitHub Actions, GitLab CI, Jenkins, and more * [JSON Output Reference](/reference/json-output/) — Detailed JSON schemas for all commands * [Error Codes](/reference/error-codes/) — Full list of exit codes and their meanings * [Command Reference](/commands/pr/) — Complete PR command documentation
# CI/CD Integration - GitHub Actions, GitLab, Jenkins, CircleCI
> Integrate Bitbucket CLI into your CI/CD pipelines. Step-by-step examples for GitHub Actions, GitLab CI, Jenkins, CircleCI, and generic pipelines with authentication and best practices.
The Bitbucket CLI can automate pull request workflows, add comments, and manage repositories in your CI/CD pipelines. ## Quick Setup [Section titled “Quick Setup”](#quick-setup) 1. **Store credentials as secrets** in your CI/CD platform * `BB_USERNAME` - Your Bitbucket username * `BB_API_TOKEN` - Your Bitbucket API token 2. **Install Bun and the CLI** in your pipeline
```bash
# Install Bun (required runtime)
curl -fsSL https://bun.sh/install | bash
# Install the CLI (can use npm/pnpm/bun)
npm install -g @pilatos/bitbucket-cli
```
3. **Authenticate** using environment variables
```bash
bb auth login
```
4. **Run commands** with explicit workspace/repo flags
```bash
bb pr list -w myworkspace -r myrepo --json
```
If your pipeline needs more than the default page size, include `--limit ` on list commands. *** ## Platform Examples [Section titled “Platform Examples”](#platform-examples) ### GitHub Actions [Section titled “GitHub Actions”](#github-actions)
```yaml
name: Bitbucket PR Check
on:
push:
branches: [main]
pull_request:
jobs:
check-bitbucket-prs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install Bitbucket CLI
run: npm install -g @pilatos/bitbucket-cli
- name: Authenticate
env:
BB_USERNAME: ${{ secrets.BB_USERNAME }}
BB_API_TOKEN: ${{ secrets.BB_API_TOKEN }}
run: bb auth login
- name: List Open PRs
run: |
bb pr list -w myworkspace -r myrepo --json > prs.json
echo "Open PRs: $(jq '.count' prs.json)"
```
#### Auto-Create PR on Push [Section titled “Auto-Create PR on Push”](#auto-create-pr-on-push)
```yaml
name: Auto-Create PR
on:
push:
branches:
- 'feature/**'
- 'fix/**'
jobs:
create-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Setup
run: npm install -g @pilatos/bitbucket-cli
- name: Create PR
env:
BB_USERNAME: ${{ secrets.BB_USERNAME }}
BB_API_TOKEN: ${{ secrets.BB_API_TOKEN }}
run: |
bb auth login
BRANCH=${GITHUB_REF#refs/heads/}
TITLE="$(echo $BRANCH | sed 's/[-_]/ /g' | sed 's/feature\///; s/fix\//Fix: /')"
# Check if PR already exists
EXISTING=$(bb pr list -w workspace -r repo --json | \
jq --arg branch "$BRANCH" '[.pullRequests[] | select(.source.branch.name == $branch)] | length')
if [ "$EXISTING" -eq 0 ]; then
bb pr create -w workspace -r repo \
-t "$TITLE" \
-s "$BRANCH" \
-d main
fi
```
*** ### GitLab CI [Section titled “GitLab CI”](#gitlab-ci)
```yaml
stages:
- check
variables:
BB_WORKSPACE: myworkspace
BB_REPO: myrepo
check-prs:
stage: check
image: oven/bun:latest
before_script:
- npm install -g @pilatos/bitbucket-cli
- bb auth login
script:
- bb pr list -w $BB_WORKSPACE -r $BB_REPO --json
- bb repo view -w $BB_WORKSPACE -r $BB_REPO
variables:
BB_USERNAME: $BB_USERNAME # From CI/CD variables
BB_API_TOKEN: $BB_API_TOKEN
```
*** ### Bitbucket Pipelines [Section titled “Bitbucket Pipelines”](#bitbucket-pipelines) Using the CLI within Bitbucket Pipelines itself:
```yaml
image: oven/bun:latest
pipelines:
default:
- step:
name: Check PRs
script:
- npm install -g @pilatos/bitbucket-cli
- bb auth login
# Use built-in variables
- bb pr list -w $BITBUCKET_WORKSPACE -r $BITBUCKET_REPO_SLUG --json
pull-requests:
'**':
- step:
name: PR Info
script:
- npm install -g @pilatos/bitbucket-cli
- bb auth login
- bb pr view $BITBUCKET_PR_ID -w $BITBUCKET_WORKSPACE -r $BITBUCKET_REPO_SLUG
definitions:
caches:
bun: ~/.bun
```
*** ### Jenkins [Section titled “Jenkins”](#jenkins) **Jenkinsfile:**
```groovy
pipeline {
agent any
environment {
BB_USERNAME = credentials('bitbucket-username')
BB_API_TOKEN = credentials('bitbucket-token')
}
stages {
stage('Setup') {
steps {
// Install Bun first (required runtime)
sh 'curl -fsSL https://bun.sh/install | bash'
sh 'export PATH="$HOME/.bun/bin:$PATH" && npm install -g @pilatos/bitbucket-cli'
sh 'export PATH="$HOME/.bun/bin:$PATH" && bb auth login'
}
}
stage('Check PRs') {
steps {
sh '''
export PATH="$HOME/.bun/bin:$PATH"
bb pr list -w myworkspace -r myrepo --json > prs.json
PR_COUNT=$(jq '.count' prs.json)
echo "Found $PR_COUNT open PRs"
'''
}
}
stage('Merge Ready PRs') {
when {
branch 'main'
}
steps {
sh '''
export PATH="$HOME/.bun/bin:$PATH"
# Get all open PR IDs, then check each for approval
PR_IDS=$(bb pr list -w myworkspace -r myrepo --json | \
jq -r '.pullRequests[].id')
for PR_ID in $PR_IDS; do
IS_APPROVED=$(bb pr view $PR_ID -w myworkspace -r myrepo --json | \
jq '[.participants[] | select(.approved == true)] | length > 0')
if [ "$IS_APPROVED" = "true" ]; then
echo "Merging approved PR #$PR_ID"
bb pr merge $PR_ID -w myworkspace -r myrepo --strategy squash
fi
sleep 1
done
'''
}
}
}
}
```
*** ### Azure DevOps [Section titled “Azure DevOps”](#azure-devops)
```yaml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
variables:
- group: bitbucket-credentials # Variable group with BB_USERNAME, BB_API_TOKEN
steps:
- script: |
curl -fsSL https://bun.sh/install | bash
echo "##vso[task.prependpath]$HOME/.bun/bin"
displayName: 'Install Bun'
- script: npm install -g @pilatos/bitbucket-cli
displayName: 'Install Bitbucket CLI'
- script: bb auth login
displayName: 'Authenticate'
env:
BB_USERNAME: $(BB_USERNAME)
BB_API_TOKEN: $(BB_API_TOKEN)
- script: |
bb pr list -w myworkspace -r myrepo --json
displayName: 'List PRs'
```
*** ## Common Use Cases [Section titled “Common Use Cases”](#common-use-cases) ### Auto-Create PR for Dependency Updates [Section titled “Auto-Create PR for Dependency Updates”](#auto-create-pr-for-dependency-updates)
```yaml
# GitHub Actions example
name: Dependency Update PR
on:
schedule:
- cron: '0 9 * * 1' # Weekly on Monday
jobs:
update-deps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Update dependencies
run: |
bun update
git config user.name "Bot"
git config user.email "bot@example.com"
git checkout -b deps/weekly-update
git add package*.json
git commit -m "chore: weekly dependency update" || exit 0
git push -u origin deps/weekly-update
- name: Create Bitbucket PR
env:
BB_USERNAME: ${{ secrets.BB_USERNAME }}
BB_API_TOKEN: ${{ secrets.BB_API_TOKEN }}
run: |
npm install -g @pilatos/bitbucket-cli
bb auth login
bb pr create -w workspace -r repo \
-t "chore: Weekly dependency update" \
-b "Automated dependency updates" \
-s deps/weekly-update \
-d main
```
### Merge Approved PRs Automatically [Section titled “Merge Approved PRs Automatically”](#merge-approved-prs-automatically)
```bash
#!/bin/bash
# auto-merge.sh - Run in CI on schedule
set -e
WORKSPACE="myworkspace"
REPO="myrepo"
# Get all open PR IDs, then check each for approval via pr view
open_prs=$(bb pr list -w "$WORKSPACE" -r "$REPO" --json | jq -r '.pullRequests[].id')
approved_prs=""
for pr_id in $open_prs; do
is_approved=$(bb pr view "$pr_id" -w "$WORKSPACE" -r "$REPO" --json | \
jq '[.participants[] | select(.approved == true)] | length > 0')
if [ "$is_approved" = "true" ]; then
approved_prs="$approved_prs $pr_id"
fi
sleep 1
done
for pr_id in $approved_prs; do
echo "Attempting to merge PR #$pr_id..."
if bb pr merge "$pr_id" -w "$WORKSPACE" -r "$REPO" --strategy squash --close-source-branch; then
echo "Successfully merged PR #$pr_id"
else
echo "Could not merge PR #$pr_id (may have conflicts or failing checks)"
fi
sleep 2
done
```
### Generate Changelog from Merged PRs [Section titled “Generate Changelog from Merged PRs”](#generate-changelog-from-merged-prs) generate-changelog.sh
```bash
#!/bin/bash
WORKSPACE="myworkspace"
REPO="myrepo"
SINCE_DATE=$(date -d '7 days ago' +%Y-%m-%d 2>/dev/null || \
date -v-7d +%Y-%m-%d)
echo "# Changelog - Week of $(date +%Y-%m-%d)"
echo ""
bb pr list -w "$WORKSPACE" -r "$REPO" -s MERGED --json | jq -r --arg since "$SINCE_DATE" '
.pullRequests[] |
select(.updated_on >= $since) |
"- \(.title) (#\(.id)) by @\(.author.nickname // .author.display_name // \"unknown\")"
'
```
*** ## Security Considerations [Section titled “Security Considerations”](#security-considerations) ### Token Scopes [Section titled “Token Scopes”](#token-scopes) Create a dedicated CI/CD token with minimal permissions: | Use Case | Required Scopes | | ---------------- | ----------------------------------------------------------- | | Verify identity | `read:user:bitbucket` | | Read-only checks | + `read:repository:bitbucket`, `read:pullrequest:bitbucket` | | Create/merge PRs | + `write:pullrequest:bitbucket` | | Create repos | + `write:repository:bitbucket` | | Delete repos | + `admin:repository:bitbucket` | ### Secrets Management [Section titled “Secrets Management”](#secrets-management) * GitHub Actions Store in **Settings > Secrets and variables > Actions** * GitLab Store in **Settings > CI/CD > Variables** (masked, protected) * Jenkins Use **Credentials** plugin with Secret text type ### Audit Logging [Section titled “Audit Logging”](#audit-logging) Track CLI usage in your pipelines:
```bash
echo "Running bb at $(date) by ${CI_USER:-unknown}"
bb pr list -w workspace -r repo --json | tee pr-list-$(date +%s).json
```
*** ## Troubleshooting CI/CD [Section titled “Troubleshooting CI/CD”](#troubleshooting-cicd) ### Authentication Fails [Section titled “Authentication Fails”](#authentication-fails)
```plaintext
Error: Authentication required
```
**Check:** 1. Environment variables are set correctly 2. Secrets are available to the job 3. Token hasn’t expired **Debug:**
```bash
echo "Username set: $([ -n "$BB_USERNAME" ] && echo 'yes' || echo 'no')"
echo "Token set: $([ -n "$BB_API_TOKEN" ] && echo 'yes' || echo 'no')"
```
### Rate Limiting in Loops [Section titled “Rate Limiting in Loops”](#rate-limiting-in-loops) Add delays between API calls:
```bash
for pr_id in $pr_ids; do
bb pr view "$pr_id" --json
sleep 2 # Prevent rate limiting
done
```
### Command Not Found [Section titled “Command Not Found”](#command-not-found) Ensure Bun and the CLI are installed:
```bash
# Install Bun (required runtime)
curl -fsSL https://bun.sh/install | bash
export PATH="$HOME/.bun/bin:$PATH"
# Install CLI
npm install -g @pilatos/bitbucket-cli
bb --version
```
# Understanding Repository Context
> How the CLI determines which workspace and repository to use
Many commands in the Bitbucket CLI need to know which workspace and repository you’re working with. The CLI uses a sophisticated resolution system to determine this automatically, so you don’t always need to specify them explicitly. ## Context Resolution Order [Section titled “Context Resolution Order”](#context-resolution-order) The CLI checks multiple sources in this order: 1. **Command-line flags** (`--workspace` and `--repo`) 2. **Current Git repository** (automatically detected from your git remote URL) 3. **Config file defaults** (`defaultWorkspace` setting) 4. **Combinations** of the above sources ### Typical Local Layout [Section titled “Typical Local Layout”](#typical-local-layout) When you run `bb` from `myworkspace-tools/`, the CLI reads the Bitbucket remote from `.git/` and uses that workspace/repo as context. ### Examples [Section titled “Examples”](#examples) #### Scenario 1: Inside a Git Repository [Section titled “Scenario 1: Inside a Git Repository”](#scenario-1-inside-a-git-repository)
```bash
# You're in /projects/myrepo, which has a Bitbucket remote
cd /projects/myrepo
bb pr list # ✅ Uses workspace/repo from git remote
```
The CLI reads your `.git/config` and extracts the workspace and repository from the remote URL. #### Scenario 2: Using Command-Line Flags [Section titled “Scenario 2: Using Command-Line Flags”](#scenario-2-using-command-line-flags)
```bash
# Explicit specification always takes precedence
bb pr list -w myworkspace -r myrepo # ✅ Uses specified values
```
This works from anywhere, even outside a git repository. #### Scenario 3: Using Config Defaults [Section titled “Scenario 3: Using Config Defaults”](#scenario-3-using-config-defaults)
```bash
# Set defaults once
bb config set defaultWorkspace myworkspace
# Then use commands without flags
bb repo list # ✅ Uses defaultWorkspace from config
```
For PR commands, you still need repository context (from git remote or `-r`). #### Scenario 4: Mixed Sources [Section titled “Scenario 4: Mixed Sources”](#scenario-4-mixed-sources)
```bash
# Inside a git repo with workspace "gitworkspace/gitrepo"
cd /projects/myrepo
# Override just the workspace
bb pr list -w anotherworkspace # Uses "anotherworkspace/gitrepo"
# Override just the repo
bb pr list -r anotherrepo # Uses "gitworkspace/anotherrepo"
```
## Repository Argument Formats [Section titled “Repository Argument Formats”](#repository-argument-formats) Commands that accept a repository argument support multiple formats: ### Full Format: `workspace/repo` [Section titled “Full Format: workspace/repo”](#full-format-workspacerepo)
```bash
bb repo view myworkspace/myrepo
bb repo delete myworkspace/myrepo --yes
```
This explicitly specifies both workspace and repository. ### Short Format: `repo` only [Section titled “Short Format: repo only”](#short-format-repo-only)
```bash
# Uses default workspace from config or git context
bb repo view myrepo
```
The CLI will: 1. Check if you set a default workspace via `bb config set defaultWorkspace` 2. Check if you’re in a git repository and use its workspace 3. Error if neither is available ## Supported Remote URL Formats [Section titled “Supported Remote URL Formats”](#supported-remote-url-formats) When detecting context from git, the CLI supports these remote URL formats: ### SSH Format [Section titled “SSH Format”](#ssh-format)
```plaintext
git@bitbucket.org:workspace/repo.git
git@bitbucket.org:workspace/repo
```
### HTTPS Format [Section titled “HTTPS Format”](#https-format)
```plaintext
https://bitbucket.org/workspace/repo.git
https://bitbucket.org/workspace/repo
https://username@bitbucket.org/workspace/repo.git
```
## Error Messages [Section titled “Error Messages”](#error-messages) ### ”Could not determine repository” [Section titled “”Could not determine repository””](#could-not-determine-repository) This error appears when the CLI can’t figure out which workspace/repo to use. **Solutions:** 1. Use explicit flags: `-w myworkspace -r myrepo` 2. Run from within a Bitbucket repository 3. Set defaults: `bb config set defaultWorkspace myworkspace` ### ”Repository not found” [Section titled “”Repository not found””](#repository-not-found) The workspace/repo combination was determined but doesn’t exist. **Check:** 1. Spelling of workspace and repository names 2. That you have access to the repository 3. That the repository exists in that workspace ## Best Practices [Section titled “Best Practices”](#best-practices) ### For Daily Work [Section titled “For Daily Work”](#for-daily-work) Set your default workspace if you primarily work with one:
```bash
bb config set defaultWorkspace myworkspace
```
Then work from within your git repositories - context will be automatic. ### For Scripts [Section titled “For Scripts”](#for-scripts) Always use explicit flags for reliability:
```bash
#!/bin/bash
WORKSPACE="myworkspace"
REPO="myrepo"
bb pr list -w "$WORKSPACE" -r "$REPO" --json
```
### For Multi-Workspace Teams [Section titled “For Multi-Workspace Teams”](#for-multi-workspace-teams) Don’t set a default workspace. Instead, use explicit flags or work from within cloned repositories:
```bash
# Each repository is self-contained
cd project-a && bb pr list # Uses project-a's workspace
cd ../project-b && bb pr list # Uses project-b's workspace
```
## Tips [Section titled “Tips”](#tips) * Use `bb repo view` with no arguments to see what context the CLI detected * The `--json` flag works with most commands for scripting * Global flags (`--workspace`, `--repo`, `--json`, `--no-color`) are available across commands * The `-w` short flag always maps to `--workspace` globally
# Scripting & Automation - Bitbucket CLI for CI/CD Workflows
> Learn how to use Bitbucket CLI in automation scripts and CI/CD pipelines. JSON output, exit codes, error handling, and practical examples for DevOps workflows.
The Bitbucket CLI is designed for both interactive use and automation. This guide covers JSON output, exit codes, and scripting patterns. ## JSON Output Mode [Section titled “JSON Output Mode”](#json-output-mode) All commands support the `--json` flag for machine-readable output:
```bash
bb pr list --json
bb repo list --json
bb pr view 42 --json
```
For list-style commands, results are limited by default. Pass `--limit` when your automation needs more rows. ### Built-in Field Selection and jq [Section titled “Built-in Field Selection and jq”](#built-in-field-selection-and-jq) Two flags inspired by the [`gh` CLI](https://cli.github.com/manual/gh_help_formatting) let you slice and filter output without an external `jq` binary:
```bash
# Project to a comma-separated field list
bb pr list --json id,title,state
# Pipe through embedded jq (requires --json)
bb pr list --json --jq '.pullRequests[].title'
# Combine both
bb pr list --json id,title,state \
--jq '.[] | select(.state == "OPEN") | .title'
```
When `--json fields` is passed against a list-style command, the wrapper envelope is dropped and the field list is projected per-item — the result is a flat array. See [JSON Output reference](/reference/json-output/) for details. ### Parsing with jq [Section titled “Parsing with jq”](#parsing-with-jq) The built-in `--jq` matches the syntax of the standalone [jq](https://jqlang.github.io/jq/) binary, so existing expressions work either way:
```bash
# Built-in (no external dependency, cross-platform)
bb pr list --json --jq '.pullRequests[].title'
# External jq (equivalent)
bb pr list --json | jq '.pullRequests[].title'
# Get PR count
bb pr list --json --jq '.count'
# Filter by state
bb pr list -s MERGED --json --jq '.count'
# Project specific fields
bb pr list --json --jq '.pullRequests[] | {id, title, author: .author.display_name}'
# Filter by author
bb pr list --json --jq '.pullRequests[] | select((.author.nickname // .author.display_name) == "alice")'
# PR URLs
bb pr list --json --jq '.pullRequests[].links.html.href'
# Web diff URL for a PR
bb pr diff 42 --web --json --jq '.url'
```
### Common jq Patterns [Section titled “Common jq Patterns”](#common-jq-patterns)
```bash
# PRs updated in the last 7 days
bb pr list --json | jq --arg date "$(date -d '7 days ago' -Iseconds 2>/dev/null || \
date -v-7d -Iseconds)" \
'.pullRequests[] | select(.updated_on > $date)'
# PRs targeting main branch
bb pr list --json | jq '.pullRequests[] | select(.destination.branch.name == "main")'
# Group PRs by author
bb pr list --json | jq '.pullRequests | group_by(.author.nickname // .author.display_name) | map({author: (.[0].author.nickname // .[0].author.display_name), count: length})'
```
*** ## Exit Codes [Section titled “Exit Codes”](#exit-codes) The CLI uses a deliberately small exit-code surface: | Code | Meaning | | ---- | ------------------------------------------------------------- | | 0 | Success | | 1 | Any failure (authentication, API, validation, network, jq, …) | There is **no `2`/`3`/etc. mapping** — every failure exits with `1`. To branch on the specific failure mode in a script, parse the JSON error written to stderr and read its `code` field, which corresponds to one of the [error codes](/reference/error-codes/).
```bash
if ! bb pr view 999 --json > out.json 2> err.json; then
code=$(jq -r '.code' err.json)
case "$code" in
1001|1002|1003) echo "auth problem";;
2002) echo "PR not found";;
*) echo "other failure ($code)";;
esac
fi
```
### Checking Exit Codes [Section titled “Checking Exit Codes”](#checking-exit-codes)
```bash
#!/bin/bash
if bb pr list -w myworkspace -r myrepo > /dev/null 2>&1; then
echo "Success"
else
echo "Failed with exit code: $?"
fi
```
### Error Handling Patterns [Section titled “Error Handling Patterns”](#error-handling-patterns)
```bash
#!/bin/bash
set -e # Exit on any error
# Or handle errors explicitly
bb pr list --json > prs.json || {
echo "Failed to list PRs"
exit 1
}
```
```bash
if ! bb config get invalidKey --json > out.json 2> err.json; then
jq '.' err.json
exit 1
fi
```
*** ## Environment Variables [Section titled “Environment Variables”](#environment-variables) For non-interactive scripts, use environment variables:
```bash
export BB_USERNAME=myuser
export BB_API_TOKEN=ATBB_token
bb auth login # Uses env vars
bb pr list -w workspace -r repo
```
See [Environment Variables Reference](/reference/environment-variables/) for details. *** ## Built-in Resilience [Section titled “Built-in Resilience”](#built-in-resilience) The CLI handles common transient failures automatically — you don’t need to implement this yourself in most cases. ### Automatic Retry [Section titled “Automatic Retry”](#automatic-retry) API requests that fail with transient errors (HTTP 429, 502, 503, 504) are retried automatically up to 3 times with exponential backoff. This means rate-limited or temporarily unavailable responses are handled without any extra scripting. ### OAuth Token Refresh [Section titled “OAuth Token Refresh”](#oauth-token-refresh) OAuth access tokens expire after 2 hours. The CLI refreshes them automatically — both proactively (before expiry) and reactively (on 401 responses). Long-running scripts using OAuth don’t need manual re-authentication. *** ## Scripting Best Practices [Section titled “Scripting Best Practices”](#scripting-best-practices) ### Always Use Explicit Flags [Section titled “Always Use Explicit Flags”](#always-use-explicit-flags) Don’t rely on context detection in scripts:
```bash
# Good - explicit and reliable
bb pr list -w myworkspace -r myrepo --json
# Bad - may fail if context can't be detected
bb pr list --json
```
### Handle Persistent Failures [Section titled “Handle Persistent Failures”](#handle-persistent-failures) The CLI retries transient errors automatically (see [Built-in Resilience](#built-in-resilience) above). For persistent failures, handle the exit code:
```bash
#!/bin/bash
if ! bb pr list -w workspace -r repo --json > prs.json 2>error.json; then
echo "Failed to list PRs"
cat error.json
exit 1
fi
```
### Add Delays in Loops [Section titled “Add Delays in Loops”](#add-delays-in-loops) When making many sequential API calls, add short delays to avoid hitting rate limits:
```bash
#!/bin/bash
for pr_id in $(bb pr list --json | jq -r '.pullRequests[].id'); do
bb pr view "$pr_id" --json
sleep 1
done
```
*** ## Example Scripts [Section titled “Example Scripts”](#example-scripts) ### Batch PR Approval [Section titled “Batch PR Approval”](#batch-pr-approval) Approve all open PRs from a specific author:
```bash
#!/bin/bash
set -e
WORKSPACE="myworkspace"
REPO="myrepo"
AUTHOR="trusted-bot"
echo "Finding PRs from $AUTHOR..."
pr_ids=$(bb pr list -w "$WORKSPACE" -r "$REPO" --json | \
jq -r --arg author "$AUTHOR" '.pullRequests[] | select((.author.nickname // .author.display_name) == $author) | .id')
for pr_id in $pr_ids; do
echo "Approving PR #$pr_id..."
bb pr approve "$pr_id" -w "$WORKSPACE" -r "$REPO"
sleep 1
done
echo "Done!"
```
### PR Status Report [Section titled “PR Status Report”](#pr-status-report) Generate a markdown report of open PRs:
```bash
#!/bin/bash
WORKSPACE="myworkspace"
REPO="myrepo"
echo "# Open Pull Requests"
echo ""
echo "Generated: $(date)"
echo ""
bb pr list -w "$WORKSPACE" -r "$REPO" --json | jq -r '.pullRequests[] |
"## PR #\(.id): \(.title)\n" +
"- **Author:** \(.author.display_name)\n" +
"- **Branch:** \(.source.branch.name) → \(.destination.branch.name)\n" +
"- **Created:** \(.created_on)\n" +
"- **Link:** \(.links.html.href)\n"'
```
### Auto-Close Stale PRs [Section titled “Auto-Close Stale PRs”](#auto-close-stale-prs) Decline PRs not updated in 30 days:
```bash
#!/bin/bash
set -e
WORKSPACE="myworkspace"
REPO="myrepo"
DAYS_OLD=30
cutoff=$(date -d "$DAYS_OLD days ago" -Iseconds 2>/dev/null || \
date -v-${DAYS_OLD}d -Iseconds) # macOS fallback
echo "Finding PRs older than $DAYS_OLD days..."
stale_prs=$(bb pr list -w "$WORKSPACE" -r "$REPO" --json | \
jq -r --arg cutoff "$cutoff" '.pullRequests[] | select(.updated_on < $cutoff) | .id')
if [ -z "$stale_prs" ]; then
echo "No stale PRs found"
exit 0
fi
for pr_id in $stale_prs; do
echo "Declining stale PR #$pr_id..."
bb pr decline "$pr_id" -w "$WORKSPACE" -r "$REPO"
sleep 1
done
```
# Recipes
> Cookbook of common Bitbucket CLI workflows — auto-merge, bulk reviewer assignment, fork sync, jq analytics, and retry wrappers.
A cookbook of ready-to-copy workflows that combine `bb` commands with `jq` and shell to solve the patterns we see most often. Each recipe is a complete, runnable script — drop it into a CI job or a dotfile and adjust workspace/repo names. If you are looking for the *primitives* these recipes are built on, see the [Scripting & Automation guide](/guides/scripting/) and the [CI/CD Integration guide](/guides/cicd/). ## Available recipes [Section titled “Available recipes”](#available-recipes) [Auto-merge when CI is green ](/recipes/auto-merge-on-ci-green/)Poll bb pr checks until all checks pass, then merge — the GitOps-friendly way. [Bulk reviewer assignment ](/recipes/bulk-reviewer-assignment/)Assign a fixed list of reviewers across many open PRs (team rotations, onboarding). [Fork synchronization ](/recipes/fork-synchronization/)Fetch upstream, rebase your fork, and push the result for fork-based contribution flows. [Reporting & analytics with jq ](/recipes/reporting-analytics/)Count PRs per state, sum diff sizes, group by author, and export to CSV. [Retry wrapper for transient failures ](/recipes/retry-wrapper/)A shell wrapper that retries bb invocations with exponential backoff for persistent flakes. ## Conventions used in these recipes [Section titled “Conventions used in these recipes”](#conventions-used-in-these-recipes) * All recipes assume `bb auth login` has already succeeded (interactively or via `BB_USERNAME` / `BB_API_TOKEN` env vars). * `WORKSPACE` and `REPO` are referenced as shell variables — set them at the top of the script or export them from your CI environment. * The CLI already retries transient HTTP 429 / 5xx errors up to 3 times with exponential backoff. The [retry wrapper recipe](/recipes/retry-wrapper/) is only for failures that persist past that. * `--json` output shapes are stable; see the [JSON Output reference](/reference/json-output/) for the envelope structure of list-style commands.
# Auto-merge when CI is green
> Poll bb pr checks until all CI checks have passed, then merge the pull request — a safe, GitOps-friendly auto-merge pattern.
The “merge approved PRs” pattern in the [CI/CD guide](/guides/cicd/#merge-approved-prs-automatically) only checks `participants[].approved` — it ignores the actual CI status. This recipe adds the missing piece: poll [`bb pr checks`](/commands/pr/activity-and-checks/#bb-pr-checks) until every status is `SUCCESSFUL`, then merge. ## What “all-green” means [Section titled “What “all-green” means”](#what-all-green-means) `bb pr checks --json` returns a stable envelope. The relevant shape:
```json
{
"pullRequestId": 42,
"workspace": "myworkspace",
"repoSlug": "myrepo",
"summary": {
"successful": 3,
"failed": 0,
"pending": 0
},
"statuses": [
{
"key": "build",
"name": "Build & Test",
"state": "SUCCESSFUL",
"description": "Build #1234 succeeded",
"url": "https://ci.example.com/build/1234",
"updatedOn": "2025-01-01T12:00:00Z"
}
]
}
```
Possible `state` values: `SUCCESSFUL`, `FAILED`, `INPROGRESS`, `STOPPED`. A PR is considered all-green when **at least one check exists** *and* every status is `SUCCESSFUL`. Treat zero checks as “not ready” — most teams want at least one passing build before auto-merge fires. ### jq filter for all-green [Section titled “jq filter for all-green”](#jq-filter-for-all-green)
```bash
# Returns "true" only if ≥1 check exists and every state is SUCCESSFUL
bb pr checks 42 --json --jq '
(.statuses | length) > 0
and (.statuses | all(.state == "SUCCESSFUL"))
'
```
If you want to also gate on approval:
```bash
bb pr view 42 --json --jq '
[.participants[] | select(.approved == true)] | length > 0
'
```
## Recipe: poll-then-merge [Section titled “Recipe: poll-then-merge”](#recipe-poll-then-merge) Drop this into a scheduled CI job or run locally. It polls a single PR until checks settle, then merges.
```bash
#!/bin/bash
# auto-merge-on-green.sh - Wait for CI to pass, then merge.
set -euo pipefail
WORKSPACE="${WORKSPACE:-myworkspace}"
REPO="${REPO:-myrepo}"
PR_ID="${1:?Usage: $0 }"
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-1800}" # 30 minutes
POLL_INTERVAL="${POLL_INTERVAL:-30}"
deadline=$(( $(date +%s) + TIMEOUT_SECONDS ))
while true; do
if [ "$(date +%s)" -gt "$deadline" ]; then
echo "Timed out waiting for PR #$PR_ID checks" >&2
exit 1
fi
checks_json=$(bb pr checks "$PR_ID" -w "$WORKSPACE" -r "$REPO" --json)
failed=$(echo "$checks_json" | jq '.summary.failed')
pending=$(echo "$checks_json" | jq '.summary.pending')
total=$(echo "$checks_json" | jq '.statuses | length')
if [ "$failed" -gt 0 ]; then
echo "PR #$PR_ID has $failed failed check(s); aborting." >&2
exit 1
fi
if [ "$total" -gt 0 ] && [ "$pending" -eq 0 ]; then
echo "All $total checks passed for PR #$PR_ID — merging."
break
fi
echo "PR #$PR_ID: $pending pending / $total total — sleeping ${POLL_INTERVAL}s"
sleep "$POLL_INTERVAL"
done
bb pr merge "$PR_ID" \
-w "$WORKSPACE" -r "$REPO" \
--strategy squash --close-source-branch
```
### Usage [Section titled “Usage”](#usage)
```bash
WORKSPACE=myworkspace REPO=myrepo ./auto-merge-on-green.sh 42
```
## Recipe: scan all open PRs [Section titled “Recipe: scan all open PRs”](#recipe-scan-all-open-prs) Run this on a schedule (cron, GitHub Actions cron trigger, Bitbucket Pipelines schedule). It merges every approved PR whose checks are all green and skips the rest silently.
```bash
#!/bin/bash
# auto-merge-scan.sh - Merge every approved, all-green PR.
set -euo pipefail
WORKSPACE="${WORKSPACE:-myworkspace}"
REPO="${REPO:-myrepo}"
open_prs=$(bb pr list -w "$WORKSPACE" -r "$REPO" --json --jq '.pullRequests[].id')
for pr_id in $open_prs; do
approved=$(bb pr view "$pr_id" -w "$WORKSPACE" -r "$REPO" --json --jq '
[.participants[] | select(.approved == true)] | length > 0
')
[ "$approved" = "true" ] || { echo "PR #$pr_id: not approved"; continue; }
green=$(bb pr checks "$pr_id" -w "$WORKSPACE" -r "$REPO" --json --jq '
(.statuses | length) > 0
and (.statuses | all(.state == "SUCCESSFUL"))
')
[ "$green" = "true" ] || { echo "PR #$pr_id: checks not green"; continue; }
echo "Merging PR #$pr_id"
if ! bb pr merge "$pr_id" -w "$WORKSPACE" -r "$REPO" \
--strategy squash --close-source-branch; then
echo "PR #$pr_id: merge failed (conflicts or branch policy)" >&2
fi
sleep 2 # gentle pacing across many PRs
done
```
Caution `bb pr merge` will still fail if the destination branch has *branch restrictions* (e.g., required reviewer counts, merge checks). The script above logs that and continues. Don’t treat a passing CI job and an approval as sufficient policy on their own — Bitbucket’s branch restrictions are the ultimate gate. ## Related [Section titled “Related”](#related) * [`bb pr checks`](/commands/pr/activity-and-checks/#bb-pr-checks) — the underlying command * [`bb pr merge`](/commands/pr/review-and-merge/) — merge strategies and flags * [Scripting & Automation](/guides/scripting/) — JSON output, exit codes, jq patterns
# Bulk reviewer assignment
> Assign a list of reviewers across many open pull requests at once — useful for team rotations, onboarding, and review coverage policies.
The [Scripting guide](/guides/scripting/#example-scripts) covers batch *approval*, but assigning reviewers across many PRs in one pass is a separate workflow. This recipe handles team rotations, onboarding new reviewers, and enforcing minimum reviewer coverage on existing PRs. ## Recipe: assign a fixed reviewer list [Section titled “Recipe: assign a fixed reviewer list”](#recipe-assign-a-fixed-reviewer-list) The script below adds every username in `REVIEWERS` to every open PR in `WORKSPACE/REPO`. Existing reviewers are not removed; if a reviewer is already assigned, [`bb pr reviewers add`](/commands/pr/reviewers/#bb-pr-reviewers-add) is a no-op. bulk-assign-reviewers.sh
```bash
#!/bin/bash
set -euo pipefail
WORKSPACE="${WORKSPACE:-myworkspace}"
REPO="${REPO:-myrepo}"
# Space-separated usernames (Bitbucket handles, not display names)
REVIEWERS="${REVIEWERS:-alice bob charlie}"
# Optional: skip PRs authored by a reviewer (you can't review your own PR)
SKIP_SELF_REVIEW="${SKIP_SELF_REVIEW:-true}"
open_prs=$(bb pr list -w "$WORKSPACE" -r "$REPO" --json \
--jq '.pullRequests[] | "\(.id)\t\(.author.nickname // .author.display_name)"')
while IFS=$'\t' read -r pr_id author; do
[ -n "$pr_id" ] || continue
echo "PR #$pr_id (by $author)"
for reviewer in $REVIEWERS; do
if [ "$SKIP_SELF_REVIEW" = "true" ] && [ "$reviewer" = "$author" ]; then
echo " - skip $reviewer (PR author)"
continue
fi
if bb pr reviewers add "$pr_id" "$reviewer" \
-w "$WORKSPACE" -r "$REPO" >/dev/null 2>&1; then
echo " + added $reviewer"
else
echo " ! failed to add $reviewer (user not found, or perms)" >&2
fi
sleep 1 # rate-limit cushion
done
done <<< "$open_prs"
```
### Usage [Section titled “Usage”](#usage)
```bash
WORKSPACE=myworkspace REPO=myrepo \
REVIEWERS="alice bob charlie" \
./bulk-assign-reviewers.sh
```
## Recipe: rotation by hash bucket [Section titled “Recipe: rotation by hash bucket”](#recipe-rotation-by-hash-bucket) If you want each PR to get *one* reviewer from a pool — for a round-robin team rotation — hash the PR ID into the reviewer list. This produces a stable, reproducible assignment without a database. rotation-assign.sh
```bash
#!/bin/bash
set -euo pipefail
WORKSPACE="${WORKSPACE:-myworkspace}"
REPO="${REPO:-myrepo}"
POOL=(alice bob charlie dana)
open_prs=$(bb pr list -w "$WORKSPACE" -r "$REPO" --json --jq '.pullRequests[].id')
for pr_id in $open_prs; do
idx=$(( pr_id % ${#POOL[@]} ))
reviewer="${POOL[$idx]}"
echo "PR #$pr_id -> $reviewer"
bb pr reviewers add "$pr_id" "$reviewer" -w "$WORKSPACE" -r "$REPO" || true
sleep 1
done
```
## Handling rate limits [Section titled “Handling rate limits”](#handling-rate-limits) The CLI already retries 429 responses up to 3 times automatically. For *very* large bulk operations (hundreds of PRs × multiple reviewers), prefer: 1. A larger sleep between PRs (`sleep 2` or `sleep 3`). 2. Splitting the run across cron windows. 3. Wrapping individual `bb` calls in the [retry wrapper](/recipes/retry-wrapper/) for the rare case of *persistent* 429s. ## Related [Section titled “Related”](#related) * [`bb pr reviewers add`](/commands/pr/reviewers/#bb-pr-reviewers-add) — single-PR command this recipe wraps * [`bb repo default-reviewers`](/commands/repo/) — repo-level defaults applied at PR creation time, often a better fit if you want this on *new* PRs only * [Reviewers reference](/commands/pr/reviewers/) — full subcommand reference
# Fork synchronization
> Keep a forked Bitbucket repository up to date with its upstream — fetch, rebase, and push using bb and git together.
Fork-based contribution is common in open-source workflows: you fork an upstream repo, work on a feature branch in your fork, and open a PR back to upstream. Forks drift quickly, so you need a routine sync. This recipe combines `bb repo view` to discover the upstream URL and plain `git` for the fetch/rebase/push. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * Your local clone is the **fork**, not the upstream. * `origin` points at your fork. * The upstream is reachable as a separate remote (we’ll add it if missing). * You have permission to push to your fork’s `main` (or whichever branch you want to keep in sync). ## Recipe: one-shot sync [Section titled “Recipe: one-shot sync”](#recipe-one-shot-sync)
```bash
#!/bin/bash
# sync-fork.sh - Keep a fork's main branch in sync with its upstream.
set -euo pipefail
UPSTREAM_WORKSPACE="${UPSTREAM_WORKSPACE:?set UPSTREAM_WORKSPACE}"
UPSTREAM_REPO="${UPSTREAM_REPO:?set UPSTREAM_REPO}"
BRANCH="${BRANCH:-main}"
# 1. Look up the upstream clone URL via bb (HTTPS).
upstream_url=$(bb repo view \
-w "$UPSTREAM_WORKSPACE" -r "$UPSTREAM_REPO" --json \
--jq '.links.clone[] | select(.name == "https") | .href')
if [ -z "$upstream_url" ]; then
echo "Could not resolve HTTPS clone URL for $UPSTREAM_WORKSPACE/$UPSTREAM_REPO" >&2
exit 1
fi
# 2. Add the upstream remote if it isn't there.
if ! git remote get-url upstream >/dev/null 2>&1; then
echo "Adding upstream remote: $upstream_url"
git remote add upstream "$upstream_url"
else
git remote set-url upstream "$upstream_url"
fi
# 3. Fetch upstream and your fork.
git fetch upstream "$BRANCH"
git fetch origin "$BRANCH"
# 4. Switch to the branch and rebase onto upstream.
git checkout "$BRANCH"
git rebase "upstream/$BRANCH"
# 5. Push the rebased branch back to your fork.
# Use --force-with-lease, NOT --force, so concurrent fork-side pushes aren't clobbered.
git push --force-with-lease origin "$BRANCH"
echo "Fork '$BRANCH' synced with upstream $UPSTREAM_WORKSPACE/$UPSTREAM_REPO"
```
### Usage [Section titled “Usage”](#usage)
```bash
UPSTREAM_WORKSPACE=acme \
UPSTREAM_REPO=widget \
BRANCH=main \
./sync-fork.sh
```
Caution The script rebases instead of merging. If `main` on your fork has commits that aren’t on upstream, the rebase will rewrite their hashes — anyone else pulling from your fork’s `main` will see history change. Use a merge instead (`git merge upstream/$BRANCH`) if your fork shares `main` with collaborators. ## Recipe: sync, then open a PR for a feature branch [Section titled “Recipe: sync, then open a PR for a feature branch”](#recipe-sync-then-open-a-pr-for-a-feature-branch) A common follow-up: after syncing `main`, rebase your feature branch and open a cross-fork PR back to upstream. `bb pr create` accepts source branch + destination workspace/repo, so you can target the upstream from your fork. sync-and-pr.sh
```bash
#!/bin/bash
set -euo pipefail
UPSTREAM_WORKSPACE="${UPSTREAM_WORKSPACE:?}"
UPSTREAM_REPO="${UPSTREAM_REPO:?}"
FORK_WORKSPACE="${FORK_WORKSPACE:?}" # your workspace
FORK_REPO="${FORK_REPO:?}" # your fork's repo slug
FEATURE_BRANCH="${FEATURE_BRANCH:?}"
TITLE="${TITLE:-Update from $FEATURE_BRANCH}"
# 1. Sync main, then rebase the feature branch onto fresh main.
BRANCH=main ./sync-fork.sh
git checkout "$FEATURE_BRANCH"
git rebase main
git push --force-with-lease origin "$FEATURE_BRANCH"
# 2. Open a PR in the upstream repo, sourced from the fork's branch.
# Bitbucket Cloud uses cross-repo PRs by passing the source as a fork.
bb pr create \
-w "$UPSTREAM_WORKSPACE" -r "$UPSTREAM_REPO" \
-t "$TITLE" \
-s "$FEATURE_BRANCH" \
-d main
```
## Related [Section titled “Related”](#related) * [Repository Context](/guides/repository-context/) — how `bb` resolves workspace/repo from your git remote * [`bb repo view`](/commands/repo/) — used here to fetch the upstream HTTPS clone URL * [`bb pr create`](/commands/pr/create-and-edit/) — for the second recipe’s cross-fork PR
# Reporting & analytics with jq
> Count PRs per state, sum diff sizes, group by author, and export to CSV — practical jq filters built on bb pr list --json.
The [Scripting guide](/guides/scripting/#common-jq-patterns) lists three starter jq patterns. This recipe expands that into a small analytics toolkit you can paste into a weekly report job. All recipes assume:
```bash
WORKSPACE=myworkspace
REPO=myrepo
```
## Count PRs per state [Section titled “Count PRs per state”](#count-prs-per-state) `bb pr list` only returns one state at a time, so to count across all states fetch each separately and combine:
```bash
for state in OPEN MERGED DECLINED SUPERSEDED; do
count=$(bb pr list -w "$WORKSPACE" -r "$REPO" -s "$state" --json --jq '.count')
printf "%-12s %s\n" "$state" "$count"
done
```
Sample output:
```plaintext
OPEN 12
MERGED 340
DECLINED 8
SUPERSEDED 2
```
If you only need a snapshot of currently open PRs grouped by state attribute, a one-liner suffices:
```bash
bb pr list -w "$WORKSPACE" -r "$REPO" --json --jq '
.pullRequests
| group_by(.state)
| map({ state: .[0].state, count: length })
'
```
## Sum additions and deletions across PRs [Section titled “Sum additions and deletions across PRs”](#sum-additions-and-deletions-across-prs) `pr list` does not include diff stats — they come from `bb pr diff --json --stat` (or equivalent). For aggregate volume, walk every PR and sum:
```bash
#!/bin/bash
total_added=0
total_deleted=0
for pr_id in $(bb pr list -w "$WORKSPACE" -r "$REPO" -s MERGED --json \
--jq '.pullRequests[].id'); do
stats=$(bb pr diff "$pr_id" -w "$WORKSPACE" -r "$REPO" --stat --json)
added=$(echo "$stats" | jq '[.files[].additions] | add // 0')
deleted=$(echo "$stats" | jq '[.files[].deletions] | add // 0')
total_added=$(( total_added + added ))
total_deleted=$(( total_deleted + deleted ))
sleep 1
done
echo "Total added: $total_added"
echo "Total deleted: $total_deleted"
```
## Group by author with counts [Section titled “Group by author with counts”](#group-by-author-with-counts)
```bash
bb pr list -w "$WORKSPACE" -r "$REPO" --json --jq '
.pullRequests
| group_by(.author.nickname // .author.display_name)
| map({
author: (.[0].author.nickname // .[0].author.display_name),
count: length,
ids: [.[].id]
})
| sort_by(-.count)
'
```
This sorts authors by descending PR count and includes the IDs for drilldown. ## Top reviewers across merged PRs [Section titled “Top reviewers across merged PRs”](#top-reviewers-across-merged-prs) Useful for identifying review load. Iterates over merged PRs and counts approvals per reviewer:
```bash
bb pr list -w "$WORKSPACE" -r "$REPO" -s MERGED --limit 200 --json --jq '
[
.pullRequests[].participants[]
| select(.approved == true)
| .user.nickname // .user.display_name
]
| group_by(.)
| map({ reviewer: .[0], approvals: length })
| sort_by(-.approvals)
'
```
## CSV export [Section titled “CSV export”](#csv-export) To export an open-PRs report into a spreadsheet, use jq’s `@csv`:
```bash
bb pr list -w "$WORKSPACE" -r "$REPO" --limit 500 --json --jq '
["id","title","author","state","created_on","source","destination"],
(
.pullRequests[]
| [
.id,
.title,
(.author.nickname // .author.display_name),
.state,
.created_on,
.source.branch.name,
.destination.branch.name
]
)
| @csv
' > prs.csv
head -3 prs.csv
```
Sample output:
```plaintext
"id","title","author","state","created_on","source","destination"
42,"Add login button","alice","OPEN","2025-01-04T09:11:00Z","feat/login","main"
43,"Fix typo in README","bob","OPEN","2025-01-04T11:22:00Z","fix/typo","main"
```
## PR cycle time (created → merged) [Section titled “PR cycle time (created → merged)”](#pr-cycle-time-created--merged)
```bash
bb pr list -w "$WORKSPACE" -r "$REPO" -s MERGED --limit 100 --json --jq '
[
.pullRequests[]
| {
id,
title,
hours: (
(.updated_on | fromdateiso8601)
- (.created_on | fromdateiso8601)
) / 3600
}
]
| sort_by(.hours)
'
```
`updated_on` on a merged PR approximates the merge time; for exact merge time, walk `bb pr activity ` and find the merge event. ## Related [Section titled “Related”](#related) * [Scripting & Automation guide](/guides/scripting/) — JSON output, exit codes, primitive jq patterns * [JSON Output reference](/reference/json-output/) — the envelope shape for list-style commands * [`bb pr list`](/commands/pr/) — flags like `-s`, `--limit`, `--json`, `--jq`
# Retry wrapper for transient failures
> A small shell wrapper that retries bb invocations with exponential backoff when the built-in retry isn't enough.
The CLI already retries HTTP 429, 502, 503, and 504 responses up to **3 times** with exponential backoff — see [Built-in Resilience](/guides/scripting/#built-in-resilience). For nearly every workflow that’s enough. This recipe is for the cases where it isn’t: * A long-running batch job that hits the rate-limit envelope and needs *more* than 3 retries. * Network flakes where DNS or TLS itself misbehaves and never reaches the CLI’s retry layer. * A dependent system (CI runner, proxy) that occasionally rejects requests. ## What you’ll see when retry kicks in [Section titled “What you’ll see when retry kicks in”](#what-youll-see-when-retry-kicks-in) The built-in retry is silent on success. On the third and final failure you’ll see an error like:
```plaintext
Error: API request failed: 429 Too Many Requests
```
If you also pass `--json`, the structured error shape on stderr looks like:
```json
{
"error": {
"code": "API_ERROR",
"message": "API request failed: 429 Too Many Requests"
}
}
```
That JSON shape is stable — see the [Error Codes reference](/reference/error-codes/). If you see this and the operation is idempotent, retrying is safe. Caution **Don’t blanket-retry mutating commands.** `bb pr create`, `bb pr merge`, `bb pr approve`, and similar can succeed *server-side* even when the response read fails. A retry might create a duplicate PR or re-approve. Limit the wrapper below to read-only commands or commands you’ve made idempotent (e.g., check existence before creating). ## Recipe: bb-with-retry wrapper [Section titled “Recipe: bb-with-retry wrapper”](#recipe-bb-with-retry-wrapper)
```bash
#!/bin/bash
# bb-retry.sh - Run a bb command with exponential backoff.
#
# Usage:
# ./bb-retry.sh pr list -w myworkspace -r myrepo --json
#
# Env vars:
# MAX_ATTEMPTS default 5
# INITIAL_DELAY default 2 (seconds)
# MAX_DELAY default 60 (seconds)
set -euo pipefail
MAX_ATTEMPTS="${MAX_ATTEMPTS:-5}"
INITIAL_DELAY="${INITIAL_DELAY:-2}"
MAX_DELAY="${MAX_DELAY:-60}"
attempt=1
delay="$INITIAL_DELAY"
while true; do
if bb "$@"; then
exit 0
fi
exit_code=$?
if [ "$attempt" -ge "$MAX_ATTEMPTS" ]; then
echo "bb $* failed after $attempt attempts (exit $exit_code)" >&2
exit "$exit_code"
fi
# Add jitter: ±25% of the current delay
jitter=$(( RANDOM % (delay / 2 + 1) - delay / 4 ))
sleep_time=$(( delay + jitter ))
[ "$sleep_time" -lt 1 ] && sleep_time=1
echo "bb $* failed (exit $exit_code); retry $((attempt + 1))/$MAX_ATTEMPTS in ${sleep_time}s" >&2
sleep "$sleep_time"
attempt=$(( attempt + 1 ))
delay=$(( delay * 2 ))
[ "$delay" -gt "$MAX_DELAY" ] && delay="$MAX_DELAY"
done
```
### Usage [Section titled “Usage”](#usage)
```bash
chmod +x bb-retry.sh
# Read-only: safe to retry freely.
./bb-retry.sh pr list -w myworkspace -r myrepo --json > prs.json
# Tune the cap for big jobs.
MAX_ATTEMPTS=10 INITIAL_DELAY=5 ./bb-retry.sh pr view 42 --json
```
## Recipe: retry only on a specific error code [Section titled “Recipe: retry only on a specific error code”](#recipe-retry-only-on-a-specific-error-code) If you only want to retry on rate-limit errors and *not* on, say, authentication failures, parse the structured error: bb-retry-on-rate-limit.sh
```bash
#!/bin/bash
set -euo pipefail
MAX_ATTEMPTS=5
attempt=1
delay=2
while true; do
err_file=$(mktemp)
if bb "$@" 2> "$err_file"; then
rm -f "$err_file"
exit 0
fi
err_msg=$(cat "$err_file")
rm -f "$err_file"
# Retry only on rate-limit / transient gateway errors.
if echo "$err_msg" | grep -qE '429|502|503|504'; then
if [ "$attempt" -ge "$MAX_ATTEMPTS" ]; then
echo "$err_msg" >&2
exit 1
fi
echo "Transient error, retrying in ${delay}s..." >&2
sleep "$delay"
delay=$(( delay * 2 ))
attempt=$(( attempt + 1 ))
continue
fi
# Non-transient: fail fast.
echo "$err_msg" >&2
exit 1
done
```
## When *not* to write your own retry [Section titled “When not to write your own retry”](#when-not-to-write-your-own-retry) The wrappers above are the right answer when the built-in retry has been exhausted. They are *not* the right answer for: * **Auth failures** (`Authentication required`) — retrying won’t help; fix the credentials. * **404 / not-found errors** — these don’t get more found over time. * **Validation errors** (`requireOption()` failures) — these are bugs in your script, not transient. The CLI exits with code `1` for all of these, same as for transient errors. Use the JSON error shape on stderr (`.error.code`) to distinguish them rather than retrying everything. ## Related [Section titled “Related”](#related) * [Scripting & Automation: Built-in Resilience](/guides/scripting/#built-in-resilience) * [Error Codes reference](/reference/error-codes/) — the stable `.error.code` values to branch on * [JSON Output reference](/reference/json-output/) — the success/error envelope shapes
# Configuration File
> Complete reference for the bb configuration file
The Bitbucket CLI stores configuration in a JSON file. This page documents the file format, location, and available settings. ## File Location [Section titled “File Location”](#file-location) * macOS / Linux
```plaintext
~/.config/bb/config.json
```
* Windows
```plaintext
%APPDATA%\bb\config.json
```
Typically: `C:\Users\\AppData\Roaming\bb\config.json` *** ## Configuration Schema [Section titled “Configuration Schema”](#configuration-schema) | Key | Type | Description | Set By | | --------------------------------- | ---------------------- | ------------------------------------------------------------------------ | -------------------------------- | | `authMethod` | `"basic"` \| `"oauth"` | Active authentication method | `bb auth login` | | `username` | string | Your Bitbucket username (API token auth) | `bb auth login -u` | | `apiToken` | string | Your API token (API token auth) | `bb auth login -p` | | `oauthAccessToken` | string | OAuth access token | `bb auth login` (OAuth) | | `oauthRefreshToken` | string | OAuth refresh token | `bb auth login` (OAuth) | | `oauthExpiresAt` | number | OAuth token expiry (Unix timestamp) | `bb auth login` (OAuth) | | `oauthClientId` | string | Custom OAuth consumer client ID | `bb auth login --client-id` | | `oauthClientSecret` | string | Custom OAuth consumer client secret | `bb auth login --client-secret` | | `defaultWorkspace` | string | Default workspace | `bb config set defaultWorkspace` | | `skipVersionCheck` | boolean | Disable update notifications | `bb config set` | | `versionCheckInterval` | number | Days between update checks (default: 1) | `bb config set` | | `prCreateIncludeDefaultReviewers` | boolean | Auto-add the repo’s default reviewers on `bb pr create` (default: false) | `bb config set` | | `lastVersionCheck` | string | Timestamp of last update check | Automatic | ### Example Configuration (OAuth) [Section titled “Example Configuration (OAuth)”](#example-configuration-oauth)
```json
{
"authMethod": "oauth",
"oauthAccessToken": "xxxxxxxxxxxxxxxx",
"oauthRefreshToken": "xxxxxxxxxxxxxxxx",
"oauthExpiresAt": 1711036800,
"defaultWorkspace": "myworkspace"
}
```
### Example Configuration (API Token) [Section titled “Example Configuration (API Token)”](#example-configuration-api-token)
```json
{
"authMethod": "basic",
"username": "myuser",
"apiToken": "ATBB_xxxxxxxxxxxxxxxxxxxx",
"defaultWorkspace": "myworkspace",
"skipVersionCheck": false,
"versionCheckInterval": 7
}
```
*** ## Managing Configuration [Section titled “Managing Configuration”](#managing-configuration) ### View All Settings [Section titled “View All Settings”](#view-all-settings)
```bash
bb config list
```
Output:
```plaintext
Config file: /Users/you/.config/bb/config.json
KEY VALUE
---------------- ------------------------
username myuser
apiToken ********
defaultWorkspace myworkspace
skipVersionCheck false
```
### Get a Specific Value [Section titled “Get a Specific Value”](#get-a-specific-value)
```bash
bb config get defaultWorkspace
# Output: myworkspace
```
### Set a Value [Section titled “Set a Value”](#set-a-value)
```bash
bb config set defaultWorkspace myworkspace
bb config set skipVersionCheck true
bb config set versionCheckInterval 7
```
#### Settable Keys [Section titled “Settable Keys”](#settable-keys) `bb config set` only accepts these four keys (the full list lives in `SETTABLE_CONFIG_KEYS` in `src/types/config.ts`). Everything else is either managed by the auth flow or written automatically by the CLI. | Key | Type | Example | | --------------------------------- | ------------------- | ---------------------------------------------------- | | `defaultWorkspace` | string | `bb config set defaultWorkspace myworkspace` | | `skipVersionCheck` | boolean | `bb config set skipVersionCheck true` | | `versionCheckInterval` | integer (days, ≥ 1) | `bb config set versionCheckInterval 7` | | `prCreateIncludeDefaultReviewers` | boolean | `bb config set prCreateIncludeDefaultReviewers true` | Typed key validation: * `skipVersionCheck` accepts only `true` or `false` * `versionCheckInterval` accepts only positive integers (`>= 1`) * `prCreateIncludeDefaultReviewers` accepts only `true` or `false` #### `prCreateIncludeDefaultReviewers` and the `--default-reviewers` flag [Section titled “prCreateIncludeDefaultReviewers and the --default-reviewers flag”](#prcreateincludedefaultreviewers-and-the---default-reviewers-flag) The config key sets the default behavior for `bb pr create`. The per-command flag — `--default-reviewers` or `--no-default-reviewers` — always wins when present, so you can opt in or out for a single PR without changing the config. | Config | Flag | Result | | --------------- | ------------------------ | ----------------------------------- | | unset / `false` | (none) | Default reviewers are **not** added | | `true` | (none) | Default reviewers are added | | unset / `false` | `--default-reviewers` | Default reviewers are added | | `true` | `--no-default-reviewers` | Default reviewers are **not** added | In short: the flag is an explicit override; the config is only consulted when neither `--default-reviewers` nor `--no-default-reviewers` is passed. Values are stored as native JSON types, so `bb config get --json` returns booleans/numbers for these keys. Example:
```bash
bb config get skipVersionCheck --json
# {"key":"skipVersionCheck","value":true}
```
### Protected Keys [Section titled “Protected Keys”](#protected-keys) Some configuration keys cannot be set directly: | Key | Reason | How to Set | | ------------------- | ---------------------- | ---------------------- | | `username` | Tied to authentication | Use `bb auth login -u` | | `apiToken` | Security-sensitive | Use `bb auth login -p` | | `authMethod` | Managed by login flow | Use `bb auth login` | | `oauthAccessToken` | Managed by OAuth flow | Use `bb auth login` | | `oauthRefreshToken` | Managed by OAuth flow | Use `bb auth login` | | `oauthExpiresAt` | Managed by OAuth flow | Use `bb auth login` | *** ## Update Notifications [Section titled “Update Notifications”](#update-notifications) The CLI automatically checks for updates when you run the bare `bb` command (without any subcommands). This helps you stay current with the latest features and bug fixes. ### How It Works [Section titled “How It Works”](#how-it-works) * Checks npm registry for the latest version * Compares with your installed version * Shows a notification if an update is available * Caches the check result for 24 hours (configurable) * Skips checks in CI environments automatically ### Example Notification [Section titled “Example Notification”](#example-notification)
```plaintext
⚠ A new version is available: 1.12.0 (you have 1.11.0)
Run 'bun install -g @pilatos/bitbucket-cli' to update
Or disable with 'bb config set skipVersionCheck true'
```
### Disable Notifications [Section titled “Disable Notifications”](#disable-notifications) To permanently disable update notifications:
```bash
bb config set skipVersionCheck true
```
### Change Check Frequency [Section titled “Change Check Frequency”](#change-check-frequency) To check less frequently (e.g., once per week):
```bash
bb config set versionCheckInterval 7
```
*** ## Configuration Precedence [Section titled “Configuration Precedence”](#configuration-precedence) When determining workspace and repository, the CLI checks sources in this order: 1. **Command-line flags** (highest priority)
```bash
bb pr list -w otherworkspace -r otherrepo
```
2. **Git repository remote** (if in a git repo)
```bash
cd /path/to/cloned-repo
bb pr list # Uses workspace/repo from git remote
```
3. **Configuration file** (lowest priority)
```bash
bb config set defaultWorkspace myworkspace
bb pr list # Uses config default
```
See [Understanding Repository Context](/guides/repository-context/) for detailed examples. *** ## File Permissions [Section titled “File Permissions”](#file-permissions) The configuration file contains sensitive data (API token). The CLI sets appropriate permissions automatically: | Platform | Permissions | | ----------- | --------------------------------- | | macOS/Linux | `0600` (owner read/write only) | | Windows | Inherits user profile permissions | Security Never share your config file or commit it to version control. The API token grants access to your Bitbucket account. *** ## Reset Configuration [Section titled “Reset Configuration”](#reset-configuration) ### Clear Authentication Only [Section titled “Clear Authentication Only”](#clear-authentication-only)
```bash
bb auth logout
```
This removes authentication credentials (OAuth tokens or API token) but keeps `defaultWorkspace` and other settings. For OAuth, it also revokes the token on Bitbucket’s side. It does not perform a full config reset. ### Full Reset [Section titled “Full Reset”](#full-reset) Delete the configuration file entirely: * macOS / Linux
```bash
rm ~/.config/bb/config.json
```
* Windows
```powershell
Remove-Item $env:APPDATA\bb\config.json
```
Then re-authenticate:
```bash
bb auth login
```
*** ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) ### ”Cannot read config file” [Section titled “”Cannot read config file””](#cannot-read-config-file) The file may be corrupted. Delete and recreate it:
```bash
rm ~/.config/bb/config.json
bb auth login
```
### “Cannot write config file” [Section titled ““Cannot write config file””](#cannot-write-config-file) Check directory permissions:
```bash
ls -la ~/.config/bb/
```
Create the directory if it doesn’t exist:
```bash
mkdir -p ~/.config/bb
```
### Config Not Being Used [Section titled “Config Not Being Used”](#config-not-being-used) Verify the CLI is reading from the expected location:
```bash
bb config list
# Check the "Configuration file:" line
```
Remember that command-line flags and git context take precedence over config file settings.
# Environment Variables
> Configure Bitbucket CLI using environment variables
Environment variables allow you to configure the CLI without storing credentials in files. This is especially useful for CI/CD pipelines and automation scripts. ## Available Variables [Section titled “Available Variables”](#available-variables) | Variable | Description | Example | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | | `BB_USERNAME` | Your Bitbucket username (fallback for `bb auth login`) | `myuser` | | `BB_API_TOKEN` | Your Bitbucket API token (fallback for `bb auth login`; forces API token auth when set) | `ATBB...` | | `BB_WORKSPACE` | Default workspace. Overrides `config.defaultWorkspace`; `--workspace` and git context still win. | `myworkspace` | | `BB_LOCALE` | BCP-47 locale tag for date/time formatting. `--locale` takes precedence; falls back to `LC_TIME`/`LC_ALL`/`LANG`, then `en-US`. | `de-DE` | | `BB_NO_UNICODE` | When set to any non-empty value, use ASCII fallbacks for separators, arrows, and status icons. Equivalent to the global `--no-unicode` flag. | `1` | | `NO_COLOR` | Disable color output globally when set to any value | `1` | | `FORCE_COLOR` | Force-enable color output globally (any value except `0`) | `1` | | `DEBUG` | Enable HTTP debug logging (request method, URL, status, response body for every API call). Must equal the literal string `true`. | `true` | ### Internal / System Variables [Section titled “Internal / System Variables”](#internal--system-variables) These variables are read by the CLI but are normally set by the runtime, your shell, or your operating system rather than by you. They are documented here so they aren’t surprising during troubleshooting. | Variable | Set By | Description | | ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `NODE_ENV` | Test runners | When set to `test`, the CLI suppresses `process.exitCode = 1` on errors so a single failing test cannot cascade into later tests. Don’t set this in production. | | `COMP_LINE` | tabtab / your shell | Set automatically while shell completion is being computed (`bb completion`). Its presence triggers the completion path; you should not set it manually. | | `APPDATA` | Windows | Used to locate the config file at `%APPDATA%\bb\config.json` on Windows. The CLI falls back to `%USERPROFILE%\AppData\Roaming\bb\config.json` if it isn’t set. | ## Configuration Priority [Section titled “Configuration Priority”](#configuration-priority) Repository context is resolved in this order (highest priority first): 1. **Command-line flags** (`--workspace`, `--repo`) 2. **Git repository context** (detected from remote URL) 3. **`BB_WORKSPACE` environment variable** 4. **Configuration file** (`defaultWorkspace`) Authentication credentials are resolved from: 1. **Configuration file** (`~/.config/bb/config.json` on macOS/Linux, `%APPDATA%\bb\config.json` on Windows) 2. **Environment variables** (`BB_USERNAME`, `BB_API_TOKEN`) when running `bb auth login` — setting `BB_API_TOKEN` automatically uses API token auth instead of OAuth For color output, precedence is: 1. `--color` (force color on — only available on `bb pr diff`, not a global flag) 2. `FORCE_COLOR` 3. `--no-color` (global flag, available on all commands) 4. `NO_COLOR` *** ## Authentication with Environment Variables [Section titled “Authentication with Environment Variables”](#authentication-with-environment-variables) ### Login from Environment Variables [Section titled “Login from Environment Variables”](#login-from-environment-variables) When environment variables are set, `bb auth login` uses them automatically:
```bash
export BB_USERNAME=myuser
export BB_API_TOKEN=ATBB_your_token_here
bb auth login # Uses env vars, no prompts
```
### Non-Interactive Usage [Section titled “Non-Interactive Usage”](#non-interactive-usage) For scripts and CI/CD, set both variables before running commands:
```bash
export BB_USERNAME=myuser
export BB_API_TOKEN=ATBB_your_token_here
bb auth login
bb pr list -w myworkspace -r myrepo
```
Security Warning Never commit environment variables containing tokens to version control. Use your CI/CD platform’s secrets management instead. *** ## Shell Configuration [Section titled “Shell Configuration”](#shell-configuration) ### Bash [Section titled “Bash”](#bash) Add to `~/.bashrc` or `~/.bash_profile`:
```bash
export BB_USERNAME="your-username"
export BB_API_TOKEN="your-api-token"
```
Then reload:
```bash
source ~/.bashrc
```
### Zsh [Section titled “Zsh”](#zsh) Add to `~/.zshrc`:
```zsh
export BB_USERNAME="your-username"
export BB_API_TOKEN="your-api-token"
```
Then reload:
```bash
source ~/.zshrc
```
### Fish [Section titled “Fish”](#fish) Add to `~/.config/fish/config.fish`:
```fish
set -gx BB_USERNAME "your-username"
set -gx BB_API_TOKEN "your-api-token"
```
Then reload:
```bash
source ~/.config/fish/config.fish
```
### PowerShell [Section titled “PowerShell”](#powershell) Add to your PowerShell profile (`$PROFILE`):
```powershell
$env:BB_USERNAME = "your-username"
$env:BB_API_TOKEN = "your-api-token"
```
*** ## Temporary Session [Section titled “Temporary Session”](#temporary-session) Set variables for a single terminal session:
```bash
# Linux/macOS
export BB_USERNAME=myuser
export BB_API_TOKEN=ATBB_token
# Windows Command Prompt
set BB_USERNAME=myuser
set BB_API_TOKEN=ATBB_token
# Windows PowerShell
$env:BB_USERNAME = "myuser"
$env:BB_API_TOKEN = "ATBB_token"
```
Or inline with a single command:
```bash
BB_USERNAME=myuser BB_API_TOKEN=ATBB_token bb auth login && bb pr list -w workspace -r repo
```
*** ## Docker Usage [Section titled “Docker Usage”](#docker-usage) Pass environment variables to containers:
```bash
docker run -e BB_USERNAME=myuser \
-e BB_API_TOKEN=ATBB_token \
your-image sh -lc "bb auth login && bb pr list -w workspace -r repo"
```
Or use an env file:
```bash
# .env.bb (not committed to git!)
BB_USERNAME=myuser
BB_API_TOKEN=ATBB_token
```
```bash
docker run --env-file .env.bb your-image sh -lc "bb auth login && bb pr list -w workspace -r repo"
```
*** ## CI/CD Examples [Section titled “CI/CD Examples”](#cicd-examples) ### GitHub Actions [Section titled “GitHub Actions”](#github-actions)
```yaml
name: PR Status
on: [push]
jobs:
check-prs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install Bitbucket CLI
run: npm install -g @pilatos/bitbucket-cli
- name: List PRs
env:
BB_USERNAME: ${{ secrets.BB_USERNAME }}
BB_API_TOKEN: ${{ secrets.BB_API_TOKEN }}
run: |
bb auth login
bb pr list -w myworkspace -r myrepo --json
```
### GitLab CI [Section titled “GitLab CI”](#gitlab-ci)
```yaml
check-prs:
image: oven/bun:latest
variables:
BB_USERNAME: $BB_USERNAME
BB_API_TOKEN: $BB_API_TOKEN
script:
- npm install -g @pilatos/bitbucket-cli
- bb auth login
- bb pr list -w myworkspace -r myrepo --json
```
### Bitbucket Pipelines [Section titled “Bitbucket Pipelines”](#bitbucket-pipelines)
```yaml
image: oven/bun:latest
pipelines:
default:
- step:
name: Check PRs
script:
- npm install -g @pilatos/bitbucket-cli
- bb auth login
- bb pr list -w $BITBUCKET_WORKSPACE -r $BITBUCKET_REPO_SLUG --json
```
*** ## Security Best Practices [Section titled “Security Best Practices”](#security-best-practices) 1. **Never commit tokens to git** * Add `.env*` to your `.gitignore` * Use CI/CD secrets management 2. **Use minimal token scopes** * Only grant permissions your script needs * Read-only tokens for read-only operations 3. **Rotate tokens regularly** * Especially after team member departures * Use short-lived tokens when possible 4. **Use secrets managers in production** * HashiCorp Vault * AWS Secrets Manager * Azure Key Vault 5. **Audit token usage** * Review which tokens are active * Revoke unused tokens
# Error Codes
> Complete reference of error codes and their meanings
When commands fail, the CLI returns structured errors with specific error codes. Understanding these codes helps you diagnose issues quickly. ## Error Code Ranges [Section titled “Error Code Ranges”](#error-code-ranges) | Range | Category | Description | | ----- | -------------------------- | -------------------------------------------------------------- | | 1xxx | Authentication | Login, credentials, and token issues | | 2xxx | API | Bitbucket API request failures | | 3xxx | Git | Local git operations | | 4xxx | Configuration | Config file read/write issues | | 5xxx | Validation | Invalid input or missing required fields | | 6xxx | Context | Repository/workspace detection issues | | 7xxx | Network | Transport/network failures before API response | | 8xxx | Output formatting | `--json fields` and `--jq` evaluation issues | | 9xxx | Shell completion / Unknown | Completion install/uninstall failures and uncategorized errors | *** ## Authentication Errors (1xxx) [Section titled “Authentication Errors (1xxx)”](#authentication-errors-1xxx) ### 1001 - AUTH\_REQUIRED [Section titled “1001 - AUTH\_REQUIRED”](#1001---auth_required) **Message:** Authentication required **Cause:** You haven’t logged in yet, or your credentials have been cleared. **Solution:**
```bash
bb auth login
```
### 1002 - AUTH\_INVALID [Section titled “1002 - AUTH\_INVALID”](#1002---auth_invalid) **Message:** Invalid credentials **Cause:** Your credentials were rejected by Bitbucket at request time. This is the code emitted for any 401 response that was *not* recovered by an OAuth refresh — e.g. a wrong API token, a revoked password, or basic-auth requests with bad credentials. **Solution:** 1. Verify your Bitbucket username 2. Generate a new API token at [Bitbucket API Tokens](https://bitbucket.org/account/settings/api-tokens/) 3. Re-authenticate:
```bash
bb auth logout
bb auth login
```
### 1003 - AUTH\_EXPIRED [Section titled “1003 - AUTH\_EXPIRED”](#1003---auth_expired) **Message:** OAuth token expired. Run `bb auth login` to re-authenticate. **Cause:** Specifically: an OAuth access token expired *and* the reactive refresh attempt also failed (refresh token revoked or expired). For non-OAuth flows, a stale token surfaces as `AUTH_INVALID` (1002) instead. **Solution:** 1. Re-run `bb auth login` to perform a fresh OAuth flow 2. If that also fails, create a new API token in Bitbucket settings and switch auth methods *** ## API Errors (2xxx) [Section titled “API Errors (2xxx)”](#api-errors-2xxx) ### 2001 - API\_REQUEST\_FAILED [Section titled “2001 - API\_REQUEST\_FAILED”](#2001---api_request_failed) **Message:** API request failed **Cause:** General network or API failure. **Solution:** * Check your internet connection * Verify Bitbucket status at [status.bitbucket.org](https://status.bitbucket.org) * Retry the command ### 2002 - API\_NOT\_FOUND [Section titled “2002 - API\_NOT\_FOUND”](#2002---api_not_found) **Message:** Resource not found **Cause:** The requested repository, PR, or resource doesn’t exist. **Solution:** * Check spelling of workspace and repository names * Verify the resource exists in Bitbucket * Ensure you have access to the repository ### 2003 - API\_FORBIDDEN [Section titled “2003 - API\_FORBIDDEN”](#2003---api_forbidden) **Message:** Access denied **Cause:** Your API token doesn’t have the required permissions. **Solution:** 1. Check your API token scopes at [Bitbucket API Tokens](https://bitbucket.org/account/settings/api-tokens/) 2. See [Token Scopes](/reference/token-scopes/) for the exact scope each `bb` command requires. 3. If a scope is missing, mint a new token (you can’t add scopes to an existing one) and re-authenticate with `bb auth login`. ### 2004 - API\_RATE\_LIMITED [Section titled “2004 - API\_RATE\_LIMITED”](#2004---api_rate_limited) **Message:** Rate limit exceeded **Cause:** You’ve made too many API requests in a short period. **Solution:** * Wait a few minutes before retrying * For scripts, implement exponential backoff * Consider caching results when possible ### 2005 - API\_SERVER\_ERROR [Section titled “2005 - API\_SERVER\_ERROR”](#2005---api_server_error) **Message:** Bitbucket server error **Cause:** Bitbucket’s servers are experiencing issues. **Solution:** * Check [status.bitbucket.org](https://status.bitbucket.org) * Retry after a few minutes *** ## Git Errors (3xxx) [Section titled “Git Errors (3xxx)”](#git-errors-3xxx) ### 3001 - GIT\_NOT\_REPOSITORY [Section titled “3001 - GIT\_NOT\_REPOSITORY”](#3001---git_not_repository) **Message:** Not a git repository **Cause:** The current directory is not a git repository, but the command requires one. **Solution:** * Navigate to a git repository directory, or * Use explicit flags: `-w -r ` ### 3002 - GIT\_COMMAND\_FAILED [Section titled “3002 - GIT\_COMMAND\_FAILED”](#3002---git_command_failed) **Message:** Git command failed **Cause:** A git operation (clone, fetch, checkout) failed. **Solution:** * Ensure git is installed and in your PATH * Check git error message for details * Verify you have proper SSH keys or credentials configured ### 3003 - GIT\_REMOTE\_NOT\_FOUND [Section titled “3003 - GIT\_REMOTE\_NOT\_FOUND”](#3003---git_remote_not_found) **Message:** No Bitbucket remote found **Cause:** The repository has no remote pointing to Bitbucket. **Solution:** * Add a Bitbucket remote:
```bash
git remote add origin git@bitbucket.org:workspace/repo.git
```
* Or use explicit flags: `-w -r ` *** ## Config Errors (4xxx) [Section titled “Config Errors (4xxx)”](#config-errors-4xxx) ### 4001 - CONFIG\_READ\_FAILED [Section titled “4001 - CONFIG\_READ\_FAILED”](#4001---config_read_failed) **Message:** Cannot read config file **Cause:** The configuration file is corrupted or unreadable. **Solution:** 1. Check file permissions 2. If corrupted, delete and recreate:
```bash
# macOS/Linux
rm ~/.config/bb/config.json
bb auth login
# Windows
del %APPDATA%\bb\config.json
bb auth login
```
### 4002 - CONFIG\_WRITE\_FAILED [Section titled “4002 - CONFIG\_WRITE\_FAILED”](#4002---config_write_failed) **Message:** Cannot write config file **Cause:** No write permission to the config directory. **Solution:** * Check directory permissions * Ensure the parent directory exists * On shared systems, verify you own the config directory ### 4003 - CONFIG\_INVALID\_KEY [Section titled “4003 - CONFIG\_INVALID\_KEY”](#4003---config_invalid_key) **Message:** Invalid configuration key **Cause:** Attempted to get/set an unknown configuration key. **Solution:** Valid configuration keys are: * `defaultWorkspace` - Default workspace * `skipVersionCheck` - Disable update notifications * `versionCheckInterval` - Days between update checks
```bash
bb config set defaultWorkspace myworkspace
bb config list
```
*** ## Validation Errors (5xxx) [Section titled “Validation Errors (5xxx)”](#validation-errors-5xxx) ### 5001 - VALIDATION\_REQUIRED [Section titled “5001 - VALIDATION\_REQUIRED”](#5001---validation_required) **Message:** Required field missing **Cause:** A required option or argument was not provided. **Solution:** Check command help for required options:
```bash
bb --help
```
Common required fields: * `bb pr create` requires `--title` * `bb repo create` requires a name argument ### 5002 - VALIDATION\_INVALID [Section titled “5002 - VALIDATION\_INVALID”](#5002---validation_invalid) **Message:** Invalid value **Cause:** A provided value doesn’t match expected format. **Solution:** * Check the expected format in command help * Common issues: * PR ID must be a number * State must be one of: OPEN, MERGED, DECLINED, SUPERSEDED ### 5003 - FILE\_NOT\_FOUND [Section titled “5003 - FILE\_NOT\_FOUND”](#5003---file_not_found) **Message:** File not found: `` **Cause:** A file referenced by an option (e.g. `--file` for `bb snippet create`/`edit`, `--body-file` for `bb pr edit`) doesn’t exist on disk, or a named file isn’t present inside a snippet. **Solution:** * Verify the path is correct relative to the current working directory * For `bb snippet view --file `, list snippet files first to confirm the name The `context` field on this error includes the missing path under `file` (or `bodyFile`), which scripts can key on to differentiate it from a generic `VALIDATION_INVALID`. *** ## Context Errors (6xxx) [Section titled “Context Errors (6xxx)”](#context-errors-6xxx) ### 6001 - CONTEXT\_REPO\_NOT\_FOUND [Section titled “6001 - CONTEXT\_REPO\_NOT\_FOUND”](#6001---context_repo_not_found) **Message:** Could not determine repository **Cause:** The CLI couldn’t figure out which repository to use. **Solution:** 1. Use explicit flags:
```bash
bb pr list -w myworkspace -r myrepo
```
2. Set a default:
```bash
bb config set defaultWorkspace myworkspace
```
3. Run from within a cloned Bitbucket repository See [Understanding Repository Context](/guides/repository-context/) for details. ### 6002 - CONTEXT\_WORKSPACE\_NOT\_FOUND [Section titled “6002 - CONTEXT\_WORKSPACE\_NOT\_FOUND”](#6002---context_workspace_not_found) **Message:** Could not determine workspace **Cause:** The CLI couldn’t figure out which workspace to use. **Solution:** 1. Use the `-w` flag:
```bash
bb repo list -w myworkspace
```
2. Set a default workspace:
```bash
bb config set defaultWorkspace myworkspace
```
*** ## Network Errors (7xxx) [Section titled “Network Errors (7xxx)”](#network-errors-7xxx) ### 7001 - NETWORK\_ERROR [Section titled “7001 - NETWORK\_ERROR”](#7001---network_error) **Message:** Network error: Unable to reach Bitbucket API **Cause:** The request failed before an HTTP response was received (offline, DNS issue, proxy/TLS issue, etc.). **Solution:** * Check internet and DNS connectivity * Verify proxy/TLS settings if applicable * Retry the command after connectivity is restored *** ## Output Formatting Errors (8xxx) [Section titled “Output Formatting Errors (8xxx)”](#output-formatting-errors-8xxx) ### 8001 - JQ\_FAILED [Section titled “8001 - JQ\_FAILED”](#8001---jq_failed) **Message:** jq evaluation failed: `` **Cause:** The expression passed to `--jq` is invalid or produced a runtime error. **Solution:** * Test the expression interactively against the full output first:
```bash
bb pr list --json | jq ''
```
* The embedded jq is jq 1.8.x; module imports (`include`, `import`) are not supported. * Remember `--jq` runs *after* field projection — when combined with `--json fields`, the input is already a flat array (the wrapper has been dropped). ### 8002 - JSON\_FORMAT\_INVALID [Section titled “8002 - JSON\_FORMAT\_INVALID”](#8002---json_format_invalid) **Message:** `--jq requires --json` or similar formatting validation failure. **Cause:** Incompatible combination of output flags. **Solution:** * `--jq` requires `--json`. Add `--json` (with or without a field list). *** ## Shell Completion Errors (9xxx) [Section titled “Shell Completion Errors (9xxx)”](#shell-completion-errors-9xxx) ### 9001 - COMPLETION\_INSTALL\_FAILED [Section titled “9001 - COMPLETION\_INSTALL\_FAILED”](#9001---completion_install_failed) **Message:** Failed to install completions: `` **Cause:** `bb completion install` couldn’t write the shell completion hooks — typically because the target shell profile isn’t writable, or the underlying `tabtab` install failed. **Solution:** * Check write permissions on your shell rc file (e.g. `~/.zshrc`, `~/.bashrc`) * Re-run with `DEBUG=true bb completion install` for the underlying error * If the issue persists, install completions manually by following your shell’s documentation for `tabtab` ### 9002 - COMPLETION\_UNINSTALL\_FAILED [Section titled “9002 - COMPLETION\_UNINSTALL\_FAILED”](#9002---completion_uninstall_failed) **Message:** Failed to uninstall completions: `` **Cause:** `bb completion uninstall` couldn’t remove the completion hooks — usually because the rc file isn’t writable or the entry was already removed manually. **Solution:** * Check write permissions on your shell rc file * Manually remove the `tabtab` block from your shell rc file if needed *** ## Unknown Errors (9xxx) [Section titled “Unknown Errors (9xxx)”](#unknown-errors-9xxx) ### 9999 - UNKNOWN [Section titled “9999 - UNKNOWN”](#9999---unknown) **Message:** An unexpected error occurred **Cause:** The CLI encountered an error that doesn’t fit any known category. **Solution:** * Check the error message for details * Retry the command * If the issue persists, [report it](https://github.com/0pilatos0/bitbucket-cli/issues) with full debug output:
```bash
DEBUG=true bb 2>&1
```
*** ## Exit Codes and Error Codes [Section titled “Exit Codes and Error Codes”](#exit-codes-and-error-codes) The process exit code is intentionally minimal — `0` for success and `1` for any failure. The numeric error code on this page lives in the JSON error payload’s `code` field, not in the exit status. To branch on a specific failure mode in a script, parse stderr JSON and read `.code`. See [Exit Codes in the scripting guide](/guides/scripting/#exit-codes) for a full example. ## Handling Errors in Scripts [Section titled “Handling Errors in Scripts”](#handling-errors-in-scripts) When using the CLI in scripts, check the exit code and handle errors appropriately:
```bash
#!/bin/bash
set -e
if ! bb pr list -w myworkspace -r myrepo --json > prs.json 2>&1; then
echo "Failed to list PRs"
exit 1
fi
# Process prs.json...
```
For JSON output, errors are emitted to stderr and include the error code:
```bash
bb pr view 999 --json 2>&1
# {"name":"BBError","code":2002,"message":"Pull request not found"}
```
Typical JSON error payload fields: * `name` - Error class name * `code` - Numeric CLI error code * `message` - Human-readable message * `context` - Optional structured metadata
# Global Flags
> Flags accepted by every bb command
These flags can be passed to any `bb` command. They are resolved before the command-specific options, so they work uniformly whether you’re running `bb pr list` or `bb config get`. ## Quick reference [Section titled “Quick reference”](#quick-reference) | Flag | Type | Default | Description | | ------------------------ | ------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | `--json [fields]` | optional CSV | *off* | Emit machine-readable JSON. Pass a comma-separated field list to project the output. | | `--jq ` | string | *off* | Run the JSON output through an in-process `jq` filter. Requires `--json`. | | `--no-color` | boolean | auto | Disable ANSI colors. Also honoured: `NO_COLOR` env var. | | `--no-unicode` | boolean | auto | Use ASCII fallbacks for separators, arrows, and status icons. Also honoured: `BB_NO_UNICODE` env var. | | `--no-truncate` | boolean | *off* | Show full values in table output without truncating long cells. | | `--limit ` | integer | command-specific | Cap the number of items returned by list commands. | | `--all` | boolean | *off* | Fetch every page (overrides `--limit`). Available on list commands. | | `--locale ` | BCP-47 | system | Locale for date/time formatting (e.g. `de-DE`, `ja-JP`). Falls back to `BB_LOCALE`, then `LC_TIME`/`LC_ALL`/`LANG`, then `en-US`. | | `-w, --workspace ` | string | git remote / env / config | Override the workspace. | | `-r, --repo ` | string | git remote | Override the repository. | | `-h, --help` | boolean | — | Print help for the command. | | `-V, --version` | boolean | — | Print the CLI version. | ## Output flags [Section titled “Output flags”](#output-flags) ### `--json [fields]` [Section titled “--json \[fields\]”](#--json-fields) Switch a command to JSON output. With no argument, the full response is printed. Pass a comma-separated field list to project to just those keys:
```bash
bb pr list --json
bb pr list --json id,title,state
```
JSON mode also disables spinners, colors, and progress notes so the output is safe to pipe. ### `--jq ` [Section titled “--jq \”](#--jq-expression) Filter the JSON output through a `jq` expression. The filter runs in-process via the embedded jq engine, so you don’t need the `jq` binary installed. Requires `--json`:
```bash
bb pr list --json --jq '.pullRequests[] | select(.state == "OPEN") | .title'
```
### `--no-color` and `--no-unicode` [Section titled “--no-color and --no-unicode”](#--no-color-and---no-unicode) `--no-color` disables ANSI colors. `--no-unicode` swaps Unicode separators and status glyphs for plain ASCII equivalents — useful for log aggregators that mangle Unicode, or terminals that don’t render the symbols cleanly. Both flags have environment-variable equivalents (`NO_COLOR`, `BB_NO_UNICODE`). They’re auto-disabled when stdout is not a TTY, so piping to a file or another process already gives you plain output. ## Pagination flags [Section titled “Pagination flags”](#pagination-flags) ### `--limit ` [Section titled “--limit \”](#--limit-n) Cap the number of items returned. Most list commands default to a small, useful page size (e.g. 25); pass `--limit 100` to fetch more in one shot. ### `--all` [Section titled “--all”](#--all) Fetch every page. Available on: * `bb repo list` * `bb pr list` * `bb pr activity` * `bb pr comments list` * `bb snippet list` * `bb snippet comments list` `--all` overrides `--limit`. When the output is truncated by `--limit`, the CLI prints a hint suggesting `--limit ` or `--all` so the truncation is never silent. ### `--no-truncate` [Section titled “--no-truncate”](#--no-truncate) Show table cells in full. By default, long values (PR descriptions, comment bodies, branch names) are truncated to keep rows on one line. `--no-truncate` disables that for the current invocation:
```bash
bb pr comments list 42 --no-truncate
```
## Context flags [Section titled “Context flags”](#context-flags) ### `-w, --workspace` and `-r, --repo` [Section titled “-w, --workspace and -r, --repo”](#-w---workspace-and--r---repo) Override the workspace and repository for the current command. The resolution order is documented in detail in [Repository Context](/guides/repository-context/), but in short: 1. `--workspace` / `--repo` flags 2. Git remote of the current directory 3. `BB_WORKSPACE` environment variable (workspace only) 4. `defaultWorkspace` in the config file (workspace only) ## Locale flag [Section titled “Locale flag”](#locale-flag) ### `--locale ` [Section titled “--locale \”](#--locale-tag) Pin a BCP-47 locale tag for date/time formatting. This affects every human-readable date the CLI prints — PR timestamps, activity entries, comment dates. JSON output is locale-independent.
```bash
bb pr list --locale de-DE
bb pr view 42 --locale ja-JP
```
If `--locale` is unset, the CLI walks `BB_LOCALE`, then the standard POSIX chain (`LC_TIME` → `LC_ALL` → `LANG`), then falls back to `en-US`. ## Precedence summary [Section titled “Precedence summary”](#precedence-summary) For settings that can come from multiple sources, the order is always: 1. Command-line flag 2. Environment variable 3. Config file 4. Built-in default ## See also [Section titled “See also”](#see-also) * [Environment Variables](/reference/environment-variables/) — env-var equivalents and precedence * [JSON Output](/reference/json-output/) — schema, field projection, scripting tips * [Configuration File](/reference/configuration/) — persistent settings
# JSON Output
> Reference for JSON output behavior across all commands
All commands support the global `--json` flag, with optional field selection and a built-in `--jq` filter modeled on the [`gh` CLI](https://cli.github.com/manual/gh_help_formatting). Use JSON mode for automation, scripts, and CI/CD pipelines. ## Quick Usage [Section titled “Quick Usage”](#quick-usage)
```bash
# Full JSON output
bb pr list --json
# Project to a comma-separated field list
bb pr list --json id,title,state
# Filter through jq (no external jq binary required)
bb pr list --json id,title,state --jq '.[] | select(.state == "OPEN") | .title'
# Disable color formatting and return JSON
bb repo view --json --no-color
```
## Field Selection (`--json fields`) [Section titled “Field Selection (--json fields)”](#field-selection---json-fields) Pass a comma-separated field list to project the output to just those fields, matching the way `gh` CLI handles `--json`:
```bash
bb pr list --json id,title,state
bb pr list --json id,title,author.display_name
```
**Rules:** * Bare `--json` (no field list) keeps the full output — backwards compatible. * Top-level field names become the keys of each result object verbatim, including dotted paths (`author.display_name` becomes the literal key `"author.display_name"`). * Dotted paths traverse nested objects; missing intermediates yield `null`. * For collection commands (`pr list`, `repo list`, etc.), the wrapper envelope is dropped and the field list is projected per-item — the result is a flat array. This matches `gh` CLI semantics. #### Example: `bb pr list --json id,title,author.display_name` [Section titled “Example: bb pr list --json id,title,author.display\_name”](#example-bb-pr-list---json-idtitleauthordisplay_name)
```json
[
{ "id": 42, "title": "Add feature", "author.display_name": "Alice" },
{ "id": 41, "title": "Fix bug", "author.display_name": "Bob" }
]
```
#### Before / after: shape change after projection [Section titled “Before / after: shape change after projection”](#before--after-shape-change-after-projection) `bb pr list --json` returns the full envelope with metadata and a named array:
```json
{
"workspace": "myworkspace",
"repoSlug": "myrepo",
"state": "OPEN",
"count": 2,
"pullRequests": [
{
"id": 42,
"title": "Add feature",
"state": "OPEN",
"author": { "display_name": "Alice", "nickname": "alice" },
"links": { "html": { "href": "..." } }
},
{ "id": 41, "title": "Fix bug", "state": "OPEN", "author": {...}, "links": {...} }
]
}
```
The same command with `--json id,title,state` drops the envelope and projects each item to a flat array of just those fields:
```json
[
{ "id": 42, "title": "Add feature", "state": "OPEN" },
{ "id": 41, "title": "Fix bug", "state": "OPEN" }
]
```
This is why `--jq` filters use `.[]` after projection (`.[] | select(...)`) but `.pullRequests[]` against the full envelope. ## Built-in jq (`--jq`) [Section titled “Built-in jq (--jq)”](#built-in-jq---jq) The `--jq ` flag pipes the JSON output through an embedded jq engine ([jq-wasm](https://www.npmjs.com/package/jq-wasm)) — no external `jq` binary required, no `bash` pipe to fail on Windows.
```bash
# Strings, one per line
bb pr list --json --jq '.pullRequests[].title'
# Combine with field selection (jq runs after projection)
bb pr list --json id,title,state --jq '.[] | select(.state == "OPEN") | .title'
# Aggregate
bb pr list --json --jq '.count'
# Project + format with jq string interpolation
bb pr list --json id,title,author.display_name \
--jq '.[] | "\(.id)\t\(.["author.display_name"])\t\(.title)"'
# Project a nested URL out of a single resource
bb pr view 42 --json links.html.href --jq '.["links.html.href"]'
# Top open PRs by author with built-in jq (no projection — full shape)
bb pr list --json --jq '.pullRequests | group_by(.author.display_name)
| map({ author: .[0].author.display_name, count: length })
| sort_by(-.count)'
```
**Rules:** * `--jq` requires `--json`. Using `--jq` alone exits non-zero with a clear error (`✗ --jq requires --json`). * jq runs *after* field projection, so `.` refers to the projected shape — a flat array when both `--json fields` and a wrapper-style command are involved. * Invalid jq expressions exit non-zero with the underlying jq compiler error (error code [8001](/reference/error-codes/#8001---jq_failed)). Caution The embedded jq is jq 1.8.x. Module imports (`include`, `import`) and filesystem-dependent features are not supported. ## Output Patterns [Section titled “Output Patterns”](#output-patterns) The CLI uses a small number of consistent output patterns. Understanding these patterns lets you predict the JSON shape of any command. ### Pattern 1: Collection (List Commands) [Section titled “Pattern 1: Collection (List Commands)”](#pattern-1-collection-list-commands) Used by: `pr list`, `repo list`, `pr comments list`, `pr activity`, `pr reviewers list`, `pr checks` Returns an envelope with metadata and a named array:
```json
{
"workspace": "myworkspace",
"repoSlug": "myrepo",
"state": "OPEN",
"filters": {},
"count": 2,
"pullRequests": [...]
}
```
**Common envelope fields:** | Field | Type | Present in | | ----------- | ------ | ------------------------------------------------ | | `workspace` | string | PR and repo collections | | `repoSlug` | string | PR collections | | `count` | number | All collections | | `state` | string | `pr list` | | `filters` | object | `pr list` (when `--mine` is used), `pr activity` | **Collection key names:** | Command | Array key | | ------------------- | ------------------------------------------------------ | | `pr list` | `pullRequests` | | `repo list` | `repositories` | | `pr comments list` | `comments` | | `pr activity` | `activities` | | `pr reviewers list` | `reviewers` | | `pr checks` | `statuses` (inside a `summary` + `statuses` structure) | #### Example: `bb pr list --json` [Section titled “Example: bb pr list --json”](#example-bb-pr-list---json)
```json
{
"workspace": "myworkspace",
"repoSlug": "myrepo",
"state": "OPEN",
"count": 2,
"pullRequests": [
{
"id": 42,
"title": "Add feature",
"state": "OPEN",
"draft": false,
"author": { "display_name": "Alice", "nickname": "alice" },
"source": { "branch": { "name": "feature/add-feature" } },
"destination": { "branch": { "name": "main" } },
"created_on": "2026-01-15T10:00:00.000000+00:00",
"updated_on": "2026-01-16T14:30:00.000000+00:00",
"links": { "html": { "href": "https://bitbucket.org/myworkspace/myrepo/pull-requests/42" } }
}
]
}
```
#### Example: `bb pr list --mine --json` [Section titled “Example: bb pr list --mine --json”](#example-bb-pr-list---mine---json)
```json
{
"workspace": "myworkspace",
"repoSlug": "myrepo",
"state": "OPEN",
"filters": { "mine": true },
"count": 1,
"pullRequests": [...]
}
```
#### Example: `bb pr checks 42 --json` [Section titled “Example: bb pr checks 42 --json”](#example-bb-pr-checks-42---json)
```json
{
"pullRequestId": 42,
"workspace": "myworkspace",
"repoSlug": "myrepo",
"summary": { "successful": 2, "failed": 0, "pending": 1 },
"statuses": [...]
}
```
*** ### Pattern 2: Resource (View/Create Commands) [Section titled “Pattern 2: Resource (View/Create Commands)”](#pattern-2-resource-viewcreate-commands) Used by: `pr view`, `repo view`, `pr create`, `pr edit` Returns the raw Bitbucket API resource object directly, with no envelope:
```json
{
"type": "pullrequest",
"id": 42,
"title": "Add feature",
"state": "OPEN",
"author": {...},
"source": {...},
"destination": {...},
"participants": [...],
"links": {...}
}
```
*** ### Pattern 3: Action (Approve/Merge/Decline Commands) [Section titled “Pattern 3: Action (Approve/Merge/Decline Commands)”](#pattern-3-action-approvemergedecline-commands) Used by: `pr approve`, `pr decline`, `pr merge`, `pr ready`, `pr comments add/edit/delete`, `pr reviewers add/remove`, `auth login`, `auth logout` Returns a success indicator plus resource identifiers:
```json
{
"success": true,
"pullRequestId": 42
}
```
Some action commands include the full resource in the response:
```json
{
"success": true,
"pullRequestId": 42,
"pullRequest": {...}
}
```
*** ### Pattern 4: Mode-Based (Diff Command) [Section titled “Pattern 4: Mode-Based (Diff Command)”](#pattern-4-mode-based-diff-command) Used by: `pr diff` (with `--stat`, `--web`, `--name-only`, or default diff mode) Returns context metadata plus mode-specific data. Every mode includes the same context envelope (`workspace`, `repoSlug`, `pullRequestId`, `mode`); the remaining fields depend on the mode. | Mode | Trigger | Mode-specific fields | | ----------- | ------------- | ------------------------------------------------------------- | | `diff` | (default) | `diff` (string — the raw unified diff text) | | `stat` | `--stat` | `filesChanged`, `totalAdditions`, `totalDeletions`, `files[]` | | `name-only` | `--name-only` | `files[]` (string array of paths) | | `web` | `--web` | `url` | #### `bb pr diff 42 --json` (default mode) [Section titled “bb pr diff 42 --json (default mode)”](#bb-pr-diff-42---json-default-mode) The default mode returns the raw unified diff as a single string under `diff`. Newlines are preserved, so the value is suitable for piping to `git apply` or writing to a `.patch` file.
```json
{
"workspace": "myworkspace",
"repoSlug": "myrepo",
"pullRequestId": 42,
"mode": "diff",
"diff": "diff --git a/src/index.ts b/src/index.ts\nindex abc123..def456 100644\n--- a/src/index.ts\n+++ b/src/index.ts\n@@ -1,3 +1,4 @@\n import { foo } from './foo';\n+import { bar } from './bar';\n \n export const main = () => {\n"
}
```
Extract just the diff text in scripts:
```bash
bb pr diff 42 --json --jq '.diff' > pr-42.patch
```
#### `bb pr diff 42 --stat --json` [Section titled “bb pr diff 42 --stat --json”](#bb-pr-diff-42---stat---json)
```json
{
"workspace": "myworkspace",
"repoSlug": "myrepo",
"pullRequestId": 42,
"mode": "stat",
"filesChanged": 3,
"totalAdditions": 27,
"totalDeletions": 11,
"files": [
{ "path": "src/index.ts", "additions": 10, "deletions": 3 }
]
}
```
#### `bb pr diff 42 --name-only --json` [Section titled “bb pr diff 42 --name-only --json”](#bb-pr-diff-42---name-only---json)
```json
{
"workspace": "myworkspace",
"repoSlug": "myrepo",
"pullRequestId": 42,
"mode": "name-only",
"files": ["src/index.ts", "src/utils.ts"]
}
```
#### `bb pr diff 42 --web --json` [Section titled “bb pr diff 42 --web --json”](#bb-pr-diff-42---web---json)
```json
{
"workspace": "myworkspace",
"repoSlug": "myrepo",
"pullRequestId": 42,
"mode": "web",
"url": "https://bitbucket.org/myworkspace/myrepo/pull-requests/42/diff"
}
```
*** ### Pattern 5: Auth & Config (Custom) [Section titled “Pattern 5: Auth & Config (Custom)”](#pattern-5-auth--config-custom) These commands have unique output shapes: #### `bb auth status --json` [Section titled “bb auth status --json”](#bb-auth-status---json)
```json
{
"authenticated": true,
"user": {
"username": "myuser",
"displayName": "My Name",
"accountId": "70121:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
```
#### `bb auth token --json` [Section titled “bb auth token --json”](#bb-auth-token---json)
```json
{
"token": "base64-encoded-username:apiToken"
}
```
#### `bb config list --json` [Section titled “bb config list --json”](#bb-config-list---json)
```json
{
"configPath": "/Users/you/.config/bb/config.json",
"config": {
"username": "myuser",
"apiToken": "********",
"defaultWorkspace": "myworkspace",
"skipVersionCheck": false
}
}
```
#### `bb config get --json` [Section titled “bb config get \ --json”](#bb-config-get-key---json)
```json
{
"key": "defaultWorkspace",
"value": "myworkspace"
}
```
*** ## jq Examples [Section titled “jq Examples”](#jq-examples) The same expressions work with the built-in `--jq` flag or with an external `jq` binary. The built-in form avoids the dependency and works identically on Windows, macOS, and Linux.
```bash
# Print PR titles (built-in)
bb pr list --json --jq '.pullRequests[].title'
# Print PR titles (external jq, equivalent)
bb pr list --json | jq -r '.pullRequests[].title'
# Count PRs
bb pr list --json --jq '.count'
# Repository names
bb repo list --json --jq '.repositories[].full_name'
# Diff file paths
bb pr diff 42 --stat --json --jq '.files[].path'
# PR URLs
bb pr list --json --jq '.pullRequests[].links.html.href'
# Auth status
bb auth status --json --jq '.authenticated'
```
## Scripting Notes [Section titled “Scripting Notes”](#scripting-notes) * Prefer `--json` in scripts rather than parsing text output. * Do not rely on text formatting symbols (`✓`, table separators, colors). * Prefer the built-in `--jq` and `--json fields` over external pipes — they avoid an extra binary dependency and behave identically across platforms. * If you need stable fields, prefer command-specific documented keys (`pullRequests`, `repositories`, `files`, `success`). * `pr list` returns lightweight PR objects. Use `pr view ` for full details including `participants` and `reviewers`. ## Errors [Section titled “Errors”](#errors) When a command fails, the CLI exits non-zero. * In normal mode, errors are plain text on stderr. * In `--json` mode, errors are compact JSON objects on stderr. Example:
```bash
bb config get invalidKey --json 2>error.json
cat error.json
# {"name":"BBError","code":4003,"message":"Unknown config key 'invalidKey'. Valid keys: username, defaultWorkspace, skipVersionCheck, versionCheckInterval","context":{"key":"invalidKey"}}
```
Error JSON fields: | Field | Type | Description | | --------- | ------ | -------------------------------------------------------------------------------------------------------- | | `name` | string | Error class name (usually `BBError`; can also be `APIError`, `AuthError`, `GitError`, `ValidationError`) | | `code` | number | Numeric [error code](/reference/error-codes/) | | `message` | string | Human-readable message | | `context` | object | Optional structured metadata. Shape depends on `code` — see the table below | The Bitbucket API response body is **not** nested inside the error JSON. `APIError` keeps the upstream HTTP status and response body as instance properties for the in-process error path, but only `name`, `code`, `message`, and `context` are serialized to stderr. Likewise, `cause` (the underlying `Error`) and stack traces are never exposed in `--json` mode. #### `context` fields by error code [Section titled “context fields by error code”](#context-fields-by-error-code) The `context` object is omitted when there’s nothing useful to attach. When present, the shape is: | Code | Typical `context` keys | | ------------------------------------- | ----------------------------------------------------------------------------------------------------- | | `1001` AUTH\_REQUIRED | *(none)* | | `1002` AUTH\_INVALID | `status` (HTTP status, OAuth verification failures only) | | `1003` AUTH\_EXPIRED | `status` (HTTP status from the token endpoint) | | `2001`–`2005` API\_\* | *(none — the upstream HTTP status code is in `APIError.statusCode` in-process but is not serialized)* | | `3001` GIT\_NOT\_REPOSITORY | *(none)* | | `3002` GIT\_COMMAND\_FAILED | `command`, `exitCode` | | `3003` GIT\_REMOTE\_NOT\_FOUND | `remote` | | `4001` CONFIG\_READ\_FAILED | *(none)* | | `4002` CONFIG\_WRITE\_FAILED | *(none)* | | `4003` CONFIG\_INVALID\_KEY | `key` | | `5001` VALIDATION\_REQUIRED | `field` (when thrown by `ValidationError`) | | `5002` VALIDATION\_INVALID | varies — usually `{ key, value }`, the offending option name, or the rejected ID | | `6001` CONTEXT\_REPO\_NOT\_FOUND | *(none)* | | `6002` CONTEXT\_WORKSPACE\_NOT\_FOUND | *(none)* | | `7001` NETWORK\_ERROR | *(usually none; OAuth revoke failures include `status`, `body`)* | | `8001` JQ\_FAILED | `expression`, optional `exitCode` | | `8002` JSON\_FORMAT\_INVALID | *(none)* | | `9999` UNKNOWN | *(none)* | In automation, always check the process exit code before parsing stdout JSON.
# Token Scopes
> Required Bitbucket API token scopes for each bb command
When you authenticate with an [API token](/getting-started/authentication/#api-token-for-cicd-and-headless-environments), you choose which scopes the token grants. This page maps every `bb` command to the minimum scope required to run it, so you can mint a token with exactly the permissions a workflow needs and nothing more. ## Scope Reference [Section titled “Scope Reference”](#scope-reference) Bitbucket Cloud API token scopes follow the format `::bitbucket`. The CLI uses these scopes: | Scope | Grants | | ----------------------------- | --------------------------------------------------------------------------------------------------------- | | `read:user:bitbucket` | Read your own user profile (required by `bb auth status`, used to verify any login) | | `read:repository:bitbucket` | List and view repositories, list default reviewers | | `write:repository:bitbucket` | Create repositories, manage default reviewers | | `admin:repository:bitbucket` | Delete repositories | | `read:pullrequest:bitbucket` | List, view, and diff pull requests; read comments, activity, checks, and reviewers | | `write:pullrequest:bitbucket` | Create, edit, approve, decline, merge, and mark PRs ready; add/edit/delete comments; add/remove reviewers | | `read:snippet:bitbucket` | List and view snippets | | `write:snippet:bitbucket` | Create, edit, and delete snippets | ## Command → Scope Map [Section titled “Command → Scope Map”](#command--scope-map) ### Auth (`bb auth …`) [Section titled “Auth (bb auth …)”](#auth-bb-auth-) | Command | Required scopes | | ---------------- | -------------------------------------------------------------------------- | | `bb auth login` | `read:user:bitbucket` (verifies the credentials) | | `bb auth logout` | *(none — local-only for API tokens; OAuth revoke uses the existing token)* | | `bb auth status` | `read:user:bitbucket` | | `bb auth token` | *(none — prints the locally-stored token)* | ### Repositories (`bb repo …`) [Section titled “Repositories (bb repo …)”](#repositories-bb-repo-) | Command | Required scopes | | ---------------------------------- | ------------------------------------------------------- | | `bb repo list` | `read:repository:bitbucket` | | `bb repo view` | `read:repository:bitbucket` | | `bb repo clone` | `read:repository:bitbucket` (plus your normal git auth) | | `bb repo create` | `write:repository:bitbucket` | | `bb repo delete` | `admin:repository:bitbucket` | | `bb repo default-reviewers list` | `read:repository:bitbucket` | | `bb repo default-reviewers add` | `write:repository:bitbucket` | | `bb repo default-reviewers remove` | `write:repository:bitbucket` | ### Pull Requests (`bb pr …`) [Section titled “Pull Requests (bb pr …)”](#pull-requests-bb-pr-) Read-only PR commands — `list`, `view`, `diff`, `checkout`, `activity`, `checks`, `comments list`, `reviewers list` — only need `read:pullrequest:bitbucket` (plus `read:repository:bitbucket` for repository context). | Command | Required scopes | | ------------------------ | ---------------------------------------------------------- | | `bb pr list` | `read:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr view` | `read:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr diff` | `read:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr checkout` | `read:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr activity` | `read:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr checks` | `read:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr comments list` | `read:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr reviewers list` | `read:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr create` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr edit` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr ready` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr approve` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr decline` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr merge` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr comments add` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr comments edit` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr comments delete` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr reviewers add` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | | `bb pr reviewers remove` | `write:pullrequest:bitbucket`, `read:repository:bitbucket` | ### Snippets (`bb snippet …`) [Section titled “Snippets (bb snippet …)”](#snippets-bb-snippet-) | Command | Required scopes | | ------------------- | ------------------------- | | `bb snippet list` | `read:snippet:bitbucket` | | `bb snippet view` | `read:snippet:bitbucket` | | `bb snippet create` | `write:snippet:bitbucket` | | `bb snippet edit` | `write:snippet:bitbucket` | | `bb snippet delete` | `write:snippet:bitbucket` | ### Local-only commands [Section titled “Local-only commands”](#local-only-commands) These don’t hit the API and don’t need any scope: * `bb config` (all subcommands) * `bb completion` * `bb` (root, including the version-check) ## Common Profiles [Section titled “Common Profiles”](#common-profiles) Pick the profile that matches your workflow and grant only those scopes when creating the token. ### Read-only automation (status checks, dashboards) [Section titled “Read-only automation (status checks, dashboards)”](#read-only-automation-status-checks-dashboards)
```plaintext
read:user:bitbucket
read:repository:bitbucket
read:pullrequest:bitbucket
```
### Bot account that creates and merges PRs [Section titled “Bot account that creates and merges PRs”](#bot-account-that-creates-and-merges-prs)
```plaintext
read:user:bitbucket
read:repository:bitbucket
read:pullrequest:bitbucket
write:pullrequest:bitbucket
```
### Repo provisioning automation [Section titled “Repo provisioning automation”](#repo-provisioning-automation)
```plaintext
read:user:bitbucket
read:repository:bitbucket
write:repository:bitbucket
admin:repository:bitbucket
```
Principle of least privilege Don’t grant `write:` or `admin:` scopes to a token unless the script that uses it actually needs them. A leaked read-only token is far less damaging than a leaked admin token. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If a command exits with [`2003` API\_FORBIDDEN](/reference/error-codes/#2003---api_forbidden), your token is missing the scope listed in the table above. Mint a new token with the required scope (you can’t add scopes to an existing token) and re-authenticate:
```bash
bb auth logout
bb auth login -u your-username -p new-token
```