Event Types

Every request made to Terra, and every event sent from Terra will contain a terra-reference header containing a unique identifier for the request or event.

The terra-reference identifier uniquely ties together a request -> event pair, whenever a request for data leads to data being asynchronously sent to your server. This can be useful for keeping track of whether or not a data transfer request has been fulfilled, or is still pending transfer

Type
Explanation

auth

Occurs when a user attempts to authenticate

deauth

Occurs when a user deauthenticates through the Terra

user_reauth

Occurs when a user successfully authenticates for a second time, with the same account. You will receive a successful auth and a user_reauth payload

access_revoked

Occurs when a user revokes Terra's access from the provider's end

connection_error

Occurs when a request to a provider returns an HTTP response of 401, 403 or 412

google_no_datasource

Occurs when a Google Fit user doesn't have a data source linked to their account. All data requests for the user will be empty unless they link a data source

processing

Occurs when data is being fetched asynchronously from the provider. The data will be sent through automatically via your Destination, and you can also safely request for it after the time in the retry_after_seconds field.

large_request_sending

Occurs when more than one month of data has been requested and all data has been successfully submitted

rate_limit_hit

Occurs when an asynchronous request has failed due to rate limiting and is going to be retried.

large_request_processing

Occurs when more a request for over one month of data has been submitted to Terra. Data will be sent in chunks with the same reference field after this request. Each chunk will be at most 10 objects in the data field or 10 MB in size, whichever limit gets hit first

activity, athlete, body, daily, menstruation, nutrition, sleep

Occurs throughout the day as users use their wearables. activity updates when new activity is completed

healthcheck

Healthcheck event sent periodically to verify your event is functional

Misc

Healthcheck

Slug:

healthcheck

Trigger:

This will periodically be sent to your destination to confirm its health status

Recommended action:

N/A

Format:

{
  "type": "healthcheck",
  "status": String,
  "creation_timestamp": String,
  "trend_percentage": Number,
  "sent_webhooks_last_hour": Number
}

Authentication

Device account connection success/failure

Slug:

auth

Trigger:

A user just finished going through connecting a device account to your app

Recommended action:

If status = success, save the user to your database. Use the reference_id parameter to link this back to an end user profile in your app.

If status = error, do nothing and treat this as an informational event

Format:

{
  "type": "auth",
  "user": User,
  "status": "success",
  "reference_id": String,
  "widget_session_id": String
}
{
  "type": "auth",
  "user": User,
  "provider": "GARMIN"
  },
  "status": "error",
  "message": "User failed to authenticate and has been deleted",
  "reason": String,
  "reference_id": String,
  "widget_session_id": String
}
Device account disconnection/deauthentication

Slug:

deauth

Trigger:

A user just disconnected their device account from your app

Recommended action:

Remove the user from your database using the user_id field and remove all their data records according to your data retention policy.

Format:

{
  "type": "deauth",
  "user": User,
  "status": "success",
  "message": "User has deauthenticated"
}
Device account re-authentication

Slug:

user_reauth

Trigger:

A user just connected a wearable account to your app which was previously already linked to you.

Recommended action:

Remove the old_user record from your database using the user_id field

Replace all references of the user_id from old_user with the user_id from new_user

Format:

{
  "type": "user_reauth",
  "new_user": User,
  "old_user": User,
  "status": "warning",
  "message": "User has reauthenticated and old ID has been deleted"
}
User access revoked

Slug:

access_revoked

Trigger:

A user revoked access to data access for your app through their wearable app's settings

Recommended action:

Remove the user from your database and remove all their data records according to your data retention policy.

Format:

{
  "type": "access_revoked",
  "user": User,
  "status": "warning",
  "message": "User revoked access"
}
User data connection error

Slug:

connection_error

Trigger:

A user potentially revoked access to data access for your app through their wearable app's settings, or modified their credentials in a way which invalidated the tokens for data access.

Unlike User access revoked, Terra cannot determine for sure that this was due to the user explicitly removing access for your app, or that this isn't a temporary connection error.

Recommended action:

Remove the user from your database, and ask the user to re-connect their device. You may need remove all their data records according to your data retention policy.

Format:

{
  "type": "connection_error",
  "user": User,
  "status": "warning",
  "message": "User connection degraded"
}
No datasource available

Slug:

google_no_datasource

Trigger:

A user was just created, but has no data sources associated with their account.

Recommended action:

Inform the user they do not have any data sources associated with their Google Fit account, and you may not receive data for them as a result. Keep a log of this for future reference (e.g. if the end user logs a support ticket regarding this)

Format:

{
  "type": "connection_error",
  "user": User,
  "status": "warning",
  "message": "User connection degraded"
}
Permission change

Slug:

permission_change

Trigger:

A user has authenticated a second time, potentially on a separate dev ID, and modified the permissions granted to Terra

Recommended action:

Log this as an informational bit of data, which would help understand why some data type(s) are no longer provided down the line.

Format:

{
"type": "permission_change",
"user": User,
"status": "warning",
"message": "User permissions have been modified",
"version": "2022-03-16",
"scopes_added": "fitness.blood_glucose.read",
"scopes_removed": "fitness.oxygen_saturation.read"
}

Data requests

Request processing

Slug:

google_no_datasource

Trigger:

Terra needs to fetch data asynchronously from the data provider. This is an HTTP-only event (only returned as an HTTP response, and never sent as an event to your destination)

Recommended action:

  • Await for the data to arrive in your destination

  • Request for it after (at worst) the time allotted in the retry_after_seconds field.

Format:

{
  "type": "processing",
  "status": "success",
  "message": "Request is processing, try again later",
  "user": TerraUser,
  "retry_after_seconds": Number,
}
Large request processing

Slug:

large_request_processing

Trigger:

A large request has been submitted to Terra, and is being processed. A large_request_sending event will follow

Recommended action:

Await for data chunks to be sent. Use the terra_reference to keep track of any events tied back to the initial request.

The terra_reference will match the one in the response to the initial HTTP request.

Format:

{
  "type": "large_request_processing",
  "status": "processing",
  "message": "Large request is processing",
  "user": TerraUser,
  "reference": String
}
Large request sending

Slug:

large_request_sending

Trigger:

A large request has been submitted to Terra, and data pertaining to it is about to be sent. Data chunks will be sent to your destination following this event, all with the same terra_reference header

Recommended action:

Await for data chunks to be sent. Use the terra_reference header or reference field to tie those back to the initial request. The reference will match the terra-reference header in the response to the initial HTTP request.

You may keep track of the sync progress using the expected_payloads field, which indicates how many data events will follow

Format:

{
  "user": User,
  "reference": String,
  "message": "Large request is being sent",
  "expected_payloads": Number,
  "type": "large_request_sending",
}
Rate limit hit

Slug:

rate_limit_hit

Trigger:

Rate limits for the data provider were hit during an asynchronous request. Terra will reschedule the request for a later time

Recommended action:

Keep a log of this occurrence

Format:

{
  "user": User,
  "start_date": DateTime,  
  "end_date": DateTime,
  "retrying_at": DateTime,
  "message": "Rate limit reached whilst processing async query",
  "type": "rate_limit_hit",
}

Data events

Activity

Slug:

activity

Trigger:

New activity records are available for the user account

Recommended action:

Save the data in your database, and overwrite previous records based off the metadata.summary_id entry

Format:

{
  "data": [Activity],
  "user": User,
  "type": "activity",
  "version": String
}
Athlete

Slug:

athlete

Trigger:

New data is available for the user account

Recommended action:

Save the data in your database

Format:

{
  "athlete": Athlete,
  "user": User,
  "type": "athlete",
  "version": String
}
Body

Slug:

body

Trigger:

New body data is available for the user account

Recommended action:

Save the data in your database, and overwrite previous records based off the metadata.start_time entry

Format:

{
  "data": [Body],
  "user": User,
  "type": "body",
  "version": String
}
Daily

Slug:

daily

Trigger:

New daily activity summary data is available for the user account

Recommended action:

Save the data in your database, and overwrite previous records based off the metadata.start_time entry

Format:

{
  "data": [Daily],
  "user": User,
  "type": "daily",
  "version": String
}
Menstruation

Slug:

menstruation

Trigger:

New menstruation data is available for the user account

Recommended action:

Save the data in your database, and overwrite previous records based off the metadata.start_time entry

Format:

{
  "data": [Menstruation],
  "user": User,
  "type": "menstruation",
  "version": String
}
Nutrition

Slug:

nutrition

Trigger:

New nutrition records are available for the user account

Recommended action:

Save the data in your database, and overwrite previous records based off the metadata.start_time entry

Format:

{
  "data": [Nutrition],
  "user": User,
  "type": "nutrition",
  "version": String
}
Sleep

Slug:

sleep

Trigger:

New sleep records are available for the user account

Recommended action:

Save the data in your database, and overwrite previous records based off the metadata.summary_id entry

Format:

{
  "data": [Sleep],
  "user": User,
  "type": "sleep",
  "version": String
}

Was this helpful?