Product Updates
November 2025 product update: Azure Blob and Kafka destinations, and one consistent way to hear that a user disconnected
November 2025: Azure Blob Storage and Kafka join Terra's destinations, disconnection and re-auth events are standardised across every source, and strain scores cover running.
TL;DR: Terra can now deliver payloads into Azure Blob Storage and into a Kafka topic, which covers the two requests we heard most often from teams whose data platform was not on AWS or Google Cloud. Separately, every source now reports a lost or revoked connection through the same event with the same shape, so the code that gets your user to reconnect is written once rather than once per integration.
Azure Blob Storage and Kafka join Terra's data destinations
Terra could already write to S3 and Google Cloud Storage, and to SQS as a queue. In November we added Azure Blob Storage and Kafka to that list. Both are configured the same way as the existing destinations, from the connections area of the dashboard, and both are documented in the destinations section of the docs, with the queue-based ones covered in the SQS and Kafka guide.
We keep adding destinations because a webhook endpoint is a piece of infrastructure with its own operational surface. It has to be up, it has to answer quickly, and it has to absorb a burst when a few thousand watches all sync at eight in the morning. A queue or an object store absorbs that burst for you by design. If your analytics stack is already reading from Kafka, having health data arrive on a topic next to everything else means the rest of your pipeline does not have to learn anything new about Terra at all.
Every source now reports connection states the same way
A connection between your user and their device platform can end for several different reasons. The person can revoke your app's access from the provider's own settings page. The provider can expire or invalidate the token. The person can change their password, or delete their account, or turn off a permission that the connection depended on. Each source describes these situations in its own vocabulary.
We standardised it. There is now one way a lost connection is reported, one way a connection that merely needs the user to sign in again is reported, and a clear distinction between the two, because the right product response is different in each case. A revoked connection means the user made a deliberate choice and you should probably respect it for a while before asking again. A connection that needs re-authentication is usually invisible to the user, and the right move is a quiet prompt the next time they open your app. The events and how to handle them are covered in handling authentication events.
Alongside this, the dashboard gained the ability to resend webhooks, so if your endpoint was down during a window you can now ask for the payloads from that window again rather than reconstructing them from a historical data request.
Activity strain scores now cover running and jogging
Activity Strain is one of Terra's health scores. It takes the average heart rate of a session, its duration, and the person's own recent maximum heart rate, and turns them into a single number describing how hard that session was for that particular person. It was already computed for a range of activity types, and in November we turned it on for running and jogging, which between them are the most common recorded activity across the whole Terra user base.
The score appears inside the activity payload under data_enrichment, with no extra call. The full set of scores, what each one needs in order to be computed, and how to switch them on is in the Health Scores documentation.
What each source gained in November
- Suunto: sleep data is now collected and normalised, so Suunto users contribute to sleep-based features and sleep scores rather than only to activity.
- Peloton: the class identifier is now part of the activity's summary identifier, which means two people who took the same class produce activities you can actually group together.
- Rouvy: the connection now uses OAuth 2.0, which is the modern sign-in flow where the user approves access on Rouvy's own page and no credentials pass through your app.
- Hammerhead: ride histories are now retrieved as a full paginated sweep, so a user with years of riding behind them arrives complete on their first sync.
- Cronometer: polling now reaches one day further back, which catches nutrition entries that people log the morning after.