terra-sdk
SKILL.md
Terra SDK Integration
Complete SDK reference for Terra API integration across all platforms.
SDK Overview
| SDK | Platform | Package | Use Case |
|---|---|---|---|
| Python | Backend | terra-python |
Server-side API calls |
| JavaScript | Backend/Node | terra-api |
Node.js, Deno, Bun |
| iOS | Mobile | TerraiOS |
Apple Health integration |
| Android | Mobile | terra-android |
Samsung Health, Health Connect |
| React Native | Mobile | terra-react |
Cross-platform mobile |
| Flutter | Mobile | terra_flutter |
Cross-platform mobile |
Python SDK
Installation
pip install terra-python
Setup
from terra import Terra, AsyncTerra
# Synchronous client
client = Terra(
dev_id="botaniqalmedtech-testing-SjyfjtG33s",
api_key="_W7Pm-kAaIf1GA_Se21NnzCaFZjg3Izc"
)
# Async client
async_client = AsyncTerra(
dev_id="botaniqalmedtech-testing-SjyfjtG33s",
api_key="_W7Pm-kAaIf1GA_Se21NnzCaFZjg3Izc"
)
Configuration Options
from terra import Terra
client = Terra(
dev_id="...",
api_key="...",
timeout=60.0, # Request timeout in seconds
max_retries=2, # Automatic retries (default: 2)
)
Complete Method Reference
# Authentication
client.authentication.generatewidgetsession(reference_id=..., auth_success_redirect_url=..., ...)
client.authentication.generateauthtoken() # No params, generates for account
client.authentication.authenticateuser(resource=..., reference_id=...)
client.authentication.deauthenticateuser(user_id=...)
# User Management
client.user.getinfoforuserid(user_id=None, reference_id=None) # Get single user
client.user.getalluserids(page=None, per_page=None) # List all connected users
client.user.getinfoformultipleuserids(user_ids=...) # Bulk user info
client.user.modifyuser(user_id=..., ...) # Update user
# Data Retrieval (use .fetch() method)
client.activity.fetch(user_id=..., start_date=..., end_date=..., to_webhook=False)
client.sleep.fetch(user_id=..., start_date=..., end_date=..., to_webhook=False)
client.daily.fetch(user_id=..., start_date=..., end_date=..., to_webhook=False)
client.body.fetch(user_id=..., start_date=..., end_date=..., to_webhook=False)
client.nutrition.fetch(user_id=..., start_date=..., end_date=..., to_webhook=False)
client.menstruation.fetch(user_id=..., start_date=..., end_date=..., to_webhook=False)
client.athlete.fetch(user_id=...)
# Integrations
client.integrations.fetch() # Basic list
client.integrations.detailedfetch() # With detailed info
# Data Writing (limited providers)
client.activity.write(user_id=..., data=...)
client.nutrition.write(user_id=..., data=...)
client.body.write(user_id=..., data=...)
Async Usage
import asyncio
from terra import AsyncTerra
async def main():
client = AsyncTerra(dev_id="...", api_key="...")
# Concurrent requests
activity, sleep, daily = await asyncio.gather(
client.activity.get(user_id, start, end),
client.sleep.get(user_id, start, end),
client.daily.get(user_id, start, end)
)
return activity.data, sleep.data, daily.data
asyncio.run(main())
Error Handling
from terra import Terra
from terra.core.api_error import ApiError
client = Terra(dev_id="...", api_key="...")
try:
data = client.activity.get(user_id="invalid", start_date=start, end_date=end)
except ApiError as e:
print(f"Status: {e.status_code}")
print(f"Message: {e.message}")
print(f"Body: {e.body}")
JavaScript/Node.js SDK
Installation
npm install terra-api
# or
yarn add terra-api
Setup
import { TerraClient } from "terra-api";
const client = new TerraClient({
apiKey: "_W7Pm-kAaIf1GA_Se21NnzCaFZjg3Izc",
devId: "botaniqalmedtech-testing-SjyfjtG33s"
});
TypeScript Support
import { TerraClient, TerraError } from "terra-api";
const client = new TerraClient({
apiKey: string,
devId: string,
timeout?: number,
maxRetries?: number
});
Complete Method Reference
// Authentication
await client.authentication.generateWidgetSession({ referenceId, authSuccessRedirectUrl, ... });
await client.authentication.generateAuthToken({ referenceId });
await client.authentication.authenticateUser({ resource, referenceId });
await client.authentication.deauthenticateUser({ userId });
// User Management
await client.user.getUser({ userId });
await client.user.getSubscriptions();
// Data Retrieval
await client.activity.get({ userId, startDate, endDate, toWebhook });
await client.sleep.get({ userId, startDate, endDate, toWebhook });
await client.daily.get({ userId, startDate, endDate, toWebhook });
await client.body.get({ userId, startDate, endDate, toWebhook });
await client.nutrition.get({ userId, startDate, endDate, toWebhook });
// Integrations
await client.integrations.fetch();
Error Handling
import { TerraClient, TerraError } from "terra-api";
try {
const data = await client.activity.get({ userId: "...", startDate, endDate });
} catch (error) {
if (error instanceof TerraError) {
console.log(error.statusCode);
console.log(error.message);
console.log(error.body);
}
}
Abort Requests
const controller = new AbortController();
const promise = client.activity.get(
{ userId, startDate, endDate },
{ abortSignal: controller.signal }
);
// Cancel if needed
controller.abort();
iOS SDK (Swift)
Installation
Swift Package Manager:
https://github.com/tryterra/TerraiOS
CocoaPods:
pod 'TerraiOS'
Setup
import TerraiOS
class HealthManager {
func initialize() {
Terra.initTerra(
devId: "botaniqalmedtech-testing-SjyfjtG33s",
referenceId: getCurrentUserId()
)
}
func connectAppleHealth(token: String) {
Terra.initConnection(
type: Connections.APPLE_HEALTH,
token: token,
schedulerOn: true // Enable background sync
) { success, error in
if success {
print("Connected to Apple Health!")
} else {
print("Connection failed: \(error?.localizedDescription ?? "Unknown")")
}
}
}
}
Reading Data
import TerraiOS
// Get activity data
Terra.getActivity(
startDate: Calendar.current.date(byAdding: .day, value: -7, to: Date())!,
endDate: Date()
) { success, data, error in
if success, let activities = data {
for activity in activities {
print("Activity: \(activity.metadata.type)")
print("Calories: \(activity.calories_data.total_burned_calories)")
}
}
}
// Get sleep data
Terra.getSleep(startDate: startDate, endDate: endDate) { success, data, error in
// Handle sleep data
}
// Get daily data
Terra.getDaily(startDate: startDate, endDate: endDate) { success, data, error in
// Handle daily summaries
}
Writing Data (Apple Health)
// Post activity
Terra.postActivity(data: activityData) { success, error in
if success {
print("Activity posted to Apple Health")
}
}
// Post planned workout (appears in Workout app)
let workout = PlannedWorkout(
name: "Morning Run",
type: "running",
phases: [
WorkoutPhase(type: "warmup", duration: 300),
WorkoutPhase(type: "active", duration: 1800),
WorkoutPhase(type: "cooldown", duration: 300)
]
)
Terra.postPlannedWorkout(data: workout) { success, error in
// Workout now available on Apple Watch
}
Background Delivery
// Enable background delivery in AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions...) {
Terra.setUpBackgroundDelivery()
}
// Data syncs automatically in background when schedulerOn: true
Android SDK (Kotlin)
Installation
build.gradle:
dependencies {
implementation 'co.tryterra:terra-android:VERSION'
}
Requirements: minSDK 28 (Android 9.0+)
Setup
import co.tryterra.terra.Terra
import co.tryterra.terra.Connections
class HealthManager(private val context: Context) {
fun initialize() {
Terra.initTerra(
devId = "botaniqalmedtech-testing-SjyfjtG33s",
referenceId = getCurrentUserId(),
context = context
)
}
fun connectSamsungHealth(token: String) {
Terra.initConnection(
connection = Connections.SAMSUNG,
token = token,
context = context,
schedulerOn = true
) { success ->
if (success) {
println("Connected to Samsung Health!")
}
}
}
fun connectHealthConnect(token: String) {
Terra.initConnection(
connection = Connections.HEALTH_CONNECT,
token = token,
context = context,
schedulerOn = true
) { success ->
if (success) {
println("Connected to Health Connect!")
}
}
}
}
Reading Data
// Get activity
Terra.getActivity(startDate, endDate) { success, data ->
if (success) {
data?.forEach { activity ->
println("Activity: ${activity.metadata.type}")
println("Calories: ${activity.caloriesData.totalBurnedCalories}")
}
}
}
// Get sleep
Terra.getSleep(startDate, endDate) { success, data ->
// Handle sleep data
}
// Get daily
Terra.getDaily(startDate, endDate) { success, data ->
// Handle daily summaries
}
Permissions
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="android.permission.BODY_SENSORS"/>
React Native SDK
Installation
npm install terra-react
# or
yarn add terra-react
# iOS: pod install
cd ios && pod install
Setup
import { Terra, Connections } from "terra-react";
// Initialize
Terra.initTerra(
"botaniqalmedtech-testing-SjyfjtG33s",
getCurrentUserId()
);
Connecting Sources
// Get auth token from your backend
const token = await fetchTerraToken();
// Connect (auto-detects platform)
const connection = Platform.OS === 'ios'
? Connections.APPLE_HEALTH
: Connections.HEALTH_CONNECT;
await Terra.initConnection(
connection,
token,
true // schedulerOn for background sync
);
Reading Data
import { Terra } from "terra-react";
// Get activity
const activities = await Terra.getActivity(startDate, endDate);
activities.forEach(activity => {
console.log(`Type: ${activity.metadata.type}`);
console.log(`Calories: ${activity.calories_data.total_burned_calories}`);
});
// Get sleep
const sleepData = await Terra.getSleep(startDate, endDate);
// Get daily
const dailyData = await Terra.getDaily(startDate, endDate);
// Get body
const bodyData = await Terra.getBody(startDate, endDate);
Writing Data
// Post activity
await Terra.postActivity(activityData);
// Post nutrition
await Terra.postNutrition(nutritionData);
// Post body metrics
await Terra.postBody(bodyData);
Flutter SDK
Installation
pubspec.yaml:
dependencies:
terra_flutter: ^VERSION
Setup
import 'package:terra_flutter/terra_flutter.dart';
class HealthManager {
late Terra terra;
void initialize() {
terra = Terra(
"botaniqalmedtech-testing-SjyfjtG33s",
getCurrentUserId()
);
}
Future<void> connectAppleHealth(String token) async {
await terra.initConnection(
Connections.APPLE_HEALTH,
token,
schedulerOn: true
);
}
}
Reading Data
// Get activity
final activities = await terra.getActivity(startDate, endDate);
for (var activity in activities) {
print("Type: ${activity.metadata.type}");
print("Calories: ${activity.caloriesData.totalBurnedCalories}");
}
// Get sleep
final sleepData = await terra.getSleep(startDate, endDate);
// Get daily
final dailyData = await terra.getDaily(startDate, endDate);
Writing Data
// Post activity
await terra.postActivity(activityData);
// Post nutrition
await terra.postNutrition(nutritionData);
Backend Token Generation
Mobile SDKs require backend token generation:
# Flask example
from flask import Flask, jsonify
from flask_login import login_required, current_user
from terra import Terra
app = Flask(__name__)
terra = Terra(dev_id="...", api_key="...")
@app.route("/api/terra/token", methods=["POST"])
@login_required
def get_terra_token():
"""Generate auth token for mobile SDK."""
response = terra.authentication.generateauthtoken(
reference_id=str(current_user.id)
)
return jsonify({"token": response.token})
Token Expiration: 180 seconds (3 minutes), one-time use.
SDK Comparison
| Feature | Python | JavaScript | iOS | Android | React Native | Flutter |
|---|---|---|---|---|---|---|
| Async support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Auto retries | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Type safety | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Background sync | N/A | N/A | ✅ | ✅ | ✅ | ✅ |
| Write data | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
When to Use Each SDK
| Scenario | Recommended SDK |
|---|---|
| Backend API calls | Python or JavaScript |
| iOS app with Apple Health | iOS SDK (Swift) |
| Android app | Android SDK (Kotlin) |
| Cross-platform mobile | React Native or Flutter |
| Serverless (Lambda, etc.) | JavaScript |
| Data processing | Python (with async) |
Related Skills
- terra-auth: Credential management
- terra-connections: Connection flows
- terra-data: Data retrieval details
- terra-webhooks: Event handling