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 three 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.
  • Service account tokens from GitHub Actions: short-lived (15 minutes), for a service account, issued in exchange for the OIDC token GitHub gives a workflow that a trust rule allows. The Shorebird CLI and actions make the exchange for you, so there’s no Shorebird secret to store. Trust rules need a Business or Enterprise plan.

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 operations, grouped by feature. Each group links to the page that explains the feature; the spec has every parameter and response:

  • Users: your own account, its email notification preferences, and deleting it.
  • Apps: create, list, rename and delete apps, and read an app’s signing key.
  • Releases: create releases, upload and list their artifacts, edit notes, and delete them. See Release.
  • Patches: create patches and upload their artifacts, promote, roll back and roll forward, and the device’s patch check. See Patch and Rollback.
  • Channels: create, list and delete tracks.
  • Metrics: active users, new devices, version distribution, patch adoption, installs and downloads, active hours and the activity heatmap.
  • Organizations: your memberships, creating, renaming and deleting organizations, their apps (and transferring an app into one), members and their roles, and organization invitations. See Organizations.
  • Collaborators: an app’s per-app collaborators and their invitations.
  • Invitations: invitations sent to you, and accepting or declining them. See Accept an invitation.
  • Billing: your plan and patch install usage, and an organization’s. See Plans & Upgrading.
  • Service accounts: an organization’s service accounts, their keys and their trust rules. See Service Accounts and Trust Rules.
  • Audit logs: an organization’s or enterprise’s audit log (/organizations/{organizationId}/audit-logs, /enterprises/{enterpriseId}/audit-logs). See Audit Logs.
  • Enterprises: your enterprise, its apps, members, guests, organizations and their members, service accounts, and billing. See Enterprise and Enterprise Roles.
  • Diagnostics: upload and download speed-test URLs.

Many operations’ descriptions in the spec name the permission they need. Most need a role in the organization that owns the resource; see What each role can do.

Requests are rate limited per caller: per bearer token, or per IP address for a request without one. Every response carries RateLimit-Policy and RateLimit headers, which give the limit, the requests left, and the seconds until the window resets, so a script can slow down before it’s refused.

A refused request gets a 429 with a Retry-After header, in seconds, and the usual error body:

{
  "code": "rate_limited",
  "message": "Too many requests. Wait and try again.",
  "details": "Limit is ... requests per ... seconds; it resets in ... seconds."
}

Wait for Retry-After and send the request again.

  • 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.