# Requesting historical health data (REST API requests)

## Overview

Terra API is **event-based**, meaning **you** ***don’t*****&#x20;need to manually request data via the API.**

For **new** and **ongoing** **data** **updates**, Terra API automatically sends them to your configured Data Destination (e.g. Webhook, Database, or cloud storage bucket).

If you need **historical** **user** **data**, you can request it using the **Health & Fitness API endpoints** by specifying the user ID, data type, and time range. This allows you to request past records on demand.

In this guide you will learn:

1. When are historical data requests useful?
2. How to use the **Terra Dashboard** to make a historical data request?
3. How to use the **Terra's Health & Fitness API** to make a historical data request?
4. Request Parameters (e.g. send to destination and include samples)
5. How to handle requests of very long time ranges ?

{% hint style="success" %}

### **Prerequisites**

In order to receive Data as Events, you'll need to:

1. [**API Key & dev-id**:](https://dashboard.tryterra.co/) Obtain your Terra API Key and dev-id from your Terra Dashboard
2. [**Destination Configured**:](/health-and-fitness-api/integration-setup.md#set-up-your-data-sources-and-destinations) Set up a Data Destination where Terra will send event and data updates.
3. [**Data Sources Enabled**:](/health-and-fitness-api/integration-setup.md#set-up-your-data-sources-and-destinations) Enable the specific data sources your app requires (e.g., activity, sleep).
4. **Connected at least a user. Requests are done using a** <mark style="color:orange;">`user_id`</mark> **and at least a date.**
   1. The [User](/reference/health-and-fitness-api/core-concepts.md#user) must be connected via Terra's Health & Fitness API.
   2. The <mark style="color:orange;">`user_id`</mark> is needed to make requests for historical data
      {% endhint %}

***

## 1. When to request historical data?

### a. Upon creating a New User

When an end user first connects an account (e.g. wearable, device, health app), you will by default only receive data from that point onwards.

If you would like to **build a historical health & fitness profile of the user,** to establish **baselines** for statistics, or for any other calculations, you can make a request to Terra for data from prior to the user's authentication.

{% hint style="info" %}
**Time Range limits in Historical Data Requests**

Some [providers](https://github.com/tryterra/gitbook-docs/blob/master/health-and-fitness-api/broken-reference/README.md) impose limits on how far back a developer can request data. Those are:

* **Garmin**: 5 years into the past, from the current point in time. This is subject to Garmin's backfill limits.
* **Polar**: 30 days into the past, but not prior to the moment the user granted permission.
* **Coros:** 3 months into the past, from the current point in time, or 24 hours prior to the user's authentication. Whichever of the two limits gets hit first gets applied
* **Health Connect**: 30 days into the past, but not prior to the moment the user granted permission.
  {% endhint %}

### b. As a "pull down to refresh" functionality

As a **fallback**, you should implement a "pull down to refresh" functionality or alternative (like a sync now button, etc...).

Hitting this button should trigger a data pull of the last e.g. 14 days of data for the user, for all the data types you ingest.

***

## 2. Request Data via the Dashboard

You may want your customer support team to use the Terra dashboard to debug by re-sending data, or verifying whether or not Terra fetches the data correctly. See the guide below for a step by step tutorial on how to do so.

{% embed url="<https://app.guideflow.com/player/dr96elwaor>" %}

***

## 3. Request Data via the API

To request historical data from your **Backend,** you need to call one of the [Data Retrieval Endpoints](https://docs.tryterra.co/reference#historical-data-retrieval). Refer to the [API endpoints](/reference/health-and-fitness-api/readme.md) section for further details on usage.

### Request Usage

Refer to the [API endpoints](/reference/health-and-fitness-api/readme.md) section for further details on usage.

#### **1. Required Parameters:**

To request historical data, the following request parameters are required:

* <mark style="color:orange;">`user_id`</mark> <mark style="color:orange;">(required)</mark>
* <mark style="color:green;">`start_date`</mark> <mark style="color:green;">(required)</mark>

#### **2. Optional Parameters**

Terra's Data Retrieval endpoints include many other useful and important parameters.

1. `with_samples` must be set to `true` to receive granular data (refer to[Integration setup](/health-and-fitness-api/integration-setup.md))
2. `to_webhook` must be set to `true` if you want to receive data asynchronously to your Destination. For synchronous data retrieval (if your use case is time-sensitive), just set this parameter to `false`.

{% hint style="info" %}

#### **to\_webhook** will always be defaulted to `true` if not provided

{% endhint %}

{% hint style="warning" %}
**Handling Asynchronous Data Retrievals**

* When making a `to_webhook=true` request, keep track of the value of the `terra-reference` header.
* When the event is eventually sent to your Data Destination, the event's `terra-signature` will match that of the initial request, allowing you to mark off the data transfer as successfully completed.
  {% endhint %}

### API Request Example (Python)

Taking **Python FastAPI** as an example framework, you may set up your server code to look like the following:

{% code title="Python" lineNumbers="true" %}

```python
@app.post("/webhook")
async def webhook_handler(request: Request):
    payload = await request.json()
    
    if payload.get("type") == "auth" and payload.get("status") == "success":
        # Calculate date range, to get data from 28 days ago to today
        start_date = (datetime.utcnow() - timedelta(days=28)).strftime('%Y-%m-%d')
        end_date = (datetime.utcnow() + timedelta(days=1)).strftime('%Y-%m-%d')
        headers = {
            "x-api-key": os.getenv("TERRA_API_KEY"), 
            "dev-id": os.getenv("TERRA_DEVELOPER_ID")
        }
        endpoints = [
            "/activity", 
            "/daily", 
            "/sleep", 
            "/body"
        ]

        # Fetch data from each endpoint
        results = {}
        for endpoint in endpoints:
            try:
                response = requests.get(
                    f"{TERRA_API_URL}{endpoint}", 
                    headers=headers, 
                    params={
                        "start_date": start_date, 
                        "end_date": end_date,
                        "to_webhook": True
                        }
                    )
                response.raise_for_status()
                results[endpoint] = response.json()
            except requests.HTTPError as e:
                raise HTTPException(status_code=response.status_code, detail=f"Error fetching data from {endpoint}")

        return {"message": "Data fetched successfully", "data": results}
    
    return {"message": "Webhook type or status did not match criteria"}
```

{% endcode %}

{% hint style="info" %}
**Handling asynchronous data retrievals**

When making a `to_webhook=true` request, keep track of the value of the `terra-reference` header. When the event is eventually sent to your webhook, the event's `terra-reference` will match that of the initial request, allowing you to mark off the data transfer as successfully completed
{% endhint %}

### Request longer time ranges

Following a large request, you will receive the following:

#### **1. "Large Request Processing" Event**

You will immediately receive a [Event Types](/reference/health-and-fitness-api/event-types.md#large-request-processing) event.

This indicates that Terra has acknowledged the large request and is currently processing the data retrieval from the [Provider](/reference/health-and-fitness-api/core-concepts.md#provider).

#### **2. "Large Request Sending" Event**

Once data retrieval has finished, Terra will organise the data into <mark style="color:orange;">**chunks**</mark>, and send a [Event Types](/reference/health-and-fitness-api/event-types.md#large-request-sending) payload, indicating **the number of payloads to expect.**

#### **3. Chunks**

When a large request is made, Terra will send the data to you in chunks of:

* at most 10MB
* at most 10 objects in the `data` array

The chunk size will be limited by whichever of the two limits gets hit first.

#### **4. Header**

**ALL** <mark style="color:orange;">**chunks**</mark> will contain the **same** `terra-reference` header value.

Once the number of payloads indicated with the same `terra-reference` header value have been received, you can consider the data transfer request complete.

{% hint style="info" %}

### Requests with >28 days Time Ranges

For time ranges longer than 28 days, Terra will default to sending the data **asynchronously, even if `to_webhook` is set to `false`**.

This is due to the large amounts of data being transferred, which would hang the request making/handling process for >30 seconds.
{% endhint %}


---

# 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/health-and-fitness-api/managing-user-health-data/requesting-historical-data.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.
