Data Management in the Google Health API

Working with data in the Google Health API is at its core a cycle of syncing data between the Google Health API datastore in the cloud and your own app or backend datastore. However, this cycle can take different forms depending on a variety of factors:

  • Are you writing data to the Google Health API? Reading only? Or doing both?
  • Is your datastore local on the app or device? Or in your own cloud?
  • Do you need to sync Google Health API data between the user's app and a wearable device? How often do you sync devices?
  • What types of data are you working with? Basic counts? Units of measurement? Series with different rates of sampling?
  • Do you plan to read data while your app is in the background?
  • Do you plan to work with historical data recorded prior to your app receiving user permissions?

To understand how this all fits together, take a look at the Google Health API sync lifecycle. There are two versions of this lifecycle: standard (read and write) and read-only.

The standard sync lifecycle

Standard sync lifecycle in the Google Health API
Figure 1: Standard sync lifecycle in the Google Health API

Integrating with the Google Health API means copying data to an app or backend datastore. For ease of use in this documentation, we'll call this datastore the developer datastore.

"Copy" here can take the place of any discrete activity, such as reading from the Google Health API (copying to the developer datastore) or writing to the Google Health API (copying to the Google Health API). Performing these actions repeatedly in a specific order is the sync lifecycle.

Figure 1 illustrates the standard sync lifecycle that involves read and write operations, without regard to any of the factors previously mentioned.

Write

  1. Prepare new data for writing — Transfer data from an external device or app and format data points into JSON representations compatible with Google Health API data types. Note that custom client-assigned IDs for writes are not supported in the Health API at this time. Such IDs may be provided in a POST, but they are ignored.
  2. Upsert records — Submit data points to the Google Health API using REST endpoints. Use POST for creating records, and PATCH for inserting and updating existing records. The IDs needed for the PATCH operation will have come from a previous POST operation (next step in a previous cycle).
  3. Process returned resource IDs — When using server-generated IDs, extract and persist the server-returned resource name or ID in your developer datastore to enable future updates (PATCH) or deletions (DELETE). See Identification strategies for more information on the two types.

Read

  1. Read records — Fetch new data from and changes to existing data in the Google Health API using REST endpoints (GET with filter query parameters and pageToken pagination, or aggregation endpoints like rollUp and dailyRollUp), or receive real-time notifications using Webhook Subscriptions (projects.subscribers). A notification only indicates that new data is available, not what the actual data is.
  2. Reconcile developer datastore — Reconcile the new and updated data to your developer datastore.

This cycle then repeats at appropriate intervals according to the specific needs of external devices or apps. This is generally the order we recommend for syncing data between your own datastore and the Google Health API.

Identification strategies

If you intend to write data to the Google Health API, prior to building your integration with the Google Health APIs, you must choose a resource identification strategy when creating data points (the basic unit of data).

Client-assigned IDs for writes are not supported in the Health API at this time. Such IDs may be provided in a POST, but they are ignored. Details on this option are provided here for informational purposes.

  1. Server-Generated IDs (default option): The client submits data without an ID, and the Google Health API backend generates and returns a unique system identifier.
  2. Client-Assigned Custom IDs (per AIP-133, not yet supported): The client app generates a unique identifier (for example, a UUID or local database primary key) and supplies it in the resource path upon creation.

The following table compares both identification strategies to help you choose the right approach for your integration:

Feature Server-Generated IDs Client-Assigned Custom IDs
ID Generation Server generates random system ID during POST execution. Client generates stable ID locally (UUID v4 / internal PK) before write.
Resource Path .../dataPoints/{server_id} (returned in response) .../dataPoints/{custom_id}
Post-Write Local Step Required. Must store returned server_id in local DB to enable future updates/deletions. None. App already owns the ID.
ID Mapping Table Required. Client must maintain a 2-way mapping (local_idserver_id). Not needed. Client uses its own primary key directly.
Retry Behavior (Weak Network) Risk of Duplicates. Retrying a timed-out POST creates a duplicate record with a new server ID. Safe & Idempotent. Retrying POST with the same custom_id prevents duplicate creation (returns 409 ALREADY_EXISTS).
Offline Sync Support Limited. Must wait for server response to obtain official resource IDs before referencing them. Full. Entities can be created and mutated offline with stable IDs, then synced seamlessly when reconnected.
Format Constraints Handled entirely by the server. Must follow ^[a-z0-9-]{4,63}$ (4–63 lowercase alphanumeric & hyphens).
When to Choose

Choose server-generated IDs if:

  • Your app is write-only / append-only (e.g. sending telemetry or step counts that are never updated or deleted later).
  • Your app does not maintain a local persistent database of individual data points.
  • You prefer simplicity without managing string validation constraints (such as 4-63 characters).

Choose custom IDs if:

  • You operate a bi-directional sync app that reads, writes, and updates health records across devices.
  • Your app has a local database (such as Room or SQLite) storing records with local primary keys.
  • Your users record data offline or over intermittent mobile connections where safe retries are necessary.
  • You want to eliminate ID mapping tables between your backend database and the API.

The read-only sync lifecycle

Read-only sync lifecycle in the Google Health API
Figure 2: Read-only sync lifecycle in the Google Health API

An app that intends to only read from the Google Health API must copy data to their developer datastore and handle the reconciliation portion of the lifecycle.

The same tasks covered in the Read section apply here.

Figure 2 illustrates the read-only lifecycle.