Skip to content

API command - Raw authenticated requests

bb api calls Bitbucket Cloud 2.0 endpoints using your configured credentials, OAuth refresh, and the CLI’s retry settings. Use it for endpoints without a typed command.

See Global flags for output and context options. --no-truncate and --locale have no effect because this command prints no tables or 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, on success and failure (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).
--dry-run Print the write request instead of sending it (details)

Put bare --json after the endpoint. Its optional field-list argument can otherwise consume the HTTP verb or endpoint.

At most two positional arguments are accepted. With two, the first must be an HTTP verb. Missing endpoints and invalid verbs fail before sending a request.

Terminal window
bb api # missing endpoint
bb api GET # missing endpoint after method
bb api GTE /user # invalid method
bb api GET /user /extra # too many arguments
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
# Trigger a pipeline (a JSON body from a file; the target object is nested)
bb api POST /repositories/my-ws/my-repo/pipelines/ --input pipeline.json
# -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.
  • Field keys are literal. -f target.commit=abc1234 does not create a nested target object. Use --input for nested JSON.

{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 on a terminal and compact when piped, and respect the global --json [fields] projection, --lean, 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.
  • Absolute endpoints require HTTPS on the Bitbucket API host. Use https://api.bitbucket.org/... without embedded URL credentials. Malformed URLs, protocol-relative paths such as //host/path, backslashes and raw control characters are rejected. Pagination cursors follow the same rules. Relative endpoints such as /user and /2.0/user are still accepted.
  • --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 command exits non-zero and prints the upstream exchange to stderr, after the ✗ line: by default just the error body; with -i/--include, the status line and response headers first. A body that merely repeats the message (a plain-text Bad Request) is not echoed twice. With --json, a single compact error object is emitted on stderr carrying statusCode, response (the body), headers, and statusText when the transport provides one. 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. Unlike success output, error bodies are not field-projected or --jq-filtered.
Terminal window
# The failing request's status line, headers and body all land on stderr
bb api GET /repositories/my-ws/no-such-repository -i
# Structured error (status + headers + body) for scripts
bb api GET /repositories/my-ws/no-such-repository --json 2> err.json
jq '.statusCode, .response, .headers' err.json
  • 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 BB_DEBUG traces.
  • 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.