# How to Record a Workout

This document describes how to record a workout using the Fitness REST API.

> [!IMPORTANT]
> **Important:** For best practices when managing user data, see [Responsible use of Google Fit](https://developers.google.com/fit/overview#responsible_use_of_google_fit).

## Step 1: Set up a project

You need to set up a project in the [Google API Console](https://console.cloud.google.com/) and activate access to the
Fitness REST API, as described in [Getting Started](https://developers.google.com/fit/rest/v1/get-started).

## Step 2: Authenticate your app

Your app needs to authenticate requests to the Fitness API using an access token. To obtain
the access token, your app includes client-specific credentials and a scope of access,
as described in [Authorizing Requests](https://developers.google.com/fit/rest/v1/authorization).

## Step 3: Create a data source

A data source represents a source of sensor data of a particular type. All data inserted into
the fitness store must be associated with a data source. You can create data sources once and
reuse them for future sessions.

To create a data source, submit an authenticated HTTP request with these parameters:

HTTP method
:   POST

Resource

:   `https://www.googleapis.com/fitness/v1/users/me/dataSources`

    The `me` user ID refers to the user whose access token authorizes the request.

Request body
:

    ```
    {
    "name": "example-fit-heart-rate",
    "dataStreamId":
        "raw:com.google.heart_rate.bpm:1234567890:Example Fit:example-fit-hrm-1:123456",
    "dataType": {
        "field": [{
            "name": "bpm",
            "format": "floatPoint"
        }],
        "name": "com.google.heart_rate.bpm"
    },
    "application": {
        "packageName": "com.example.fit.someapp",
        "version": "1.0"
    },
    "device": {
        "model": "example-fit-hrm-1",
        "version": "1",
        "type": "watch",
        "uid": "123456",
        "manufacturer":"Example Fit"
    },
    "type": "raw"
    }
    ```

This request creates a data source that represents a heart rate monitor which provides fitness
data of type `com.google.heart_rate.bpm`. You must specify the ID of the data source, and it
can be any value. The data source ID in this example follows a reasonable naming convention
that you can adopt. The device component is optional if the data is only generated by an app.

If the request is successful, the response is a `200 OK` status code.

For more information about data sources, see the API reference for the
[`Users.dataSources`](https://developers.google.com/fit/rest/v1/reference/users/dataSources) resource.

## Step 4: Add data points

You use datasets to insert data points in the fitness store. A dataset is a collection of data
points from a single data source bounded by time.

To create a dataset and add points to it, submit an authenticated HTTP request with these
parameters:

HTTP method
:   PATCH

Resource

:   `https://www.googleapis.com/fitness/v1/users/me/dataSources/
    raw:com.google.heart_rate.bpm:1234567890:Example%20Fit:example-fit-hrm-1:123456/datasets/1411053997000000000-1411057556000000000`

    The URL includes the data source ID and the start and end times of the dataset in nanoseconds.

Request body
:

    ```
    {
    "minStartTimeNs": 1411053997000000000,
    "maxEndTimeNs": 1411057556000000000,
    "dataSourceId":
      "raw:com.google.heart_rate.bpm:1234567890:Example Fit:example-fit-hrm-1:123456",
    "point": [
    {
      "startTimeNanos": 1411053997000000000,
      "endTimeNanos": 1411053997000000000,
      "dataTypeName": "com.google.heart_rate.bpm",
      "value": [
        {
          "fpVal": 78.8
        }
      ]
    },
    {
      "startTimeNanos": 1411055000000000000,
      "endTimeNanos": 1411055000000000000,
      "dataTypeName": "com.google.heart_rate.bpm",
      "value": [
        {
          "fpVal": 89.1
        }
      ]
    },
    {
      "startTimeNanos": 1411057556000000000,
      "endTimeNanos": 1411057556000000000,
      "dataTypeName": "com.google.heart_rate.bpm",
      "value": [
        {
          "fpVal": 62.45
        }
      ]
    }
    ]
    }
    ```

This request creates a dataset with three heart rate data points within an hour for the data
source in the previous step.

> [!NOTE]
> **Note:** For data points that have multiple values (like location), the order of the values must match the data type definition.

If the request is successful, the response is a `200 OK` status code.

For more information about datasets, see the API reference for the
[`Users.dataSources.datasets`](https://developers.google.com/fit/rest/v1/reference/users/dataSources/datasets) resource.

### Generate valid timestamps

The timestamps in the example above are in nanoseconds. To generate valid timestamps, you can use
the following Python script:

```
from datetime import datetime, timedelta
import calendar

def date_to_nano(ts):
    """
    Takes a datetime object and returns POSIX UTC in nanoseconds
    """
    return calendar.timegm(ts.utctimetuple()) * int(1e9)

if __name__ == '__main__':
    print 'Current time is %d' % date_to_nano(datetime.now())
    print 'Time 1 hour ago was %d' % date_to_nano(datetime.now() +
       timedelta(hours=-1))
```

## Step 5: Create a session

Now that you have inserted data into the fitness store, you can insert a session to provide
additional metadata for this workout. Sessions represent a time interval during which users
perform a fitness activity.

To create a session for this workout, submit an authenticated HTTP request with these parameters:

HTTP method
:   PUT

Resource

:   `https://www.googleapis.com/fitness/v1/users/me/sessions/sessionId`

    The <var class="apiparam" translate="no">sessionId</var> is arbitrary and must be unique for all sessions
    associated with the authenticated user.

Request body
:

    ```
    {
    "id": "example-fit-1411053997",
    "name": "Example Fit Run on Sunday Afternoon",
    "description": "Example Fit Running Session",
    "startTimeMillis": 1411053997000,
    "endTimeMillis": 1411057556000,
    "application": {
    "name": "Foo Example App",
    "version": "1.0"
    },
    "activityType": 8
    }
    ```

Choose a session name that is human-readable and descriptive, since it may be used by other apps
to summarize the session. The start and end times for sessions are in milliseconds
(not nanoseconds). Use the same package name for your sessions and your data sources; this makes
data more consistent and ensures that data attribution will link back to your app.

The time interval specified in this session covers the heart rate data inserted earlier, so
Google Fit associates those data points with this session.

For more information about sessions, see the API reference for the
[`Users.sessions`](https://developers.google.com/fit/rest/v1/reference/users/sessions) resource.

## Step 6: Create activity segments

Activity segments help you represent different activities within a session.
An activity segment is a time segment that covers a single activity. For example, if a user goes
for a one-hour run, you can create an activity segment of type `running` (8) for the
entire hour. If a user runs for 25 minutes, takes a break for 5, then runs for another half an
hour, you can create three consecutive activity segments of types `running`,
`unknown`, and `running` respectively.

Creating an activity segment is the same as adding any other data point. To create activity
segments, first create an activity segment data source, then create a dataset and add
activity segment data points to it.

The following example creates three segments (running, resting, and running) in the same timeframes
as the heart rate readings, assuming you already created an activity segment
data source and the data source ID is "raw:com.google.activity.segment:1234567890:Example Fit:example-fit-hrm-1:123456":

HTTP method
:   PATCH

Resource
:   `https://www.googleapis.com/fitness/v1/users/me/dataSources/
    raw:com.google.activity.segment:1234567890/datasets/1411053997000000000-1411057556000000000`

Request body
:

    ```
    {
    "minStartTimeNs": 1411053997000000000,
    "maxEndTimeNs": 1411057556000000000,
    "dataSourceId":
      "raw:com.google.activity.segment:1234567890",
    "point": [
    {
      "startTimeNanos": 1411053997000000000,
      "endTimeNanos": 1411053997000000000,
      "dataTypeName": "com.google.activity.segment",
      "value": [
        {
          "intVal": 8
        }
      ]
    },
    {
      "startTimeNanos": 1411055000000000000,
      "endTimeNanos": 1411055000000000000,
      "dataTypeName": "com.google.activity.segment",
      "value": [
        {
          "intVal": 4
        }
      ]
    },
    {
      "startTimeNanos": 1411057556000000000,
      "endTimeNanos": 1411057556000000000,
      "dataTypeName": "com.google.activity.segment",
      "value": [
        {
          "intVal": 8
        }
      ]
    }
    ]
    }
    ```

These activity segment data points are added to a data source that has been created specifically
to handle activity segments. You could create a new data source for each set of segments, but
you should reuse one dedicated to a particular type of session, like running.

Sessions specify an activity type, which should match the overall activity the user is engaged in.
Even if a user takes a break while running, the overall workout is still a run. In general the
activity type for the session will match the dominant activity segment type.

Use the activity type *unknown* (4) to indicate that a user is resting, as you might not
know what the user is doing: they may be still, or stretching, drinking water, and so on. If you
know the user is not moving, you can use *still* (3).

For a detailed list of activity types, see [Activity Types](https://developers.google.com/fit/rest/v1/reference/activity-types).

## Summary

In this tutorial, you created data sources for data types and activity segments; you inserted
data points into the fitness store; you created activity segments to represent the different
activities taking place during a workout; and you inserted a session that covers the entire
workout.

Google Fit associates the data you inserted and any other data available for that time interval
with a session that represents the user's workout.