iOS (Swift)
Connections
The iOS SDK supports the following connection types:
Connections.APPLE_HEALTH
Apple Health (HealthKit)
Connections.FREESTYLE_LIBRE
FreeStyle Libre (NFC sensor)
CustomPermissions
Use these to request a subset of permissions instead of all available ones. When not specified, all permissions from your developer scopes are requested.
WORKOUT_TYPES, ACTIVITY_SUMMARY, LOCATION, CALORIES, STEPS, HEART_RATE, HEART_RATE_VARIABILITY, VO2MAX, HEIGHT, ACTIVE_DURATIONS, WEIGHT, FLIGHTS_CLIMBED, BMI, BODY_FAT, EXERCISE_DISTANCE, GENDER, DATE_OF_BIRTH, BASAL_ENERGY_BURNED, SWIMMING_SUMMARY, RESTING_HEART_RATE, BLOOD_PRESSURE, BLOOD_GLUCOSE, BODY_TEMPERATURE, MINDFULNESS, LEAN_BODY_MASS, OXYGEN_SATURATION, SLEEP_ANALYSIS, RESPIRATORY_RATE, NUTRITION_SODIUM, NUTRITION_PROTEIN, NUTRITION_CARBOHYDRATES, NUTRITION_FIBRE, NUTRITION_FAT_TOTAL, NUTRITION_SUGAR, NUTRITION_VITAMIN_C, NUTRITION_VITAMIN_A, NUTRITION_CALORIES, NUTRITION_WATER, NUTRITION_CHOLESTEROL, MENSTRUATION, INTERBEAT, SPEED, POWER, ELECTROCARDIOGRAM
Initialization
Terra.instance
Creates and authenticates a TerraManager instance. This makes a network call to Terra's servers to validate your developer ID and retrieve your account configuration.
If an existing Apple Health user is found for this device, the SDK will automatically reconnect — this may trigger the HealthKit permission popup and start background delivery if previously configured.
Terra.instance(devId: String,
referenceId: String?,
completion: @escaping (TerraManager?, TerraError?) -> Void)devId: String➡ Your developer ID from the Terra Dashboard.referenceId: String?➡ An identifier for your app's user. This value appears asreference_idin webhook payloads and API responses, allowing you to map Terra users back to your own user system.completion: @escaping (TerraManager?, TerraError?) -> Void➡ Called when initialization completes. You must wait for this callback before calling any other SDK function. On failure,TerraManagerwill be nil andTerraErrorwill describe the issue.
This function requires network connectivity. It will fail with TerraError.NoInternet if the device is offline.
Possible errors:
TerraError.InvalidDevID
The devId is not recognized by Terra
TerraError.NoInternet
Network request failed
TerraError.HealthKitUnavailable
Device does not support HealthKit (e.g. iPad)
Static methods on Terra
setUpBackgroundDelivery
Registers HealthKit observer queries and a BGTaskScheduler task to automatically send new health data to your webhook destination, even when your app is in the background.
This is a static method on the Terra class (not on TerraManager). It must be called in your AppDelegate's didFinishLaunchingWithOptions.
Delivery frequency by data type:
Activity, Sleep, Daily
Immediate (on new data)
Body, Nutrition, Menstruation
Hourly
Prerequisites:
Terra.instancemust have been called at least once previously (the SDK uses your stored scopes to determine which data types to observe).Your app's
Info.plistmust includeco.tryterra.data.post.requestin theBGTaskSchedulerPermittedIdentifiersarray.HealthKit Background Delivery and Background Processing capabilities must be enabled in Xcode.
If a data post fails due to no network, the SDK caches the payload and retries via BGTaskScheduler when connectivity is restored.
checkAuthentication
Checks whether a connection is authenticated by making a network call to Terra's servers.
connection: Connections➡ The connection type to check.devId: String➡ Your developer ID.completion: @escaping (Bool) -> Void➡trueif the connection is authenticated on the server,falseotherwise (including network failures).
setIgnoredSources
Filters out health data from specific apps when reading from Apple Health. Use this to prevent double-counting when a user connects a data source both through Terra's API (e.g. WHOOP, Garmin) and has that same app syncing into Apple Health.
ignored: [String]➡ An array of app bundle identifiers to exclude (e.g.["com.whoop.app", "com.garmin.connect.mobile"]). Any HealthKit samples originating from these apps will be filtered out of all data reads.
Can be called at any time — takes effect on the next data fetch (including background delivery).
Not persisted across app launches — call this on every app start if needed.
Does not affect which data sources can write to HealthKit, only what the Terra SDK reads.
TerraManager Instance methods
All methods below are called on the TerraManager instance returned by Terra.instance.
Connection setup/management
initConnection
Authenticates a new user connection with Terra's servers and triggers the platform permission dialog. This makes a network call and, for Apple Health, shows the HealthKit permission popup.
This function should only be called once per user/connection type. On subsequent app launches, Terra.instance will automatically reconnect existing users.
type: Connections➡ The connection type to initialize (e.g..APPLE_HEALTH).token: String➡ A single-use authentication token generated from your backend server via the Generate Authentication Token endpoint. Each token can only be used once.(Optional)
customReadTypes: Set<CustomPermissions>➡ Customize which permissions appear in the HealthKit popup. When empty, defaults to all permissions from your developer scopes.schedulerOn: Bool➡ Enables background delivery of health data. Defaults totrue. When enabled, new data is automatically sent to your webhook destination. Requires callingTerra.setUpBackgroundDelivery()in your AppDelegate for background delivery to function.completion: @escaping (Bool, TerraError?) -> Void➡ Called when the connection is established (or fails).
Possible errors:
TerraError.InvalidDevID
Developer ID not recognized
TerraError.InvalidToken
Token is invalid or already used
TerraError.UserLimitsReached
Your plan's user limit has been reached
TerraError.NoInternet
Network request failed
TerraError.HealthKitUnavailable
Device does not support HealthKit
getUserId
Returns the Terra user ID for a connection, or nil if no connection exists. This is a synchronous, local read with no network call.
The returned user_id is the same identifier used in webhook payloads, API requests, and the Terra dashboard.
type: Connections➡ The connection to retrieve the user ID for.
Returns nil when:
initConnectionwas never called for this connection typeNo existing user was found during
Terra.instanceinitializationThe connection failed
Data retrieval
All data retrieval functions make network calls — even with toWebhook: false, the SDK sends data to Terra's normalization servers and returns the normalized result.
Each function accepts dates as either Date or TimeInterval (Unix timestamp). Each also accepts an optional withSamples: Bool? = nil parameter.
toWebhook behavior:
toWebhook
What happens
Completion returns
true (default)
Data is fetched from the health source and sent to your webhook destination
A reference ID string only (not the data itself)
false
Data is fetched, sent to Terra for normalization, and the normalized payload is returned locally
The full normalized data payload
Both paths require network connectivity.
withSamples parameter: Controls whether the server includes granular time-series sample arrays in the response. When nil (default), the server uses its default behavior. Set to true to explicitly request samples, or false to exclude them for smaller payloads.
Date ranges over 31 days are automatically chunked into weekly segments and processed serially.
getActivity
Retrieves workout and activity data (exercise sessions, mindfulness sessions, heart rate during workouts, GPS routes, etc.).
getDaily
Retrieves daily summary data (total steps, calories, distance, resting heart rate, HRV, floors climbed, etc.).
getSleep
Retrieves sleep session data (sleep stages, duration, heart rate during sleep, HRV, SpO2, respiratory rate).
getBody
Retrieves body measurement data (weight, height, BMI, body fat, heart rate, HRV, blood pressure, blood glucose, SpO2, body temperature, ECG).
latestReading: Bool➡ Whentrue, ignores the date range and returns only the single most recent reading for each body metric (weight, height, BMI, etc.). Heart rate and HRV samples still use the date range. Only available on theDateoverload (notTimeInterval). Defaults tofalse.
getNutrition
Retrieves nutrition and meal data (macronutrients, micronutrients, water intake, individual meals).
getMenstruation
Retrieves menstrual cycle data.
getAthlete
Retrieves the user's athlete profile (biographical data, no date range needed).
Completion parameters (same structure for all data getters):
Bool➡trueif the request succeeded.Payload?➡ WhentoWebhook: true, contains only areferencestring. WhentoWebhook: false, contains the full normalized data.nilon failure.TerraError?➡ Describes the error if the request failed. Possible values:TerraError.Unauthenticated(no connection for this type),TerraError.UnsupportedResource(e.g. calling getActivity with FREESTYLE_LIBRE).
subscribe
Registers for real-time data updates via HealthKit anchored object queries. When new data arrives, the Terra.updateHandler closure is called with the new samples.
forDataTypes: Set<DataTypes>➡ Data types to subscribe to. Available values:STEPS,HEART_RATE,HEART_RATE_VARIABILITY,CALORIES,DISTANCE.
Before calling subscribe, you must set the update handler:
Set this in your AppDelegate's didFinishLaunchingWithOptions so it persists across app launches. The handler is called both for real-time updates and for catching up on data that arrived while the app was closed.
Writing data
These functions write data directly into Apple Health. No network calls are made — data is written to the local HealthKit store.
postActivity
Writes a workout to Apple Health.
type: The connection type (e.g.
.APPLE_HEALTH).payload: A
TerraActivityDataobject. Required fields:metadata.start_time,metadata.end_time, and at least one field indevice_data. Optional:distance_data.summary.distance_meters,calories_data.net_activity_calories.completion:
Boolfor success,TerraError?for errors (e.g.StartTimeCannotBeNil,InvalidDateFormat,InvalidDevice,PermissionsDenied).
postNutrition
Writes nutrition data (a food entry with macros/micros) to Apple Health.
payload: A
TerraNutritionDataobject withmetadata.start_time/end_timeand nutrition values insummary.macros/summary.micros. Supports 33+ nutrient types.completion:
Boolonly (noTerraError). Returnsfalseif dates are invalid, all write permissions are denied, or the HealthKit save fails.
postBody
Writes body measurement data to Apple Health (weight, height, BMI, heart rate, blood pressure, glucose, SpO2, temperature, etc.).
payload: A
TerraBodyDataobject with measurement samples.completion:
Boolonly (noTerraError). Returnsfalseif dates are invalid or HealthKit save fails.
Last updated
Was this helpful?