---
title: "What Shorebird Collects"
description: "What Shorebird's open source client code sends to Shorebird, from the updater in your app and from the Shorebird CLI."
---

This page covers the technical behavior of the open source code Shorebird publishes, and only that:

* **The Shorebird updater**, which you bundle into your app. It determines what Shorebird collects from your app’s users.
* **The Shorebird CLI**, which you and your team run. It determines what Shorebird collects about you, your company and your builds.

Everything else about what Shorebird collects and does, such as analytics on its website and console, its servers, how long it keeps data and the vendors it uses, is in Shorebird’s [privacy policy](https://shorebird.dev/privacy/). The privacy policy is the legal document; this page is a technical explainer that goes with it. If the two ever disagree, the privacy policy wins.

Each section links to the code it describes, so you can read exactly what it does. Those links point at specific lines, which can go stale as the code changes; the code on `main` is always the current truth.

## The updater: data from your app’s users

### The short version

Your app sends Shorebird what it needs to deliver the right patch, to show you how your patches are doing and to count your monthly active users, and nothing else. It sends nothing about who your users are: no names, no accounts, no device identifiers, no location, and nothing from your app’s data.

### Patch checks

Your app checks for a patch so that your users get your fixes without waiting for an app store release. By default it checks each time it starts (see [When do updates happen?](/code-push/faq/#when-do-updates-happen)). Each check sends:

| Field                  | Example                                | Why it’s collected and how it helps you                                                       |
| ---------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------- |
| `app_id`               | `8a9a1b2c-...`                         | Says which of your Shorebird apps this is, from `shorebird.yaml`, so it gets your patches.    |
| `channel`              | `stable`                               | Says which channel to look on, from `shorebird.yaml`, so you can test patches before rollout. |
| `release_version`      | `1.0.0+1`                              | Says which release is installed, so it only gets a patch built for that release.              |
| `platform`             | `android`                              | Picks the patch for the right platform.                                                       |
| `arch`                 | `aarch64`                              | Picks the patch for the right CPU architecture.                                               |
| `current_patch_number` | `3`                                    | Says which patch the app runs now, so it isn’t sent a patch it already has.                   |
| `client_id`            | `0c7e5f3a-6b1d-4e2f-9a8b-1d2c3e4f5a6b` | The anonymous install identifier, used only to count your monthly active users (below).       |

Source: [`PatchCheckRequest` in `network.rs`](https://github.com/shorebirdtech/updater/blob/main/library/src/network.rs#L292-L324).

If there’s a new patch, the app then downloads the patch file. That download is a plain HTTPS request for the file and carries none of the fields above.

### The anonymous install identifier

The updater sends the anonymous install identifier so Shorebird can count your app’s monthly active users (MAUs), the number Shorebird’s plans are priced on. Counting them takes a way to tell one install from another; that is the identifier’s sole purpose.

Only apps built with recent versions of Shorebird send it. Apps built with older versions send no identifier at all, so until your users update to a release built with a recent version, some of your installs don’t send one.

`client_id` is a random v4 UUID that the Shorebird updater generates the first time your app runs. The updater stores it in `state.json` inside your app’s own storage (see [What does the Shorebird updater store on disk?](/code-push/faq/#what-does-the-shorebird-updater-store-on-disk)).

* It’s random. It isn’t derived from anything on the device.
* It’s per install, not per device. Two Shorebird apps on the same phone get two unrelated identifiers.
* It lasts until the app is uninstalled or its data is cleared. The next launch generates a new one. Release and patch updates keep it.

Source: [`generate_client_id` in `updater_state.rs`](https://github.com/shorebirdtech/updater/blob/main/library/src/cache/updater_state.rs#L89-L91).

The FAQ has more on [what the identifier is](/code-push/faq/#what-is-the-anonymous-install-identifier) and [what Shorebird does with it](/code-push/faq/#what-does-shorebird-do-with-the-anonymous-install-identifier).

### Patch events

Shorebird collects patch events so it can show you, in the [Shorebird console](https://console.shorebird.dev), whether each patch is succeeding or failing in the wild: how many devices downloaded it, how many installed it, and how many hit a problem and why. That tells you whether a patch is reaching your users and working, without your app adding any reporting of its own. Your app sends four events:

| Event                       | Sent when                                                    |
| --------------------------- | ------------------------------------------------------------ |
| `__patch_download__`        | A patch finished downloading.                                |
| `__patch_install__`         | A patch was installed and launched successfully.             |
| `__patch_update_failure__`  | Downloading or installing a patch failed.                    |
| `__patch_install_failure__` | An installed patch failed to launch, so the app rolled back. |

Each event carries the same `app_id`, `release_version`, `platform`, `arch` and `client_id` as a patch check, so it’s counted against the right app, release and patch and toward your MAUs, plus:

* `patch_number`: the patch the event is about, so the console shows it under that patch.
* `timestamp`: when it happened, in seconds since the Unix epoch, so the console can show how a rollout went over time.
* `event_id`: a random UUID for the event itself, so an event sent twice is counted once and your numbers stay accurate.

Failure events also carry what you’d need to fix the failure:

* `failure_category`: a short code such as `network`, `out_of_space` or `corrupt_patch`, so you can tell a flaky network from a broken patch.
* `message`: a short description of what went wrong, such as `update_failure: patch 3 failed (...)`. It’s capped at 256 characters, and the updater replaces the app’s file system paths with placeholders like `<storage>` before sending it, since those paths can contain a user name. It never contains your app’s data or anything about your users.

Events that can’t be sent right away (the device is offline, or the app is about to roll back a patch that failed) are queued in `state.json` and sent on a later launch, so the console’s counts include them.

Source: [`PatchEvent` and `EventType` in `events.rs`](https://github.com/shorebirdtech/updater/blob/main/library/src/events.rs), and the [failure categories in `updater.rs`](https://github.com/shorebirdtech/updater/blob/main/library/src/updater.rs#L141-L175).

### What the updater doesn’t send

The fields above are everything the updater sends. In particular, it doesn’t send:

* Device identifiers: no IDFA, IDFV, Android ID, advertising ID, serial number or hardware identifier.
* Device details: no device model, OS version or locale.
* Anything about your users: no names, emails, account IDs or user IDs from your app.
* Your app’s data: nothing your app stores or displays.
* Crash reports or logs: a failed patch sends only the short failure message above.
* Analytics: no screens, sessions, taps or usage beyond the patch check and patch events.
* Location.

## The CLI: data from you and your team

The `shorebird` command line tool, which you and your team run, talks to Shorebird as your signed-in account. It uploads your release and patch files so Shorebird can deliver them to your users. With them it sends:

* With each release and patch: the platform; Flutter and Shorebird versions; your operating system’s name and version; and Xcode’s version for Apple builds. When a build or patch goes wrong, support can see your toolchain without asking you for it, and Shorebird knows which Flutter versions and platforms its customers rely on, so it keeps supporting them.
* Your `shorebird.yaml`, so support can see how your app is configured when you ask for help.
* Whether the build ran on CI and which CI provider, so Shorebird can make its CI integrations work for the providers you use.
* A few yes/no facts about the build, such as whether a patch changed assets or native code, so support can tell why a patch behaves as it does.
* How long each stage of the build took, so Shorebird can find and fix the steps that slow your builds down.
* With every request: the CLI’s version, your operating system and the Dart version, in the `User-Agent` header, so Shorebird can tell you when your CLI needs an update and keep older versions working until then.

The CLI doesn’t send your machine’s name, your user name, file paths or source code, and it has no analytics or usage tracking of its own.

Source: [`UpdateReleaseMetadata`](https://github.com/shorebirdtech/shorebird/blob/main/packages/shorebird_cli/lib/src/metadata/update_release_metadata.dart), [`CreatePatchMetadata`](https://github.com/shorebirdtech/shorebird/blob/main/packages/shorebird_cli/lib/src/metadata/create_patch_metadata.dart), [`BuildEnvironmentMetadata`](https://github.com/shorebirdtech/shorebird/blob/main/packages/shorebird_cli/lib/src/metadata/build_environment_metadata.dart) and [`BuildTraceSummary`](https://github.com/shorebirdtech/shorebird/blob/main/packages/shorebird_cli/lib/src/artifact_builder/build_trace_summary.dart).

## More

* Everything this page doesn’t cover, including how long Shorebird keeps what it collects: Shorebird’s [privacy policy](https://shorebird.dev/privacy/).
* Shorebird’s commitments for your app’s users’ data, as a signed agreement: Shorebird’s [Data Processing Agreement](https://shorebird.dev/dpa/).
* Questions for a security review or procurement questionnaire: Shorebird’s [privacy team](mailto:privacy@shorebird.dev).
