Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"source": "./",
"strict": false,
"skills": [
"./skills/terra-api",
"./skills/terra-unified-api",
"./skills/terra-mobile-sdk",
"./skills/terra-streaming",
"./skills/terra-planned-workouts",
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Rules:
- Good: `Read references/webhooks.md when implementing the webhook endpoint or debugging signature failures.`
- Bad: `See references/ for more details.`
- Keep references one level deep from SKILL.md – no chains of files referencing files.
- Rules-based skills (like `terra-api`) use `rules/` instead of `references/`: SKILL.md is an index with a category priority table and a one-liner per rule; each rule lives in `rules/<prefix>-<name>.md` with frontmatter (title, impact, tags) and incorrect/correct code examples. `rules/_sections.md` defines the categories; copy `rules/_template.md` for new rules.
- Rules-based skills (like `terra-unified-api`) use `rules/` instead of `references/`: SKILL.md is an index with a category priority table and a one-liner per rule; each rule lives in `rules/<prefix>-<name>.md` with frontmatter (title, impact, tags) and incorrect/correct code examples. `rules/_sections.md` defines the categories; copy `rules/_template.md` for new rules.
- Scripts in `scripts/` should be self-contained, print status to stderr and machine-readable output to stdout, and fail with helpful error messages.
- Source content from the live docs: append `.md` to any `docs.tryterra.co` URL for markdown, or start from the index at `docs.tryterra.co/llms.txt`. Cite the source URL at the top of each reference file so it can be refreshed later.

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Rules:
- Good: `Read references/webhooks.md when implementing the webhook endpoint or debugging signature failures.`
- Bad: `See references/ for more details.`
- Keep references one level deep from SKILL.md – no chains of files referencing files.
- Rules-based skills (like `terra-api`) use `rules/` instead of `references/`: SKILL.md is an index with a category priority table and a one-liner per rule; each rule lives in `rules/<prefix>-<name>.md` with frontmatter (title, impact, tags) and incorrect/correct code examples. `rules/_sections.md` defines the categories; copy `rules/_template.md` for new rules.
- Rules-based skills (like `terra-unified-api`) use `rules/` instead of `references/`: SKILL.md is an index with a category priority table and a one-liner per rule; each rule lives in `rules/<prefix>-<name>.md` with frontmatter (title, impact, tags) and incorrect/correct code examples. `rules/_sections.md` defines the categories; copy `rules/_template.md` for new rules.
- Scripts in `scripts/` should be self-contained, print status to stderr and machine-readable output to stdout, and fail with helpful error messages.
- Source content from the live docs: append `.md` to any `docs.tryterra.co` URL for markdown, or start from the index at `docs.tryterra.co/llms.txt`. Cite the source URL at the top of each reference file so it can be refreshed later.

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ npx skills add tryterra/agent-skills
Or a single skill:

```bash
npx skills add tryterra/agent-skills --skill terra-api
npx skills add tryterra/agent-skills --skill terra-unified-api
```

**Claude Code plugin** (alternative):
Expand All @@ -28,14 +28,14 @@ npx skills add tryterra/agent-skills --skill terra-api
**Manual** (Claude Code):

```bash
cp -r skills/terra-api ~/.claude/skills/
cp -r skills/terra-unified-api ~/.claude/skills/
```

## Skills

| Skill | Description | Status |
| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------- |
| [`terra-api`](skills/terra-api) | Best-practice rules: webhooks & signature verification, data idempotency, connection lifecycle, multi-device data, testing | ✅ Ready |
| [`terra-unified-api`](skills/terra-unified-api) | Best-practice rules: webhooks & signature verification, data idempotency, connection lifecycle, multi-device data, testing | ✅ Ready |
| [`terra-mobile-sdk`](skills/terra-mobile-sdk) | Mobile SDK: Apple Health, Samsung Health, Health Connect (iOS, Android, React Native, Flutter) | ✅ Ready |
| [`terra-streaming`](skills/terra-streaming) | Realtime streaming: websockets, Real-Time SDK, live sensor data (iOS, Android, React Native, Flutter, Wear OS) | ✅ Ready |
| [`terra-planned-workouts`](skills/terra-planned-workouts) | Planned Workouts API: push structured workouts with intervals and targets to wearables | 🧪 Pre-release |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"url": "https://github.com/tryterra/agent-skills/issues"
},
"keywords": [
"terra-api",
"terra-unified-api",
"agent-skills",
"ai-agents",
"claude-code",
Expand Down
2 changes: 1 addition & 1 deletion skills.sh.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"title": "Terra API",
"description": "Skills for integrating Terra API – the unified health & fitness data API.",
"skills": [
"terra-api",
"terra-unified-api",
"terra-mobile-sdk",
"terra-streaming",
"terra-planned-workouts",
Expand Down
2 changes: 1 addition & 1 deletion skills/terra-mobile-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Integration guidance for the [Terra API](https://tryterra.co) mobile SDK – the on-device path for health sources that have **no web API**: Apple Health (HealthKit), Samsung Health, and Health Connect.

Every other provider (Garmin, Fitbit, Oura, Whoop, Strava, Dexcom, and 500+ more) connects through the [Health & Fitness API](https://docs.tryterra.co/health-and-fitness-api), covered by the `terra-api` skill. This skill is for the three sources you can only reach on-device.
Every other provider (Garmin, Fitbit, Oura, Whoop, Strava, Dexcom, and 500+ more) connects through the [Unified API](https://docs.tryterra.co/unified-api), covered by the `terra-unified-api` skill. This skill is for the three sources you can only reach on-device.

`SKILL.md` carries the six-step workflow and every cross-platform gotcha inline; the `references/` files carry per-platform setup detail and code.

Expand Down
8 changes: 4 additions & 4 deletions skills/terra-mobile-sdk/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ The mobile SDK exists for one reason: to reach health sources that have **no web
- **Samsung Health** (Android)
- **Health Connect** (Android)

Every other provider (Garmin, Fitbit, Oura, Whoop, Strava, Dexcom, and 500+ more) connects through the [Health & Fitness API](https://docs.tryterra.co/health-and-fitness-api), not the SDK. Google Fit can be read through the SDK via Health Connect, but the web API is the preferred, more reliable route for it. If a provider you need has a web API, use the web API.
Every other provider (Garmin, Fitbit, Oura, Whoop, Strava, Dexcom, and 500+ more) connects through the [Unified API](https://docs.tryterra.co/unified-api), not the SDK. Google Fit can be read through the SDK via Health Connect, but the web API is the preferred, more reliable route for it. If a provider you need has a web API, use the web API.

Data captured by the SDK flows to the same Data Destination (webhook) as web API data, and connections are managed with the same auth model. If you are building the receiving webhook or storing the health data, that is the `terra-api` skill's territory; this skill covers the on-device connection.
Data captured by the SDK flows to the same Data Destination (webhook) as web API data, and connections are managed with the same auth model. If you are building the receiving webhook or storing the health data, that is the `terra-unified-api` skill's territory; this skill covers the on-device connection.

## The six-step workflow

Expand All @@ -35,7 +35,7 @@ The shape is identical on every platform. Platform differences are in the `refer
5. **Validate with `getUserId` on every re-initialization.** `getUserId` is synchronous and returns the `user_id` if the connection is live or `nil`/`null` if not. Call it right after every init; on `nil`, call `initConnection` again to reconnect. Re-connecting an already-connected user triggers no popup and does not interrupt the user.
6. **iOS only: enable background delivery.** Call `Terra.setUpBackgroundDelivery()` in your `AppDelegate`'s `didFinishLaunchingWithOptions`. Without it, Apple Health data is not pushed automatically.

**Deauthenticating** a user uses the same endpoint as web integrations: `DELETE /auth/deauthenticateUser`, called from your backend. See [the web API auth reference](https://docs.tryterra.co/health-and-fitness-api).
**Deauthenticating** a user uses the same endpoint as web integrations: `DELETE /auth/deauthenticateUser`, called from your backend. See [the web API auth reference](https://docs.tryterra.co/unified-api).

## Permission popup behavior (read before shipping)

Expand Down Expand Up @@ -83,4 +83,4 @@ Read the file for the platform you are building on:
- **`references/react-native.md`** – read when integrating **terra-react**: install, iOS + Android native setup, `initTerra`/`initConnection`, the AppDelegate background-delivery edit, `postActivity` (Apple Health only).
- **`references/flutter.md`** – read when integrating **terra_flutter_bridge**: `flutter pub`, native setup, `TerraFlutter` API, AppDelegate background delivery, getters.

Full docs: [docs.tryterra.co](https://docs.tryterra.co) (append `.md` to any docs URL for a markdown version). Where a signature or enum is not shown here, see the SDK reference linked from [docs.tryterra.co](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources). If the terra-docs MCP server (`https://docs.tryterra.co/~gitbook/mcp`) is connected, use its tools to search and fetch the docs instead.
Full docs: [docs.tryterra.co](https://docs.tryterra.co) (append `.md` to any docs URL for a markdown version). Where a signature or enum is not shown here, see the SDK reference linked from [docs.tryterra.co](https://docs.tryterra.co/unified-api/mobile-only-sources). If the terra-docs MCP server (`https://docs.tryterra.co/~gitbook/mcp`) is connected, use its tools to search and fetch the docs instead.
10 changes: 5 additions & 5 deletions skills/terra-mobile-sdk/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
"date": "July 2026",
"abstract": "Integration guidance for the Terra API mobile SDK, the on-device path for health sources with no web API: Apple Health (HealthKit), Samsung Health, and Health Connect. Covers the install/init/token/connect/validate/background-delivery workflow, permission-popup behavior, and per-platform setup for TerraiOS, TerraAndroid, terra-react, and terra_flutter_bridge.",
"references": [
"https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources",
"https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/ios-swift",
"https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/android-kotlin",
"https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/react-native",
"https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/flutter"
"https://docs.tryterra.co/unified-api/mobile-only-sources",
"https://docs.tryterra.co/unified-api/mobile-only-sources/ios-swift",
"https://docs.tryterra.co/unified-api/mobile-only-sources/android-kotlin",
"https://docs.tryterra.co/unified-api/mobile-only-sources/react-native",
"https://docs.tryterra.co/unified-api/mobile-only-sources/flutter"
]
}
6 changes: 3 additions & 3 deletions skills/terra-mobile-sdk/references/android.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Android (Kotlin) – TerraAndroid

Native Kotlin integration for **Samsung Health** and **Health Connect**. Source: [docs.tryterra.co/health-and-fitness-api/mobile-only-sources/android-kotlin](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/android-kotlin).
Native Kotlin integration for **Samsung Health** and **Health Connect**. Source: [docs.tryterra.co/unified-api/mobile-only-sources/android-kotlin](https://docs.tryterra.co/unified-api/mobile-only-sources/android-kotlin).

## 1. Install

Expand Down Expand Up @@ -106,7 +106,7 @@ fun initialiseUserConnection() {
- `connection`: `Connections.SAMSUNG` (Samsung Health) or `Connections.HEALTH_CONNECT`.
- `schedulerOn = true`: lets Terra API make scheduled requests while the app is in the foreground.
- `startIntent`: **deprecated, always pass `null`**.
- `customPermissions`: maps to Health Connect / Samsung data types – see [Permissions mapping](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources).
- `customPermissions`: maps to Health Connect / Samsung data types – see [Permissions mapping](https://docs.tryterra.co/unified-api/mobile-only-sources).

**Popup fires once.** Health Connect forbids the permission popup from appearing more than once per permission, so a second `initConnection` does nothing. It re-appears only if you expand `customPermissions`, the app is reinstalled, or you request a permission Google has not approved for release.

Expand Down Expand Up @@ -146,4 +146,4 @@ fun requestData() {
}
```

Disconnect via the same backend endpoint as web integrations (`DELETE /auth/deauthenticateUser`). There is no iOS-style background-delivery setup on Android – foreground scheduled requests are controlled by `schedulerOn`. See the SDK reference on [docs.tryterra.co](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/android-kotlin) for the full function list.
Disconnect via the same backend endpoint as web integrations (`DELETE /auth/deauthenticateUser`). There is no iOS-style background-delivery setup on Android – foreground scheduled requests are controlled by `schedulerOn`. See the SDK reference on [docs.tryterra.co](https://docs.tryterra.co/unified-api/mobile-only-sources/android-kotlin) for the full function list.
6 changes: 3 additions & 3 deletions skills/terra-mobile-sdk/references/flutter.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Flutter – terra_flutter_bridge

Cross-platform integration for **Apple Health** (iOS), **Samsung Health**, and **Health Connect** (Android). Source: [docs.tryterra.co/health-and-fitness-api/mobile-only-sources/flutter](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/flutter).
Cross-platform integration for **Apple Health** (iOS), **Samsung Health**, and **Health Connect** (Android). Source: [docs.tryterra.co/unified-api/mobile-only-sources/flutter](https://docs.tryterra.co/unified-api/mobile-only-sources/flutter).

## 1. Install and native setup

Expand Down Expand Up @@ -78,7 +78,7 @@ Future<void> _initialiseConnection() async {

- `type`: `Connection.appleHealth`, `Connection.samsung`, or `Connection.healthConnect`.
- `schedulerOn`: **no effect on iOS** (background delivery is via `setUpBackgroundDelivery`); on Android, `true` enables foreground scheduled requests.
- `customPermissions`: see [Permissions mapping](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources).
- `customPermissions`: see [Permissions mapping](https://docs.tryterra.co/unified-api/mobile-only-sources).

Popup behavior: Apple Health and Health Connect show the popup once (re-triggers only on expanded `customPermissions`, reinstall, or – Health Connect – a permission Google has not approved). The HealthKit popup is a WebView; WebView-based apps must interrupt their WebView, call `initConnection`, then reopen.

Expand Down Expand Up @@ -134,4 +134,4 @@ Future<void> getData() async {
}
```

Set `toWebhook: false` to receive the payload in the response instead of pushing to your destination. Disconnect via the same backend endpoint as web integrations (`DELETE /auth/deauthenticateUser`). See the SDK reference on [docs.tryterra.co](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/flutter) for the full function list.
Set `toWebhook: false` to receive the payload in the response instead of pushing to your destination. Disconnect via the same backend endpoint as web integrations (`DELETE /auth/deauthenticateUser`). See the SDK reference on [docs.tryterra.co](https://docs.tryterra.co/unified-api/mobile-only-sources/flutter) for the full function list.
8 changes: 4 additions & 4 deletions skills/terra-mobile-sdk/references/ios.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# iOS (Swift) – TerraiOS

Native Swift integration for **Apple Health**. Source: [docs.tryterra.co/health-and-fitness-api/mobile-only-sources/ios-swift](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/ios-swift). `TerraiOS` supports Apple Health only.
Native Swift integration for **Apple Health**. Source: [docs.tryterra.co/unified-api/mobile-only-sources/ios-swift](https://docs.tryterra.co/unified-api/mobile-only-sources/ios-swift). `TerraiOS` supports Apple Health only.

## 1. Install and add capabilities

Expand Down Expand Up @@ -59,7 +59,7 @@ terra.initConnection(
}
```

`schedulerOn` has no effect on iOS; background delivery is controlled by `setUpBackgroundDelivery()`. `customReadTypes` maps to HealthKit types – see [Permissions mapping](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources). The popup fires once (re-triggers only on expanded `customPermissions` or reinstall), and it is a WebView (WebView-based apps must interrupt their WebView, call `initConnection`, then reopen).
`schedulerOn` has no effect on iOS; background delivery is controlled by `setUpBackgroundDelivery()`. `customReadTypes` maps to HealthKit types – see [Permissions mapping](https://docs.tryterra.co/unified-api/mobile-only-sources). The popup fires once (re-triggers only on expanded `customPermissions` or reinstall), and it is a WebView (WebView-based apps must interrupt their WebView, call `initConnection`, then reopen).

## 4. Validate with getUserId on every re-init

Expand Down Expand Up @@ -178,7 +178,7 @@ let activityData = TerraActivityData(
terra.postActivity(type: .APPLE_HEALTH, payload: activityData) { success, error in /* ... */ }
```

`postBody` and `postNutrition` follow the same shape with `TerraBodyData` / `TerraNutritionData` payloads. Fetch [docs.tryterra.co/health-and-fitness-api/mobile-only-sources/ios-swift.md](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/ios-swift.md) for the full payload field lists when building the request body.
`postBody` and `postNutrition` follow the same shape with `TerraBodyData` / `TerraNutritionData` payloads. Fetch [docs.tryterra.co/unified-api/mobile-only-sources/ios-swift.md](https://docs.tryterra.co/unified-api/mobile-only-sources/ios-swift.md) for the full payload field lists when building the request body.

## Planned workout sync (iOS 17+)

Expand All @@ -188,4 +188,4 @@ Planned workouts are created via Terra API's REST API on your backend; the iOS S
- `syncPlannedWorkoutsFromBackend(type:)` – manually trigger a sync of pending actions.
- `isPlannedWorkoutBackendSyncEnabled` – current state.

Observe `.terraPlannedWorkoutSynced` and `.terraPlannedWorkoutSyncCompleted` via `NotificationCenter` for per-workout and completion events. See the SDK reference linked from [the iOS docs](https://docs.tryterra.co/health-and-fitness-api/mobile-only-sources/ios-swift) for the event object shapes.
Observe `.terraPlannedWorkoutSynced` and `.terraPlannedWorkoutSyncCompleted` via `NotificationCenter` for per-workout and completion events. See the SDK reference linked from [the iOS docs](https://docs.tryterra.co/unified-api/mobile-only-sources/ios-swift) for the event object shapes.
Loading
Loading