Terra Docs
Dashboard
  • Docs
  • API Reference
  • Changelog
  • Getting Started
    • What is Terra API?
    • Account setup and API keys
    • Core concepts
  • Health & Fitness API
    • Overview
    • Quickstart
    • Integration setup
      • Understanding sources and destinations
      • Setting up data sources
      • Setting up data destinations
        • Webhooks
        • SQL database (Postgres, MySQL)
        • Supabase
        • Cloud storage (S3, GCP)
        • Queuing services (SQS, Kafka)
      • Customising data types
      • Dedicated data source API keys
      • Understanding Terra environments
    • User authentication
      • Authentication flow
      • Implementation (Terra widget)
      • Implementation (Custom UI)
      • Handling authentication events
      • Customising authentication redirects
    • Managing user health data
      • Receiving health data updates (events)
      • Requesting historical health data (REST API requests)
      • Writing data
    • Mobile-only sources
      • iOS (Swift)
      • Android (Kotlin)
      • React Native
      • Flutter
    • Troubleshooting
    • Pricing
  • User Engagement
    • Health Scores
  • Streaming API
    • Overview
    • Wearable -> Your app
      • iOS (Swift)
      • Android
    • Your app -> Terra
      • iOS (Swift)
      • Android
    • Terra -> Your backend
  • Teams API
  • Biomarkers API - Upcoming
Powered by GitBook
On this page
  • Overview
  • 1. When to request historical data?
  • a. Upon creating a New User
  • b. As a "pull down to refresh" functionality
  • 2. Request Data via the Dashboard
  • 3. Request Data via the API
  • Request Usage
  • API Request Example (Python)
  • Request longer time ranges

Was this helpful?

  1. Health & Fitness API
  2. Managing user health data

Requesting historical health data (REST API requests)

Learn how to request for historical data to be sent to your destination through the REST API

PreviousReceiving health data updates (events)NextWriting data

Last updated 1 day ago

Was this helpful?

Overview

Terra API is event-based, meaning you don’t 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 ?

Prerequisites

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

  1. Obtain your Terra API Key and dev-id from your Terra Dashboard

  2. Set up a Data Destination where Terra will send event and data updates.

  3. Enable the specific data sources your app requires (e.g., activity, sleep).

  4. Connected at least a user. Requests are done using a user_id and at least a date.

    1. The must be connected via Terra's Health & Fitness API.

    2. The user_id is needed to make requests for historical data


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.

Time Range limits in Historical Data Requests

  • 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.

  • Health Connect: 30 days into the past, but not prior to the moment the user granted permission.

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.


3. Request Data via the API

Request Usage

1. Required Parameters:

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

  • user_id (required)

  • start_date (required)

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 toIntegration setup)

  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.

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.

API Request Example (Python)

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

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

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

Request longer time ranges

Following a large request, you will receive the following:

1. "Large Request Processing" Event

2. "Large Request Sending" Event

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 chunks 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.

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.

Some impose limits on how far back a developer can request data. Those are:

To request historical data from your Backend, you need to call one of the . Refer to the section for further details on usage.

Refer to the section for further details on usage.

You will immediately receive a event.

This indicates that Terra has acknowledged the large request and is currently processing the data retrieval from the .

Once data retrieval has finished, Terra will organise the data into chunks, and send a payload, indicating the number of payloads to expect.

providers
API Key & dev-id:
Data Retrieval Endpoints
Destination Configured:
Data Sources Enabled:
#large-request-processing
#large-request-sending
User
API endpoints
API endpoints
Provider