Health Rewards
Health Rewards
Overview
The Terra Health Rewards product lets you turn the raw activity, sleep and physiological data you already receive through the Terra API into actionable, gamified points that drive user engagement.
Science‑based & adaptive – Points are calculated from evidence‑backed metrics (sleep duration, HRV, steps, floors climbed and more) and automatically adjust to each individual’s baseline.
Real‑time – Rewards are generated on demand
Configurable – Limits, category weights and streak bonuses can be tweaked in Dashboard → Health Rewards (see screenshots below).
Monetisable – Combine earned points with in‑app currency, coupons or badge systems to incentivise healthier habits.

How It Works
Enable Rewards Open the dashboard, navigate to Health Rewards and toggle the product to “Enabled”. Here you can:
assign daily point caps (overall or per category),
choose weights for each goal (e.g. “Hours Slept = 3 pts”, “Steps = 1 pt”),
add streak bonuses (e.g. “≥10 pts 2 days in a row → +1 pt”). All changes apply instantly to new calculations.
Request points Call the Rewards endpoints (see below) providing the user_id and a start_date (and optionally end_date). Terra fetches the necessary
daily
,sleep
,activity
, data, runs the algorithm in real time, then returns a total plus a human‑readable breakdown for every day.
Endpoints
Base URL
https://api.tryterra.co/v2
All calls require the standarddev-id
&x-api-key
headers.
GET
/rewards/points
Calculate points for a period
POST
/rewards/points/spent
Deduct points (e.g. when a user redeems a voucher)
GET
/rewards/points/spent/history
Retrieve a chronological list of redeemed points
1 Get points
GET /rewards/points?user_id=USER123&start_date=2024‑08‑01&end_date=2024‑08‑07&store=true
dev-id: YOUR_DEV_ID
Query parameters
user_id
string
✓
Terra user identifier
start_date
YYYY‑MM‑DD
✓
First date (inclusive)
end_date
YYYY‑MM‑DD
Last date (exclusive). Defaults to start_date + 1.
Key fields:
total
All‑time points earned (including streak bonuses, minus redemptions).
daily[*].raw_total
Points before streak bonuses that day.
daily[*].breakdown
Per‑category goals (activity, sleep, movement, health_data) with goal, achieved, points and max.
daily[*].streak_total
Points awarded from streak goals for that day.
2 Spend points
POST /rewards/points/spent?user_id=USER123
dev-id: YOUR_DEV_ID
Content-Type: application/json
{ "points": 50 }
Deducts 50 points from the user’s balance. A 400 error is returned if the user has insufficient points.
3 Redemption history
GET /rewards/points/spent/history?user_id=USER123&start_date=2024‑01‑01&end_date=2024‑12‑31
dev-id: YOUR_DEV_ID
Returns an ordered array [ [points, timestamp] ]
.
Response Object Anatomy
Below is a trimmed version of the example response highlighting the structure you will typically work with:
{
"daily": [
{
"date": "2024‑08‑06",
"breakdown": {
"activity": {
"proportional": { "goal": "Up to 30 mins", "achieved": {...}, "points": 5, "max": 5 },
"target": { "goal": "30 mins", "points": 5 },
"extra": { "goal": "Extra 15 mins", "points": 2 },
"streaks": [ { "goal": "≥3 activity pts for 2 days", "points": 1 } ],
"raw_total": 8,
"max": 8
},
"sleep": { … },
"movement":{ … },
"health_data": { … }
},
"raw_total": 12,
"streak_total": 4,
"max": 12
}
],
"total": 147
}
Tip – Parsing points quickly If you only need the numeric score, read
daily[*].raw_total + daily[*].streak_total
. If you want to visualise goals, iterate overbreakdown
and use thegoal
/achieved
strings to populate the UI.
Dashboard Configuration
The Health Rewards UI (see screenshots) is laid out by category:
Activity
Minutes of moderate / vigorous activity
Movement
Steps & floors climbed
Sleep
Hours in bed, bedtime consistency, efficiency, quality
Health Data
HRV, resting heart‑rate consistency & improvement
Use Limits & Streaks to:
Set an overall cap (e.g., 30 pts / day)
Add global streaks (e.g., ≥20 pts for 5 days → +3 pts)
Define per‑category streaks (e.g., Movement ≥5 pts for 3 days → +1 pt)
All configuration is stored in Terra and read by the API at calculation time.
Example Use Case – “Weekly Wellness Challenge”
Configure Goals
Dashboard → Health Rewards
Overall daily limit = 30 pts
Activity proportional = max 5, target = 5, extra = 2
Movement steps = 1, proportional = 2
Sleep hours/efficiency/quality = 2 each
Add streak: ≥20 pts for 7 days → +5 bonus
Frontend Implementation
Show a progress bar that calls GET /rewards/points every morning for yesterday’s date.
Display breakdown tool‑tips using the
goal
andachieved
strings.
Redemption Flow
When a user taps “Redeem 100 pts for free shipping”, call POST /rewards/points/spent.
Show the new balance (
total
field) returned in the 200 response.
Leaderboard
Aggregate
raw_total + streak_total
per user over the week to show top performers.
Best Practices
Sync ahead of time – Make sure wearable data is pulled before you calculate rewards for a day.
Store on server‑side – Use
store=true
(default) so that the canonical balance lives with Terra and cannot be tampered with client‑side.Handle nulls gracefully – If a metric is missing (e.g., HRV), its goal will remain but
points
might be0
.Rate limits – Reward endpoints share the same rate limits as other
v2
calls (60 req/min default). Aggregate user calls where possible.
FAQ
Can I backfill rewards?
Yes. Provide a historical start_date
/end_date
; Terra will fetch past data and compute points retro‑actively.
What time zone are dates evaluated in?
All dates are interpreted in local time.
Can I override an individual user’s goal?
Not yet. Goals are global per developer account.
Why are my users getting 0 points?
Check that the necessary data (sleep, daily summary) exists and that rewards are enabled for your dev ID.
Need help? Reach out via a dashboard support ticket.
Last updated
Was this helpful?