Skip to content

API Command — Raw Authenticated Bitbucket API Access

bb api sends an authenticated request to any Bitbucket Cloud 2.0 endpoint through the same stack as every other command: Basic/Bearer auth, automatic OAuth token refresh, rate-limit and transient-error retries, and secret redaction. Same shape as gh api.

Every global flag is inherited — see Global Flags. The ones that matter here are --json [fields], --jq <expression>, -w/--workspace, -r/--repo, and --no-color/--no-unicode, which style the error and --paginate warning lines. --no-truncate and --locale change nothing: bb api prints no tables and no dates.

Terminal window
bb api [options] [method] <endpoint>
Argument Description
method Optional HTTP verb (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS), case-insensitive. When omitted, defaults to GET, or POST when fields/body are present. Both bb api GET /user and bb api /user work.
endpoint The API path, relative to https://api.bitbucket.org/2.0 (a leading / is optional). A redundant leading /2.0 is stripped, so paths copied straight out of the Bitbucket REST docs (/2.0/user) work unchanged. {workspace} and {repo} placeholders are substituted from --workspace/--repo or the current repository.
Option Description
-X, --method <method> HTTP method. Overrides a positional verb.
-f, --raw-field <key=value> Add a string parameter. Query param on GET/HEAD, JSON body field otherwise. Repeatable.
-F, --field <key=value> Add a typed parameter: true/false/null and numbers are converted; @file reads a file and @- reads stdin. Repeatable.
--input <file> Read the raw request body from a file, or - for stdin. Sent as application/json (override with -H 'Content-Type: ...'). Mutually exclusive with -f/-F.
-H, --header <key:value> Add a request header. Repeatable. Authorization is managed automatically and cannot be set here.
-i, --include Print the HTTP status line and response headers before the body (text mode only — suppressed under --json).
--paginate Follow the cursor (next) across pages and merge every page into a single { "values": [...] } result (GET/HEAD only).

Positionals are strict: at most two, and with two the first must be an HTTP verb. Every case below exits 1 without sending a request.

$ bb api
✗ An endpoint path is required (e.g. /user). Run `bb api --help` for usage.
$ bb api GET
✗ An endpoint path is required after the method (e.g. bb api GET /user). Run `bb api --help` for usage.
$ bb api GTE /user
✗ 'GTE' is not a valid HTTP method. Expected one of: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. Run `bb api --help` for usage.
(Did you mean GET?)
$ bb api -X GTE /user
✗ --method must be one of: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
(Did you mean GET?)
$ bb api GET /user /extra
error: too many arguments for 'api'. Expected 2 arguments but got 3: GET, /user, /extra.
Terminal window
# Current user
bb api /user
# Explicit method (equivalent to the above)
bb api GET /user
# List every pull request, following pagination, using the current repository
bb api /repositories/{workspace}/{repo}/pullrequests --paginate
# Create an issue (method inferred as POST because fields are present)
bb api /repositories/my-ws/my-repo/issues -f title=Bug -f priority=major
# -F applies gh-style magic typing: true/false/null and numbers become JSON literals
bb api PUT /repositories/my-ws/my-repo -F is_private=true
# Send a JSON body from a file
bb api PUT /repositories/my-ws/my-repo/pullrequests/42 --input body.json
# Pipe a body in from stdin
cat body.json | bb api POST /repositories/my-ws/my-repo/pullrequests/42/comments --input -
# Force a GET with query parameters (fields normally infer POST)
bb api GET /repositories/my-ws/my-repo/pullrequests -f state=MERGED
# Filter the response with jq (no --json needed — bb api output is already JSON)
bb api /repositories/my-ws --jq '.values[].name'
# Inspect the status line and response headers
bb api -i /user
  • GET / HEAD-f/-F are appended as a URL query string (?key=value&...).
  • Every other method-f/-F are assembled into a JSON request body.
  • Repeating the same key turns it into an array, matching gh.

{workspace} and {repo} are resolved only when they actually appear in the path, so bb api /user works outside a checkout.

Terminal window
# Inside a Bitbucket checkout, these resolve automatically:
bb api /repositories/{workspace}/{repo}/commits
# Or override explicitly:
bb api -w my-ws -r my-repo /repositories/{workspace}/{repo}/commits

The response body is printed to stdout. JSON responses are pretty-printed and respect the global --json [fields] projection and --jq filtering. Non-JSON responses (e.g. raw diffs) are printed verbatim, and --json/--jq are inert on them. An empty response body (e.g. a HEAD or 204) prints nothing in text mode, and {} under --json, so a downstream jq never sees zero bytes.

Terminal window
bb api /user
{
"type": "user",
"username": "my-user",
"display_name": "My User",
"account_id": "557058:..."
}

bb api is the only command where --jq works without --json; everywhere else a bare --jq fails with ✗ --jq requires --json.

On a paginated endpoint, --json <fields> unwraps the values array and drops the envelope (pagelen, size, next), returning a bare array of projected objects. Projection runs before --jq, so once you pass --json <fields> the expression sees that flat array — use .[], not .values[].

Terminal window
# Envelope intact
bb api /repositories/my-ws --jq '.values[].name'
# Projected and unwrapped
bb api /repositories/my-ws --json name --jq '.[].name'
  • Authentication is automatic. The same credentials as the rest of the CLI are attached to every request; you cannot (and need not) set Authorization yourself.
  • Only the Bitbucket API host is allowed. Absolute URLs are accepted only when they point at api.bitbucket.org. This prevents the CLI from sending your token to a foreign host. Pagination cursors (which are absolute api.bitbucket.org URLs) are followed safely.
  • --paginate degrades instead of erroring. On a non-GET/HEAD request it prints --paginate only applies to GET/HEAD requests; ignoring it. on stderr and sends the request unpaginated. If the first response has no values array — a single resource rather than a collection — it prints --paginate: response has no "values" array; returning the first page only. and returns page 1. Both warnings are suppressed under --json. Combined with -i, the status line and headers printed are the first page’s.
  • Errors surface the API response. On a non-2xx status, the API’s error body is printed and the command exits non-zero. With --json, the error payload (including statusCode and response) is emitted as structured JSON. A 401 or 403 also carries a hint with the next step to take. The generic 404 hint is deliberately suppressed here — you supplied the URL yourself, so advice about --workspace/--repo would not apply. Note the API error body prints to stdout while the error line and its hint go to stderr, so in a terminal the hint appears after the body.
  • Retries and redaction are inherited from the shared API client — rate limits (429) and the transient gateway errors 502/503/504 are retried with backoff, and sensitive values are redacted from DEBUG logs.
  • Scripting & Automation — combine bb api with --jq to build pipelines over endpoints without a typed command.
  • JSON Output — how --json projection and --jq filtering work across the CLI.
  • Authentication — the auth methods that bb api reuses.