Terra: one API for 500+ wearables and health data sources
Terra turns Fitbit, Garmin, Oura and Strava data into one normalized API with SDKs for Python, TypeScript, iOS, Android and Flutter.
TL;DR: Terra exposes Fitbit, Garmin, Oura, Strava and dozens of other wearable services through one normalized REST API, so your app reads sleep, workouts and body metrics the same way no matter which device a user owns. Generated Python and TypeScript clients ship alongside mobile SDKs for iOS, Android, React Native and Flutter. Paid plans start at $499 a month and are metered in credits.
What it is
Terra is a YC W21 company that started out as an API for putting wearables in apps. The product now sits in front of a long list of providers: Oura, Fitbit, Garmin, Polar, COROS, WHOOP, Strava, Zwift, Withings, Google Fit and others. You authenticate a user once against Terra, then read their data through the same endpoints regardless of which device they wear.
Every payload comes back normalized. A Garmin sleep record and an Oura sleep record are both results from client.sleep.fetch(...) with the same fields, so a chart in your app does not care where the data came from. That normalization is the product itself. The provider integrations are just the plumbing behind it.
The company also sells past wearables now: lab reports, DNA tests, health scores, rewards, and an AI interface for building models on the same feed. The site claims 500+ wearables, sensors and blood testing providers. The public integrations endpoint I called returns 80 provider identifiers, so read 500+ as the wider catalog covering lab partners and destinations, not a count of wearable vendors.
Why it matters
Building health features directly against vendors is a treadmill. Fitbit alone wants its own OAuth app, its own rate limits and its own response format, and Garmin, Oura and Strava each want another. Every provider needs client-secret handling, token refresh and a mapping from its field names to yours. Then you test against all of them.
Terra turns that into one partner relationship with the vendors and an OAuth flow you implement once. The authenticateUser call returns a URL your user visits to link their own account, and after that the data arrives normalized, on demand or as a webhook. A health app can ship with Garmin and Oura support without writing two provider clients.
Getting it running
The Python client is generated with Fern and published as terra-python.
pip install terra-python
from terra import Terra
client = Terra(
dev_id="YOUR_DEV_ID",
api_key="YOUR_API_KEY",
)
integrations = client.integrations.fetch()
Linking a user’s own account is one call. The resource argument names the provider, and reference_id ties the result back to your own user record.
client.authentication.authenticateuser(
resource="FITBIT",
reference_id="user_1234",
)
The TypeScript client is published as terra-api on npm and follows the same shape.
import { TerraClient } from "terra-api";
const client = new TerraClient({ apiKey: "YOUR_API_KEY", devId: "YOUR_DEV_ID" });
await client.integrations.fetch();
Under the hood both clients hit https://api.tryterra.co/v2 with two headers, dev-id and x-api-key, so a plain curl works as well.
curl -H "dev-id: $TERRA_DEV_ID" \
-H "x-api-key: $TERRA_API_KEY" \
https://api.tryterra.co/v2/integrations
Health data lives in resources separate from the auth calls, and every one of them has a fetch method:
activityandplannedworkoutfor workouts and sessionssleepfor sleep recordsbodyfor weight and body compositiondailyfor daily summariesnutritionfor calories and intakemenstruationfor cycle dataathletefor athlete-level metricsuserfor account state and identifiers
activity, body, nutrition and plannedworkout also accept write and delete, so Terra can push data back to a provider rather than only reading from it.
Most of this traffic lands on a phone, and the mobile SDKs live in their own repositories with their own release cadence.
| SDK | Repository | License | Last push |
|---|---|---|---|
| iOS | tryterra/TerraiOS | MIT | 2026-10-13 |
| React Native | tryterra/terra-react | MIT | 2026-10-22 |
| Flutter | tryterra/terra-flutter | BSD-3-Clause | 2026-10-21 |
| Android | tryterra/TerraAndroid | none listed | 2023-04-18 |
Pricing
Two public tiers, and the unit is credits rather than requests.
| Plan | Price | Included |
|---|---|---|
| Quick Start | from $499/month | 100,000 credits, unlimited integrations and destinations, mobile SDK, connection widget |
| Enterprise | custom | 24/7 engineering support, custom integrations and destinations, MSAs and SLAs, signed BAA, dedicated server |
Both tiers carry a 30-day money-back guarantee. Real-time streaming is an add-on on Quick Start rather than part of the base plan.
What to watch for
Credits are the number to model carefully before you commit to a polling interval. A “request” is not the same thing across providers, so your bill depends on how many users sync and how often, not on how many screens you build.
The license picture is uneven. The three actively maintained mobile SDKs carry MIT or BSD-3-Clause, while the generated terra-client-python and terra-client-js repositories have no LICENSE file at all. The Python package is at version 1.1.0 on PyPI and requires Python 3.8 or newer.
Two smaller things. TerraAndroid has had no commit since April 2023, so the maintained Android route is the React Native SDK rather than the native one. And because the whole catalog is health data, consent, retention and BAA terms become part of your contract rather than a checkbox you tick.
Source and Accuracy Notes
- Project page: https://tryterra.co, verified by direct visit on 2026-10-22
- API reference: https://docs.tryterra.co/reference, with endpoint paths, auth headers and the base URL read from the generated clients
- Source repositories:
tryterra/terra-client-python,tryterra/terra-client-js,tryterra/TerraiOS,tryterra/terra-react,tryterra/terra-flutter,tryterra/TerraAndroid - Licenses: MIT for the iOS and React Native SDKs, BSD-3-Clause for Flutter; the Python and TypeScript client repositories have no LICENSE file
- Provider count: 80 identifiers returned by a live GET against
https://api.tryterra.co/v2/integrations - HN launch thread: https://news.ycombinator.com/item?id=29118517, Launch HN on 2021-11-05
Related Posts
ai-setup
Recall – Persistent Memory for Claude Code via MCP Hooks
Recall gives Claude Code a permanent memory store that survives session restarts and context compaction. Four hooks capture and restore context automatically — with cloud SaaS or self-hosted options.
2/28/2026
dev-tools
Automotive Skills Suite for AI Engineering
Evaluate Automotive Skills Suite for APQP, ASPICE, HARA, safety-plan, and DIA workflows with setup notes, governance risks, and SME review guidance.
5/28/2026
dev-tools
awesome-agentic-ai-zh Roadmap Guide
Explore awesome-agentic-ai-zh as a Chinese agentic AI learning roadmap, with setup notes, track selection, study workflow, and evaluation guidance.
5/28/2026