We're making some changes to the Google Fit APIs. Learn about how these changes might affect your app. Read our new policy.

Authorization, heart rate and sleep updates 2020

As part of our ongoing effort to enhance the security and privacy of Google Fit for users and developers, we’re making changes to the next version of the Google Fit API. If you're a developer with an existing app/project that uses the Google Fit APIs, learn about the changes we're making below and how they might affect your app.

Follow the relevant instructions to make sure your integration continues to work. These changes will be available for developers to test and use from 19 October 2020. On 4 May 2021 (delayed from 27 April), the authorization changes will become required and the policy changes will become enforceable for all apps accessing Google Fit APIs.

These changes apply to both our Android and REST APIs. The steps you'll need to follow to update your integration will be different depending on which API you're using.

What are the authorization changes?

Improving the behaviour of read and write access

Before, Write scopes allowed both write-access and read-access.

Now, Write scopes allow your app to have write-access and read-access only to data written by your app.

What do you need to do?

To read data written by other apps from the Google Fit platform, update your integration to explicitly request the relevant read scopes.

Android

  1. Upgrade your app to build using SDK version 20.0.0.
  2. To read data written by other apps from the Google Fit platform, add the corresponding read constant to your code. For example, this:

    val fitnessOptions = FitnessOptions.builder()
        .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_WRITE)
        .build()
    

    becomes this:

    val fitnessOptions = FitnessOptions.builder()
        // Add the read scope.
        .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
        .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_WRITE)
        .build()
    

REST

If your application only requests the write scope, but also relies on reading data of this type that it did not write, you should explicitly add the corresponding read scope.

Separate scopes for heart rate

Before, heart rate came under the Body scope.

Now, heart data has its own, dedicated pair of scopes that apply to the heart rate data type. This increased granularity of access recognises the sensitivity of heart rate data and lets users grant access to your app to read and/or write heart rate data independently of other body data types.

What do you need to do?

Android

  1. Upgrade your app to build using SDK version 20.0.0.
  2. Post-upgrade, the first time your app requests the heart rate data type, by using the appropriate data type in FitnessOptions, the app will request permission for the new scope.

REST

Modify your application to request the appropriate additional scope(s) as necessary:

    https://www.googleapis.com/auth/fitness.heart_rate.read
    https://www.googleapis.com/auth/fitness.heart_rate.write

Separate scopes and new data type for sleep

Before, sleep was treated as an activity, under the activity data type.

Now, sleep data has:

  • Its own, separate data type. This increases the clarity around how Google Fit treats activity data versus sleep data.
  • Its own, dedicated pair of scopes that apply to the new sleep data type. This increased granularity of access recognises the sensitivity of sleep data and lets users grant access to your app to read and/or write sleep data independently of other activity data types.

What do you need to do?

Android

  1. Upgrade your app to build using SDK version 20.0.0.
  2. Use the new sleep data type. The first time your app requests the sleep.segments data type, post-upgrade, the app will request permission for the new scope.

    val fitnessOptions = FitnessOptions.builder() .addDataType(DataType.TYPE_SLEEP_SEGMENT, FitnessOptions.ACCESS_READ) .build()

  3. Migrate to the new data type in your data sources, for example

     val dataSource  = DataSource.Builder()
        .setType(DataSource.TYPE_RAW)
        .setDataType(DataType.TYPE_SLEEP_SEGMENT)
        .setAppPackageName(this)
        .setStreamName(streamName)
        .build()
    
  4. Migrate your construction of data points to use the new data type:

    val dataSet = DataSet.builder(dataSource)
        .add(
            DataPoint.builder(dataSource)
                .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
                .setField(Field.FIELD_SLEEP_SEGMENT_TYPE, SleepStages.SLEEP_LIGHT)
                .build()
        ).build()
    
  5. To read sleep sessions, use the .includeSleepSessions() method as sleep sessions aren't returned by default. Learn more about reading sleep data.

     SessionReadRequest request = new SessionReadRequest.Builder()
        .readSessionsFromAllApps()
        // By default, only activity sessions are included, so you
        // need to explicitly request sleep sessions.
        .includeSleepSessions()
        .read(DataType.TYPE_SLEEP_SEGMENT)
        .setTimeInterval(1576690819, 1576750401, TimeUnit.SECONDS)
        .build();
    

REST

  1. Modify your application to request the appropriate additional scope(s):

    https://www.googleapis.com/auth/fitness.sleep.read
    https://www.googleapis.com/auth/fitness.sleep.write
    

    It's best practice to request authorization from users for resources at the time you need them. Follow the guidelines on requesting incremental authorization.

  2. Migrate from using com.google.activity.segment to com.google.sleep.segment, and change the integer for the type of sleep to the new sleep_segment_type enum:

    {
        "dataTypeName": "com.google.activity.segment",
        "startTimeNanos": startTime,
        "endTimeNanos": endTime,
        "value": [
            {
                intVal: 109 // Light sleep
            }
        ]
    }
    

    becomes

    {
        "dataTypeName": "com.google.sleep.segment",
        "startTimeNanos": startTime,
        "endTimeNanos": endTime,
        "value": [
            {
                intVal: 4 // Light sleep
            }
        ]
    }
    

Activity segments with a sleep activity type will be automatically 1-time copied into sleep segments at or before migration start date. This will ensure that any data read from sleep.segment will always contain all sleep data for the user.

Increasing clarity around session versus data access

If you're using our Android APIs, currently using FitnessOptions lets you specify which types of data you want access to, but it doesn't let you be explicit about what types of sessions you want access to. Sessions are metadata about something users did, like an activity, a workout or a night’s sleep.

Now, when working with the SessionsClient, you need to specify what type of session your app needs to access, using the appropriate methods from FitnessOptions. For example, to read sessions relating to running you might choose:

        val fitnessOptions = FitnessOptions.builder()
            .accessActivitySessions(FitnessOptions.ACCESS_READ)
            .addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_READ)
            .addDataType(DataType.TYPE_SPEED, FitnessOptions.ACCESS_READ)
            .addDataType(DataType.TYPE_LOCATION_SAMPLE, FitnessOptions.ACCESS_READ)
            .build()

This example specifies that your app wants to access activity session metadata, and it also specifies the data types it wants to read within those sessions; the heart rate, speed and location data types are used in this example.

What are the policy changes?

Strengthening the review system for apps using Google Fit

We're conscious that health and wellness data is particularly sensitive to users. Ensuring the security and privacy of that data is of utmost importance. So, we will be enhancing the review system that apps using Google Fit need to go through. This verification process will begin later in 2021.

To enable the enhanced review, we have updated all Fitness API scopes for Write access to Sensitive, and we will update all scopes for Read access to Restricted. To understand the implications for your apps, learn more about requesting access to sensitive and restricted OAuth scopes.

What do you need to do?

When to apply for verification?

  • Wait until you’re contacted by the Trust and Safety team who will reach out at least a month before your verification is required to start to give you more information on the verification process and next steps. Your app will continue to have access to the data and scopes it currently does until then.
  • If your app is not affected by these API changes and you want to request access to a new scope or scopes, you can apply for verification whenever you're ready to submit your application.

Thinking about user experience

When you update your app to request a new scope (for example, if you add the new sleep or heart rate scopes, or add a read scope), users will be prompted that your app is requesting these access to these scopes and they can choose to grant or reject access.

It's best practice to request authorization from users for resources at the time you need them. Follow the guidelines on requesting incremental authorization.

Users will be more likely to grant access if they understand why/how your app uses this data:

  • Consider adding a screen that warns/informs users that they'll be asked for these scopes.
  • Clearly explain why your app is asking for access to these scopes/data so users can make an informed decision.

Learn more about best practices around app permissions for Android.

Testing your integration before enforcement

You can test your integration before the enforcement date to check your changes work as expected.

Android

Use SDK 20.0.0 or later to switch to the new authorization model.

REST

Use the use2020ScopeRestrictions parameter to switch to the new authorisation model before the enforcement date to test your integration.

../fitness/v1/users/me/dataSources -H 'Authorization: Bearer ' -H 'FitAuthOptions: use_2020_scope_restrictions:true

FAQs

Which Google Fit APIs does this policy change apply to?

The policy applies to both the REST and Android APIs

The policy becomes enforceable at the changes deadline. What does this mean in practice?

If you access Fit APIs and have more than 100 users, you will be contacted in due course to begin a verification process. If you request read access to any data that you did not write, then you will also be required to carry out a security assessment. This includes cases where you are reading sensor data such as steps using the Recording API and Sessions APIs on Android.

How can I check whether I’ve exceeded the 100 user cap?

You can look that up for your project in Cloud Console.

I use a version of the Fit Android SDK older than v20.0.0. If I do not upgrade, will my app stop working on April 27th?

It depends on which data types you use from Fit and how you use them. If any of the following are true about your integration then those aspects will fail with an authorization error:

  1. You request only write scopes and access data you did not write.
  2. You read or write sleep sessions or segments
  3. You read or write heart rate data
  4. You create a FitnessOptions object without a reference to FitnessOptions.ACCESS_READ for some data types, and use that in the Recording API or Sessions API.

Do apps need to go through verification before the changes deadline?

No. The changes deadline is when the policy becomes enforceable. You will be separately invited to go through verification with ample notice to complete it.

How will I be invited to go through verification?

You will be contacted via the contact email addresses that you have stored in Cloud Console, so please make sure these are kept up to date.

Do I still need to go through the verification process after the changes

deadline if I don’t upgrade my app to v20.0.0?

Yes.

Which data types can I read using the Google Fit APIs without going through verification or a security assessment?

If your app reads data other than data that it has written, and has exceeded the 100 user cap, then your app will be required to go through app verification and security assessment.

Which data types can I write using the Google Fit API without going through verification?

All fitness.*.write scopes in Google Fit are categorized as sensitive and therefore your app will need to go through sensitive scope verification, but not a security assessment.

How do I determine if my app needs a security assessment?

If your app uses a restricted scope such as any read scope, and has exceeded the 100 user cap then it will need a security assessment. You will be separately invited to go through verification and security assessment with ample notice to complete it.

How do I get a security assessment if my app needs one?

When you are invited to go through verification, you will be provided with details of how to get a security assessment with ample notice to complete it.

How much will a security assessment cost annually and when will I need to pay?

Full details of the security assessment will be provided in due course and well before any deadline to complete the assessment.

If I need a security assessment does it need to be completed by the changes deadline?

No. You do not need to complete the security assessment by the changes deadline. The changes deadline is when the policy becomes enforceable. You will be separately invited to go through verification and security assessment with ample notice to complete it.