Skip to content

API Reference

Interact programmatically with your Shorebird account. You can manage apps, releases, and over-the-air patches with the Shorebird Code Push API. It offers everything the Shorebird CLI does under the hood.

The full, always-up-to-date reference is published as an OpenAPI 3 document:

https://api.shorebird.dev/openapi.json

Load that URL into any OpenAPI-compatible viewer to browse every endpoint, parameter, and schema interactively. If you are pointing a tool at Shorebird and only have the hostname, the API catalog at https://api.shorebird.dev/.well-known/api-catalog lists the spec, these docs, and the Shorebird status page.

The API does not yet carry a compatibility guarantee. It is the same API the Shorebird CLI and console use, and it changes when they do. You are welcome to build on it; expect to follow it.

For everyday tasks, use the dedicated commands (shorebird apps list, shorebird releases list, shorebird patches list, and so on). shorebird api is for everything else: it calls any API endpoint, including ones with no dedicated command, and is designed mainly for coding agents and scripts. It sends an authenticated request using your current Shorebird credentials, so there is no token to copy and no headers to set. Only the response body goes to stdout (the global --json flag is not supported), and a failed request exits with a non-zero status. --jq applies only to successful responses; on an error the raw error body is printed instead, so check the exit status before using the output. Find endpoints in the OpenAPI spec.

shorebird api needs Shorebird 1.6.129 or newer.

# List the members of an organization (find its id with `shorebird orgs list`, or `shorebird account orgs` before 1.6.135)
shorebird api /organizations/ORG_ID/users --jq '.users[].user.email'

The HTTP method can go before the endpoint, or in -X. Without one, the request is a GET, or a POST when you pass fields with -f or -F:

shorebird api GET /apps
shorebird api DELETE /apps/APP_ID/releases/RELEASE_ID

To read a whole paged list in one call, add --paginate. It keeps requesting the next page and prints the pages as one JSON object, with the list fields joined. It works only with GET, and on an endpoint that doesn’t page it makes a single request:

shorebird api /apps -f per_page=100 --paginate --jq '.apps[].app_id'

Because --paginate always sends a GET, the -f fields here go in the query string.

The method before the endpoint and --paginate need Shorebird 1.6.130 or newer.

Run shorebird api --help for all options. For how paging works, see Pagination below.

https://api.shorebird.dev/api/v1

Every request (other than the patch-check endpoint, see below) needs a bearer token. No other headers are required:

Authorization: Bearer <token>

There are two kinds of tokens, and which one you use depends on context:

  • API keys (sb_api_*): long-lived, generated from the Shorebird console. Use these for CI pipelines, scripts, and any non-interactive automation. Default expiration is 1 year, with options for 30 or 90 days, and only a service account’s key can be set to never expire. Treat these like any other long-lived secret.
  • OAuth JWTs: short-lived (15 minutes), issued by the interactive login flow and refreshed automatically by the CLI. Use these for interactive/local tooling. Given the fast expiration, these should not be hardcoded anywhere.

The core objects and how they relate:

  • Organization → has Users as members, with a Role (owner, admin, appManager, developer, viewer) each.
  • App → belongs to an organization, has Channels (e.g. stable, beta).
  • Release → belongs to an app, has a platform (android, ios, linux, macos, windows) and status (draft, active), and one or more Release Artifacts (the platform/arch-specific binaries).
  • Patch → an OTA update tied to a release, with its own Patch Artifacts; patches get promoted to a channel to go live for devices.

The main tags the spec organizes endpoints under are below. See the linked reference for full parameter and response detail on each:

  • Users: the authenticated user’s account
  • Apps: create/list/delete apps, fetch app icons
  • Channels: release channels for distributing patches
  • Releases: create and manage releases and their artifacts
  • Patches: create patches, register artifacts, promote to a channel, and check for available patches from a device
  • Metrics: version distribution, device growth, patch adoption/installs/downloads, active-hours and activity-heatmap analytics
  • Organizations: list memberships, org apps, and org users
  • Diagnostics: GCP upload/download speed-test URLs
  • Errors: non-2xx responses return a standard ErrorResponse with a machine-readable code, a human-readable message, and optional details and documentation_url. Branch on code rather than on message.

  • Pagination: the apps, releases and patches lists accept an optional per_page (default 30, maximum 100) and cursor. A paged response includes next_cursor when there is another page; pass it as cursor to fetch the next one. Without per_page or cursor, these lists return every item. Some newer list endpoints page by default, with the same parameters. shorebird api --paginate follows next_cursor for you.

    On a CLI older than 1.6.130, this script prints every app ID, one page of 50 at a time, stops when a page has no next_cursor, and exits with status 1 if a request fails:

    cursor=""
    while :; do
      page=(-X GET /apps -f per_page=50)
      [ -n "$cursor" ] && page+=(-f "cursor=$cursor")
      shorebird api "${page[@]}" --jq '.apps[].app_id' || exit 1
      cursor=$(shorebird api "${page[@]}" --jq '.next_cursor | select(. != null)') || exit 1
      [ -n "$cursor" ] || break
    done
  • Unauthenticated endpoint: POST /patches/check is the one exception to the auth rule above: it’s what a device calls to check for an available patch, and it doesn’t require a bearer token.