# Event Types

{% hint style="info" %}
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
{% endhint %}

| 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 authenticates a provider that is already connected under the same `reference_id` and `dev_id`. The old connection is deleted and a new `user_id` is issued. You will receive both 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](https://docs.tryterra.co/reference/core-concepts#destinations), 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                                                                                                                                                                                                                           |
| `s3_upload`                                                                  | Data event sent as a download link.                                                                                                                                                                                                                                                              |

## Misc

<details>

<summary>Healthcheck</summary>

**Slug:**

`healthcheck`

**Trigger:**

This will periodically be sent to your [destination](https://docs.tryterra.co/reference/core-concepts#destinations) to confirm its health status

**Recommended action:**

**N/A**

**Format:**

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

</details>

## Authentication

<details>

<summary>Device account connection success</summary>

**Slug:**

`auth`

**Trigger:**

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

**Recommended action:**

Save the [user](https://docs.tryterra.co/reference/core-concepts#user) to your database. Use the `reference_id` parameter to link this back to an [end user](https://docs.tryterra.co/reference/core-concepts#end-user) profile in your app.

**Format:**

```json
{
  "type": "auth",
  "user": User,
  "status": "success",
  "reference_id": String,
  "widget_session_id": String
}
```

</details>

<details>

<summary>Device account disconnection/deauthentication</summary>

**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"
}
```

</details>

<details>

<summary>Device account re-authentication</summary>

**Slug:**

`user_reauth`

**Trigger:**

A user authenticated a provider that was already connected under the same `reference_id` and `dev_id`. The previous connection is deleted and replaced with a new `user_id`. This is per-provider — re-authenticating one provider does not affect connections to other providers under the same `reference_id`.

**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:**

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

</details>

<details>

<summary>User access revoked</summary>

**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:**

```json
{
  "type": "access_revoked",
  "user": User,
  "status": "warning",
  "message": "User revoked access"
}
```

</details>

<details>

<summary>User data connection error</summary>

**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](#user-access-revoked "mention"), 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:**

```json
{
  "type": "connection_error",
  "user": User,
  "status": "warning",
  "message": "User connection degraded"
}
```

</details>

<details>

<summary>No datasource available</summary>

**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](https://docs.tryterra.co/reference/core-concepts#end-user) logs a support ticket regarding this)

**Format:**

```json
{
  "type": "connection_error",
  "user": User,
  "status": "warning",
  "message": "User connection degraded"
}
```

</details>

<details>

<summary>Permission change</summary>

**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:**

```json
{
"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"
}
```

</details>

## Data requests

<details>

<summary>Request processing</summary>

**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](https://docs.tryterra.co/reference/core-concepts#event) to your [destination](https://docs.tryterra.co/reference/core-concepts#destinations))

**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:**

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

</details>

<details>

<summary>Large request processing</summary>

**Slug:**

`large_request_processing`

**Trigger:**

A [large request](https://docs.tryterra.co/reference/core-concepts#large-request) has been submitted to Terra, and is being processed. A [`large_request_sending`](#large-request-sending) [event](https://docs.tryterra.co/reference/core-concepts#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:**

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

</details>

<details>

<summary>Large request sending</summary>

**Slug:**

`large_request_sending`

**Trigger:**

A [large request](https://docs.tryterra.co/reference/core-concepts#large-request) has been submitted to Terra, and data pertaining to it is about to be sent. [Data chunks](#data-types) will be sent to your [destination](https://docs.tryterra.co/reference/core-concepts#destinations) following this [event](https://docs.tryterra.co/reference/core-concepts#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](#data-events) will follow

**Format:**

```json
{
  "user": User,
  "reference": String,
  "message": "Large request is being sent",
  "expected_payloads": Number,
  "type": "large_request_sending",
}
```

</details>

<details>

<summary>Rate limit hit</summary>

**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:**

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

</details>

## Data events

<details>

<summary>Activity</summary>

**Slug:**

`activity`

**Trigger:**

New activity records are available for the [user](https://docs.tryterra.co/reference/core-concepts#user) account

**Recommended action:**

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

**Format:**

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

</details>

<details>

<summary>Athlete</summary>

**Slug:**

`athlete`

**Trigger:**

New data is available for the [user](https://docs.tryterra.co/reference/core-concepts#user) account

**Recommended action:**

Save the data in your database

**Format:**

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

</details>

<details>

<summary>Body</summary>

**Slug:**

`body`

**Trigger:**

New body data is available for the [user](https://docs.tryterra.co/reference/core-concepts#user) account

**Recommended action:**

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

**Format:**

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

</details>

<details>

<summary>Daily</summary>

**Slug:**

`daily`

**Trigger:**

New daily activity summary data is available for the [user](https://docs.tryterra.co/reference/core-concepts#user) account

**Recommended action:**

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

**Format:**

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

</details>

<details>

<summary>Menstruation</summary>

**Slug:**

`menstruation`

**Trigger:**

New menstruation data is available for the [user](https://docs.tryterra.co/reference/core-concepts#user) account

**Recommended action:**

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

**Format:**

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

</details>

<details>

<summary>Nutrition</summary>

**Slug:**

`nutrition`

**Trigger:**

New nutrition records are available for the [user](https://docs.tryterra.co/reference/core-concepts#user) account

**Recommended action:**

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

**Format:**

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

</details>

<details>

<summary>Sleep</summary>

**Slug:**

`sleep`

**Trigger:**

New sleep records are available for the [user](https://docs.tryterra.co/reference/core-concepts#user) account

**Recommended action:**

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

**Format:**

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

</details>

<details>

<summary>S3 Upload</summary>

**Slug:**

`s3_payload`

**Trigger:**

New data (activity/daily/body/sleep/nutrition/menstruation) records are available for the [user](https://docs.tryterra.co/reference/core-concepts#user) account

**Recommended action:**

Make a request to the `url` provided, and handle the resulting payload as you would one of the above [#data-events](#data-events "mention")

(i.e. save the data in your database, and overwrite previous records based off the `metadata.summary_id` /`metadata.start_time` entry)

**Format:**

```json
{
    "status": "success",
    "type": "s3_payload",
    "url": "https://example.com",
    "expires_in": 300,
}
```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tryterra.co/reference/health-and-fitness-api/event-types.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
