.claude/skills/terra-connections/SKILL.md
Terra API device and provider connections. Use when connecting users to wearables (Fitbit, Garmin, Apple Health, Oura, WHOOP), managing user sessions, or handling disconnections.
npx skillsauth add adaptationio/skrillz terra-connectionsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Connect users to 150+ wearable devices and health data providers.
Pre-built UI, easiest integration:
from terra import Terra
client = Terra(
dev_id=os.environ["TERRA_DEV_ID"],
api_key=os.environ["TERRA_API_KEY"]
)
# Generate widget session
response = client.authentication.generatewidgetsession(
reference_id="user_12345", # Your internal user ID
auth_success_redirect_url="https://app.botaniqal.com/success",
auth_failure_redirect_url="https://app.botaniqal.com/failure",
providers=["FITBIT", "GARMIN", "OURA"] # Optional: filter providers
)
widget_url = response.url
# Redirect user to widget_url
User Flow:
type: "auth"Build your own provider selection UI:
# Step 1: Get available integrations
integrations = client.integrations.fetch()
# Display provider list in your UI
# Step 2: User selects provider, generate auth URL
response = client.authentication.authenticateuser(
resource="FITBIT", # Provider selected by user
reference_id="user_12345"
)
auth_url = response.auth_url
# Open auth_url in browser (NOT WebView/iFrame!)
Important: Always open auth URLs in a real browser, not WebView or iFrame (OAuth security requirement).
These sources have no web API - mobile SDK required:
iOS (Swift) - Apple Health:
import TerraiOS
// 1. Get token from your backend
let token = await fetchTerraToken()
// 2. Initialize Terra
Terra.initTerra(devId: "botaniqalmedtech-testing-SjyfjtG33s", referenceId: "user_12345")
// 3. Connect to Apple Health
Terra.initConnection(
type: Connections.APPLE_HEALTH,
token: token,
schedulerOn: true // Enable background sync
) { success, error in
if success {
print("Connected to Apple Health!")
}
}
Android (Kotlin) - Samsung Health / Health Connect:
import co.tryterra.terra.Terra
// 1. Get token from your backend
val token = fetchTerraToken()
// 2. Initialize Terra (minSDK 28 required)
Terra.initTerra(
devId = "botaniqalmedtech-testing-SjyfjtG33s",
referenceId = "user_12345",
context = this
)
// 3. Connect to Samsung Health or Health Connect
Terra.initConnection(
connection = Connections.SAMSUNG, // or Connections.HEALTH_CONNECT
token = token,
context = this,
schedulerOn = true
) { success ->
if (success) {
println("Connected to Samsung Health!")
}
}
React Native:
import { Terra, Connections } from "terra-react";
// Initialize
Terra.initTerra("botaniqalmedtech-testing-SjyfjtG33s", "user_12345");
// Connect (iOS: Apple Health, Android: Samsung/Health Connect)
await Terra.initConnection(
Connections.APPLE_HEALTH,
authToken,
true // schedulerOn for background sync
);
connect-userConnect a user to a wearable provider.
def connect_user(
client: Terra,
reference_id: str,
provider: str = None,
success_url: str = None,
failure_url: str = None
) -> dict:
"""
Connect user to wearable provider.
Args:
reference_id: Your internal user ID
provider: Specific provider or None for widget with all
success_url: Redirect URL on success
failure_url: Redirect URL on failure
Returns:
dict with url and session_id
"""
if provider:
# Custom UI flow - specific provider
response = client.authentication.authenticateuser(
resource=provider,
reference_id=reference_id
)
return {"url": response.auth_url, "type": "direct"}
else:
# Widget flow - user selects provider
response = client.authentication.generatewidgetsession(
reference_id=reference_id,
auth_success_redirect_url=success_url,
auth_failure_redirect_url=failure_url
)
return {
"url": response.url,
"session_id": response.session_id,
"type": "widget"
}
disconnect-userDisconnect user and remove their data.
def disconnect_user(client: Terra, terra_user_id: str) -> bool:
"""
Disconnect user from Terra (revokes access, removes data).
Args:
terra_user_id: Terra's user ID (not your reference_id)
Returns:
bool: Success status
"""
response = client.authentication.deauthenticateuser(user_id=terra_user_id)
return response.success
get-user-infoGet user's connection status and details.
def get_user_info(client: Terra, terra_user_id: str) -> dict:
"""Get information about a connected user."""
response = client.user.getuser(user_id=terra_user_id)
return {
"user_id": response.user.user_id,
"provider": response.user.provider,
"reference_id": response.user.reference_id,
"scopes": response.user.scopes,
"last_webhook_update": response.user.last_webhook_update
}
list-connected-usersGet all users connected to your app.
def list_connected_users(client: Terra) -> list:
"""List all connected Terra users."""
response = client.user.getsubscriptions()
users = []
for user in response.users:
users.append({
"user_id": user.user_id,
"provider": user.provider,
"reference_id": user.reference_id,
"last_update": user.last_webhook_update
})
return users
get-users-by-referenceFind Terra users by your internal reference ID.
def get_users_by_reference(client: Terra, reference_id: str) -> list:
"""
Get all Terra users for a reference_id.
(One person can have multiple providers connected)
"""
response = client.user.getuser(reference_id=reference_id)
return response.users # List of TerraUser objects
One user can connect multiple wearables:
# User connects Fitbit
connect_user(client, "user_123", provider="FITBIT")
# Same user connects Oura Ring
connect_user(client, "user_123", provider="OURA")
# Get all connections for user
users = get_users_by_reference(client, "user_123")
# Returns: [TerraUser(provider="FITBIT"), TerraUser(provider="OURA")]
Each provider creates a separate Terra User ID, but all share the same reference_id.
schedulerOn: trueWhen user connects/disconnects, you receive webhooks:
Connection Success (type: "auth"):
{
"type": "auth",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT",
"reference_id": "user_12345"
},
"status": "authenticated"
}
Disconnection (type: "deauth"):
{
"type": "deauth",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT"
},
"status": "deauthenticated"
}
Connection Error (type: "connection_error"):
{
"type": "connection_error",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT"
},
"message": "Token refresh failed"
}
CREATE TABLE terra_connections (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id), -- Your user
terra_user_id VARCHAR(255) UNIQUE, -- Terra's user ID
provider VARCHAR(50), -- FITBIT, GARMIN, etc.
reference_id VARCHAR(255), -- Your reference ID
connected_at TIMESTAMP DEFAULT NOW(),
last_sync TIMESTAMP,
status VARCHAR(20) DEFAULT 'active', -- active, disconnected
scopes TEXT[] -- Granted permissions
);
CREATE INDEX idx_terra_user ON terra_connections(user_id);
CREATE INDEX idx_terra_reference ON terra_connections(reference_id);
development
Setup secure web-based terminal access to WSL2 from mobile/tablet via ttyd + ngrok/Cloudflare/Tailscale. One-command install, start, stop, status. Use when you need remote terminal access, web terminal, browser-based shell, or mobile access to WSL2 environment.
development
Complete development workflows where Claude writes the code while Gemini and Codex provide research, planning, reviews, and different perspectives. Claude remains the main developer. Use for complex projects requiring expert planning and multi-perspective reviews.
development
Systematic progress tracking for skill development. Manages task states (pending/in_progress/completed), updates in real-time, reports progress, identifies blockers, and maintains momentum. Use when tracking skill development, coordinating work, or reporting progress.
testing
Comprehensive testing workflow orchestrating functional testing, example validation, integration testing, and usability assessment. Sequential workflow for complete skill testing from examples through scenarios to integration validation. Use when conducting thorough testing, pre-deployment validation, ensuring skill functionality, or comprehensive quality checks.