Skip to main content

Data Flow

Historical Data Flow

When a user first connects a device to Vital, Vital backend pulls historical data. Historical data is all data that exists on a user's account, prior to them linking their wearable account with Vital. This can take several minutes for all the data to be retrieved and to be readily accessible.

When data is available, the backend triggers a historical.data.<resource_type>.created webhook event. The resource_type is determined by the provider - more information on which resources a provider can support can be found here.

We send a webhook event for each resource a provider supports. In certain cases, where a user has large amounts of historical data, we send webhook events for each ordered-chunk (most-recent first). The is_final flag is used to indicate that the data collection is complete.

Webhook Event
1
2
3
4
5
6
7
8
9
10
{
  "event_type": "historical.data.workouts.created",
  "data": {
    "user_id": "e9e072e8-...",
    "start_date": "2020-06-21T08:23:01+00:00",
    "end_date": "1996-11-02T14:39:28+00:00",
    "is_final": true,
    "provider": "zwift"
  }
}

When you receive the historical backfill event, you should make an API call for the specific resource you received the webhook event for. As an example, if you receive the event historical.data.workouts.created you should make a call to GET workout data from the API. Historical data can be quite big, so we don't send the full payload in a webhook.

Daily Data Flow

After a user has connected and historical data is backfilled, any new data is sent in the payload of the daily.data.<resource_type>.created webhook. Each payload has an id associated with it, and we recommend storing this value. This is to support cases where data may be updated. If an instance of previously sent data is changed by the user, we issue a daily.data.<resource_type>.updated event. For example, the title of a workout can be edited, or the amount of calories a user has burnt can change throughout the day.

Examples of each payload are provided in the webhooks dashboard. You can send test events which contain the different payloads you may receive throughout the integrations lifecyle.

Webhook Event
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
  "event_type": "daily.data.workouts.created",
  "data": {
    "id": "c90bd6fb-...",
    "average_hr": 198,
    "distance": 8544,
    "time_start": "2012-11-24T22:57:01+00:00",
    "time_end": "2017-04-22T04:57:31+00:00",
    "calories": 4470,
    "hr_zones": [
      8279
    ],
    "user_id": "ab3247dc-...",
    "moving_time": 4719,
    "total_elevation_gain": 8967,
    "elev_high": 3868,
    "max_speed": 8371,
    "average_watts": 9029,
    "max_watts": 1551,
    "provider_id": "dolor ipsum reiciendis Lorem veniam elit. esse",
    "source": {
      "name": "Zwift",
      "slug": "zwift",
      "logo": "https://logo.png"
    }
  }
}

Connection Created

Once a connection between a provider and a user is established, we will send a webhook confirming it.

Webhook Event
1
2
3
4
5
6
7
8
9
10
11
{
 "event_type": "provider.connection.created",
 "data": {
  "user_id": "4eca10f9-...",
  "source": {
   "source_name": "Strava",
   "source_slug": "strava",
   "source_logo": "https://storage.googleapis.com/vital-assets/strava.png"
  }
 }
}

Deep Dive into Vital Webhooks

Webhook Events

All our webhook events have the following structure. Each event consists of an event_type followed by a payload under the data key. The event_type specifies the type of data that is sent. You can see examples in the dashboard under Svix. You can also send example data via the Svix dashboard, under example events.

Webhook Event
1
2
3
4
{
 "event_type": "daily.data.glucose.created",
 "data": "...event_specific_data"
}