API Reference
API Reference
Complete reference for the MTH Health REST API. All endpoints return JSON. Authentication uses a two-tier system: API keys for user management, and user tokens for user-scoped operations.
Base URL
https://health-api.movetohappiness.com
All endpoint paths in this reference are relative to this base URL.
Headers
Include the appropriate authorization header with every request. Legacy custom headers are still accepted during development, but the preferred contract is Authorization: Bearer ....
Authorization: Bearer YOUR_API_KEY Content-Type: application/json
Authorization: Bearer USER_TOKEN Content-Type: application/json
Compatibility aliases: X-App-Api-Key for API keys and X-User-Token for user tokens.
Connections
Manage OAuth connections between users and wearable providers. All connection endpoints require a user token .
Dexcom is supported in this flow as a glucose provider. The dedicated activity endpoint below is intended for Fitbit, Garmin, and Whoop connections, not Dexcom.
/api/v1/users/{userId}/connections/sessionsCreate an OAuth connect session. Returns an authorization URL to redirect the end user to.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | One of: Fitbit, Whoop, Garmin, Dexcom |
redirectUrl | string | Yes | URL to redirect to after authorization |
scopes | string | No | Custom OAuth scopes (null for defaults) |
Example request
curl -X POST \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections/sessions \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "provider": "Dexcom", "redirectUrl": "https://myapp.com/connect/callback", "scopes": null }'
Example response
{
"id": "f8a1b2c3-d4e5-6789-0abc-def123456789",
"authorizationUrl": "https://sandbox-api.dexcom.com/v3/oauth2/login?...",
"expiresAt": "2026-03-17T10:10:00Z"
} Redirect the end user to authorizationUrl. After they grant permission, they are redirected back to your redirectUrl with ?success=true or ?success=false.
/api/v1/users/{userId}/connectionsList all active connections for a user.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
Example request
curl -X GET \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections \ -H "Authorization: Bearer USER_TOKEN"
Example response
[
{
"id": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"userId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"provider": "Dexcom",
"providerUserId": "dexcom-user-id",
"status": "Active",
"scopes": "offline_access",
"tokenExpiresAt": "2026-03-24T10:00:00Z",
"createdAt": "2026-03-17T10:00:00Z",
"updatedAt": "2026-03-17T10:00:00Z"
}
]/api/v1/users/{userId}/connections/{connectionId}Disconnect a provider. Revokes the OAuth token and stops data sync.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
connectionId | path | string (UUID) | The connection ID to disconnect |
Example request
curl -X DELETE \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections/c1d2e3f4-a5b6-7890-cdef-123456789abc \ -H "Authorization: Bearer USER_TOKEN"
Example response
(empty response body)/api/v1/users/{userId}/connections/activityRetrieve canonical daily activity summaries for a date range across one or more providers.
This is the preferred public read endpoint for daily activity summaries. Use the optional provider query parameter to scope the response to a single provider; omit it to return entries across all of the user's connected providers in the app.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
from | query | string | Start date in YYYY-MM-DD format |
to | query | string | End date in YYYY-MM-DD format |
provider | query | string | Optional provider filter, such as Fitbit or Garmin |
Example request
curl -X GET \ "https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections/activity?from=2026-03-10&to=2026-03-15&provider=Fitbit" \ -H "Authorization: Bearer USER_TOKEN"
Example response
[
{
"connectionId": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"provider": "Fitbit",
"date": "2026-03-15",
"steps": 8432,
"caloriesOut": 2180,
"distanceMeters": 6340,
"lightActiveMinutes": 42,
"moderateActiveMinutes": 25,
"vigorousActiveMinutes": 22,
"sedentaryMinutes": 640,
"floorsClimbed": 8
}
]/api/v1/users/{userId}/connections/{connectionId}/activity/{date}Retrieve daily activity data for a specific connection and date.
This endpoint is only applicable to providers that expose daily activity summaries. Use it with Fitbit or Garmin connections. WHOOP uses the dedicated activity-load route documented below, and unsupported providers return 404 instead of an internal server error.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
connectionId | path | string (UUID) | The connection ID |
date | path | string | Date in YYYY-MM-DD format |
Example request
curl -X GET \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections/c1d2e3f4-a5b6-7890-cdef-123456789abc/activity/2026-03-15 \ -H "Authorization: Bearer USER_TOKEN"
Example response
{
"steps": 8432,
"caloriesOut": 2180,
"distance": 6.34,
"fairlyActiveMinutes": 25,
"veryActiveMinutes": 22,
"rawJson": "{...}"
}/api/v1/users/{userId}/connections/activity-loadRetrieve canonical load-oriented activity data for a date range across one or more providers.
This is the preferred public read endpoint for WHOOP-style strain or load data. Use the optional provider query parameter to scope the response to a single provider; omit it to return entries across all matching providers.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
from | query | string | Start date in YYYY-MM-DD format |
to | query | string | End date in YYYY-MM-DD format |
provider | query | string | Optional provider filter, such as Whoop |
Example request
curl -X GET \ "https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections/activity-load?from=2026-03-10&to=2026-03-15&provider=Whoop" \ -H "Authorization: Bearer USER_TOKEN"
Example response
[
{
"connectionId": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"provider": "Whoop",
"date": "2026-03-15",
"windowKind": "PhysiologicalCycle",
"windowStartUtc": "2026-03-14T21:48:00Z",
"windowEndUtc": "2026-03-15T07:12:00Z",
"loadScore": 15.4,
"loadScoreScale": "whoop-strain-0-21",
"energyKilocalories": 612.5,
"averageHeartRate": 70,
"maxHeartRate": 188,
"distanceMeters": null,
"steps": null,
"zoneDurationsJson": "{...}",
"sourceConfidence": "ProviderNative"
}
]/api/v1/users/{userId}/connections/{connectionId}/activity-load/{date}Retrieve canonical load-oriented activity data for a specific connection and date.
This route is intended for providers that expose strain or load-oriented day data. The current public implementation is primarily relevant for Whoop cycle data.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
connectionId | path | string (UUID) | The connection ID |
date | path | string | Date in YYYY-MM-DD format |
Example request
curl -X GET \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections/c1d2e3f4-a5b6-7890-cdef-123456789abc/activity-load/2026-03-15 \ -H "Authorization: Bearer USER_TOKEN"
Example response
{
"date": "2026-03-15",
"windowKind": "PhysiologicalCycle",
"windowStartUtc": "2026-03-14T21:48:00Z",
"windowEndUtc": "2026-03-15T07:12:00Z",
"loadScore": 15.4,
"loadScoreScale": "whoop-strain-0-21",
"energyKilocalories": 612.5,
"averageHeartRate": 70,
"maxHeartRate": 188,
"distanceMeters": null,
"steps": null,
"zoneDurationsJson": "{...}",
"sourceConfidence": "ProviderNative"
}/api/v1/users/{userId}/connections/glucoseRetrieve canonical glucose readings, events, and calibrations for a date range.
Use the optional provider query parameter to scope the response to a single provider, such as Dexcom. If omitted, the response includes glucose data from all of the user's connected glucose-capable providers.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
from | query | string | Start date in YYYY-MM-DD format |
to | query | string | End date in YYYY-MM-DD format |
provider | query | string | Optional provider filter, such as Dexcom |
Example request
curl -X GET \ "https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections/glucose?from=2026-03-10&to=2026-03-15&provider=Dexcom" \ -H "Authorization: Bearer USER_TOKEN"
Example response
{
"readings": [
{
"connectionId": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"provider": "Dexcom",
"date": "2026-03-15",
"systemTime": "2026-03-15T08:00:00Z",
"displayTime": "2026-03-15T08:00:00Z",
"value": 112,
"trend": "Flat",
"trendRate": 0,
"unit": "mg/dL",
"rateUnit": "mg/dL/min",
"status": "Active",
"transmitterId": "8G6F2",
"recordId": "reading-1"
}
],
"events": [
{
"connectionId": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"provider": "Dexcom",
"date": "2026-03-15",
"systemTime": "2026-03-15T08:05:00Z",
"displayTime": "2026-03-15T08:05:00Z",
"eventType": "Exercise",
"eventSubType": null,
"value": null,
"unit": null,
"eventId": "event-1"
}
],
"calibrations": [
{
"connectionId": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"provider": "Dexcom",
"date": "2026-03-15",
"systemTime": "2026-03-15T08:10:00Z",
"displayTime": "2026-03-15T08:10:00Z",
"value": 110,
"unit": "mg/dL"
}
]
}/api/v1/users/{userId}/connections/providersList all available providers with the user's current connection status for each.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userId | path | string (UUID) | The user's MTH Health ID |
Example request
curl -X GET \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/connections/providers \ -H "Authorization: Bearer USER_TOKEN"
Example response
[
{
"provider": {
"name": "Whoop",
"slug": "whoop",
"authType": "OAuth2",
"logoUrl": null,
"supportedDataTypes": [
"Sleep",
"ActivitySession",
"Recovery",
"ActivityLoadDaily",
"ProfileSnapshot",
"BodyMeasurementSnapshot"
]
},
"connection": null
},
{
"provider": {
"name": "Dexcom",
"slug": "dexcom",
"authType": "OAuth2",
"logoUrl": null,
"supportedDataTypes": ["GlucoseReading", "GlucoseEvent", "GlucoseCalibration"]
},
"connection": {
"id": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"userId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"provider": "Dexcom",
"providerUserId": "dexcom-user-id",
"status": "Active",
"scopes": "offline_access",
"tokenExpiresAt": "2026-03-24T10:00:00Z",
"createdAt": "2026-03-17T10:00:00Z",
"updatedAt": "2026-03-17T10:00:00Z"
}
}
]Journal Entries
Manage user-scoped nutrition journal entries. Manual meals, generic drinks, dedicated water or coffee logs, and AI-analyzed meal photos all use the same journal entry model and require a user token.
/api/v1/users/{userId}/journal-entriesCreate a manual meal, generic drink, water, or coffee entry.
Example request
curl -X POST \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/journal-entries \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "entryKind": "Water", "consumedAtUtc": "2026-03-18T08:00:00Z", "nutrients": { "volumeMl": 500 } }'
Use Water and Coffee as dedicated entryKind values when you want them tracked separately from generic Drink entries.
Example response
{
"id": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
"entryKind": "Water",
"entrySource": "Manual",
"analysisStatus": "None",
"title": "Water",
"notes": null,
"consumedAtUtc": "2026-03-18T08:00:00Z",
"journalDate": "2026-03-18",
"timezone": "Europe/Brussels",
"isUserEdited": false,
"nutrients": {
"caloriesKcal": null,
"proteinGrams": null,
"carbsGrams": null,
"fatGrams": null,
"fiberGrams": null,
"sugarGrams": null,
"sodiumMg": null,
"caffeineMg": null,
"volumeMl": 500
},
"items": [],
"image": null,
"createdAt": "2026-03-18T08:00:01Z",
"updatedAt": "2026-03-18T08:00:01Z"
}/api/v1/users/{userId}/journal-entries/scans Upload a meal photo for async AI nutrition analysis. The request uses multipart/form-data and returns 202 Accepted with a journal entry in Pending status.
Most scan flows will use Meal, but the API accepts the same journal kind set: Meal, Drink, Water, and Coffee.
Example request
curl -X POST \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/journal-entries/scans \ -H "Authorization: Bearer USER_TOKEN" \ -F "image=@lunch.jpg" \ -F "entryKind=Meal" \ -F "consumedAtUtc=2026-03-18T12:15:00Z" \ -F "timezone=Europe/Brussels" \ -F "notes=Lunch"
Example response
{
"id": "c2d3e4f5-a6b7-8901-bcde-f1234567890a",
"entryKind": "Meal",
"entrySource": "AiImage",
"analysisStatus": "Pending",
"title": "Meal",
"notes": "Lunch",
"consumedAtUtc": "2026-03-18T12:15:00Z",
"journalDate": "2026-03-18",
"timezone": "Europe/Brussels",
"isUserEdited": false,
"nutrients": {
"caloriesKcal": null,
"proteinGrams": null,
"carbsGrams": null,
"fatGrams": null,
"fiberGrams": null,
"sugarGrams": null,
"sodiumMg": null,
"caffeineMg": null,
"volumeMl": null
},
"items": [],
"image": {
"id": "d3e4f5a6-b7c8-9012-cdef-1234567890ab",
"storageProvider": "AzureBlob",
"fileName": "lunch.jpg",
"contentType": "image/jpeg",
"sizeBytes": 284512,
"width": null,
"height": null,
"createdAt": "2026-03-18T12:15:01Z",
"updatedAt": "2026-03-18T12:15:01Z"
},
"createdAt": "2026-03-18T12:15:01Z",
"updatedAt": "2026-03-18T12:15:01Z"
}/api/v1/users/{userId}/journal-entries?date={date}List all journal entries for one journal date.
Example request
curl -X GET \ "https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/journal-entries?date=2026-03-18" \ -H "Authorization: Bearer USER_TOKEN"
Example response
[
{
"id": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
"entryKind": "Water",
"entrySource": "Manual",
"analysisStatus": "None",
"title": "Water",
"notes": null,
"consumedAtUtc": "2026-03-18T08:00:00Z",
"journalDate": "2026-03-18",
"timezone": "Europe/Brussels",
"isUserEdited": false,
"nutrients": {
"caloriesKcal": null,
"proteinGrams": null,
"carbsGrams": null,
"fatGrams": null,
"fiberGrams": null,
"sugarGrams": null,
"sodiumMg": null,
"caffeineMg": null,
"volumeMl": 500
},
"itemCount": 0,
"hasImage": false,
"createdAt": "2026-03-18T08:00:01Z",
"updatedAt": "2026-03-18T08:00:01Z"
},
{
"id": "e4f5a6b7-c8d9-0123-def1-234567890abc",
"entryKind": "Coffee",
"entrySource": "Manual",
"analysisStatus": "None",
"title": "Coffee",
"notes": null,
"consumedAtUtc": "2026-03-18T09:30:00Z",
"journalDate": "2026-03-18",
"timezone": "Europe/Brussels",
"isUserEdited": false,
"nutrients": {
"caloriesKcal": 2,
"proteinGrams": null,
"carbsGrams": null,
"fatGrams": null,
"fiberGrams": null,
"sugarGrams": null,
"sodiumMg": null,
"caffeineMg": 95,
"volumeMl": 240
},
"itemCount": 0,
"hasImage": false,
"createdAt": "2026-03-18T09:30:01Z",
"updatedAt": "2026-03-18T09:30:01Z"
}
]/api/v1/users/{userId}/journal-entries/{entryId}Fetch one entry with itemized nutrients and optional image metadata.
Example request
curl -X GET \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/journal-entries/c2d3e4f5-a6b7-8901-bcde-f1234567890a \ -H "Authorization: Bearer USER_TOKEN"
Example response
{
"id": "c2d3e4f5-a6b7-8901-bcde-f1234567890a",
"entryKind": "Meal",
"entrySource": "AiImage",
"analysisStatus": "Completed",
"title": "Chicken breast + 1 more",
"notes": "Lunch",
"consumedAtUtc": "2026-03-18T12:15:00Z",
"journalDate": "2026-03-18",
"timezone": "Europe/Brussels",
"isUserEdited": false,
"nutrients": {
"caloriesKcal": 428,
"proteinGrams": 49,
"carbsGrams": 12,
"fatGrams": 18,
"fiberGrams": 3,
"sugarGrams": 2,
"sodiumMg": 540,
"caffeineMg": null,
"volumeMl": null
},
"items": [
{
"id": "f5a6b7c8-d9e0-1234-ef12-34567890abcd",
"name": "Chicken breast",
"category": "Protein",
"quantity": 150,
"unit": "g",
"estimatedWeightGrams": 150,
"nutrients": {
"caloriesKcal": 248,
"proteinGrams": 46,
"carbsGrams": 0,
"fatGrams": 5,
"fiberGrams": null,
"sugarGrams": null,
"sodiumMg": 410,
"caffeineMg": null,
"volumeMl": null
},
"confidence": 0.94,
"sortOrder": 0,
"createdAt": "2026-03-18T12:15:09Z",
"updatedAt": "2026-03-18T12:15:09Z"
},
{
"id": "a6b7c8d9-e0f1-2345-f123-4567890abcde",
"name": "Rice",
"category": "Carbohydrate",
"quantity": 120,
"unit": "g",
"estimatedWeightGrams": 120,
"nutrients": {
"caloriesKcal": 180,
"proteinGrams": 3,
"carbsGrams": 12,
"fatGrams": 13,
"fiberGrams": 3,
"sugarGrams": 2,
"sodiumMg": 130,
"caffeineMg": null,
"volumeMl": null
},
"confidence": 0.88,
"sortOrder": 1,
"createdAt": "2026-03-18T12:15:09Z",
"updatedAt": "2026-03-18T12:15:09Z"
}
],
"image": {
"id": "d3e4f5a6-b7c8-9012-cdef-1234567890ab",
"storageProvider": "AzureBlob",
"fileName": "lunch.jpg",
"contentType": "image/jpeg",
"sizeBytes": 284512,
"width": null,
"height": null,
"createdAt": "2026-03-18T12:15:01Z",
"updatedAt": "2026-03-18T12:15:01Z"
},
"createdAt": "2026-03-18T12:15:01Z",
"updatedAt": "2026-03-18T12:15:09Z"
}/api/v1/users/{userId}/journal-entries/{entryId}Update an existing entry to correct portions, nutrients, or missing items.
Example request
curl -X PATCH \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/journal-entries/b1c2d3e4-f5a6-7890-abcd-ef1234567890 \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "name": "Chicken breast", "quantity": 150, "unit": "g", "nutrients": { "caloriesKcal": 248, "proteinGrams": 46 } } ] }'
Example response
{
"id": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
"entryKind": "Meal",
"entrySource": "AiImage",
"analysisStatus": "Completed",
"title": "Chicken breast",
"notes": null,
"consumedAtUtc": "2026-03-18T12:15:00Z",
"journalDate": "2026-03-18",
"timezone": "Europe/Brussels",
"isUserEdited": true,
"nutrients": {
"caloriesKcal": 248,
"proteinGrams": 46,
"carbsGrams": null,
"fatGrams": null,
"fiberGrams": null,
"sugarGrams": null,
"sodiumMg": null,
"caffeineMg": null,
"volumeMl": null
},
"items": [
{
"id": "f5a6b7c8-d9e0-1234-ef12-34567890abcd",
"name": "Chicken breast",
"category": "",
"quantity": 150,
"unit": "g",
"estimatedWeightGrams": null,
"nutrients": {
"caloriesKcal": 248,
"proteinGrams": 46,
"carbsGrams": null,
"fatGrams": null,
"fiberGrams": null,
"sugarGrams": null,
"sodiumMg": null,
"caffeineMg": null,
"volumeMl": null
},
"confidence": null,
"sortOrder": 0,
"createdAt": "2026-03-18T12:18:00Z",
"updatedAt": "2026-03-18T12:18:00Z"
}
],
"image": {
"id": "d3e4f5a6-b7c8-9012-cdef-1234567890ab",
"storageProvider": "AzureBlob",
"fileName": "lunch.jpg",
"contentType": "image/jpeg",
"sizeBytes": 284512,
"width": null,
"height": null,
"createdAt": "2026-03-18T12:15:01Z",
"updatedAt": "2026-03-18T12:15:01Z"
},
"createdAt": "2026-03-18T12:15:01Z",
"updatedAt": "2026-03-18T12:18:00Z"
}OAuth Callbacks
These are system endpoints used internally by the OAuth flow. You do not call them directly, but you need to know the callback URLs when configuring your OAuth app credentials with each provider.
/api/v1/connections/callback OAuth 2.0 callback endpoint. Used by Fitbit, Whoop, and Dexcom. Receives code and state query parameters. Redirects the user to the client's redirectUrl.
No authentication required. These callbacks are managed by MTH Health as part of the hosted OAuth flow.
Example request
GET /api/v1/connections/callback?code=oauth-code-123&state=state-token-abc
Example response
Location: https://myapp.com/connect/callback?success=true
/api/v1/connections/callback/oauth1 OAuth 1.0a callback endpoint. Used by Garmin. Receives oauth_token and oauth_verifier query parameters. Redirects the user to the client's redirectUrl.
No authentication required. This callback is managed by MTH Health as part of the hosted OAuth flow.
Example request
GET /api/v1/connections/callback/oauth1?oauth_token=request-token&oauth_verifier=verifier-123
Example response
Location: https://myapp.com/connect/callback?success=true
Scores
Retrieve computed health scores that combine data from sleep, activity, and recovery across all connected providers. All score endpoints require a user token .
The current score contract is built around sleep, activity, and recovery dimensions. Dexcom support does not add glucose-specific score fields to these endpoints.
/api/v1/scores/dailyRetrieve daily health scores for a date range.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
from | query | string | Start date in YYYY-MM-DD format (inclusive) |
to | query | string | End date in YYYY-MM-DD format (inclusive) |
Example request
curl -X GET \ "https://health-api.movetohappiness.com/api/v1/scores/daily?from=2026-03-10&to=2026-03-15" \ -H "Authorization: Bearer USER_TOKEN"
Example response
[
{
"date": "2026-03-15",
"sleepScore": 82,
"activityScore": 71,
"recoveryScore": 78,
"overallScore": 77,
"components": { ... }
},
{
"date": "2026-03-14",
"sleepScore": 75,
"activityScore": 68,
"recoveryScore": 80,
"overallScore": 74,
"components": { ... }
}
]/api/v1/scores/weeklyRetrieve weekly aggregated health scores for a date range.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
from | query | string | Start date in YYYY-MM-DD format (inclusive) |
to | query | string | End date in YYYY-MM-DD format (inclusive) |
Example request
curl -X GET \ "https://health-api.movetohappiness.com/api/v1/scores/weekly?from=2026-03-03&to=2026-03-16" \ -H "Authorization: Bearer USER_TOKEN"
Example response
[
{
"weekStartDate": "2026-03-10",
"sleepScore": 80,
"activityScore": 68,
"recoveryScore": 75,
"overallScore": 74,
"daysWithData": 5
},
{
"weekStartDate": "2026-03-03",
"sleepScore": 77,
"activityScore": 72,
"recoveryScore": 70,
"overallScore": 73,
"daysWithData": 7
}
]Users
Manage users within your application. All user endpoints require an API key. Users represent end users of your application whose wearable data you want to access.
/api/v1/usersCreate a user idempotently by external user ID. Returns the user object plus a freshly issued token for user-scoped operations.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
externalUserId | string | Yes | Your application's unique identifier for the user |
locale | string | No | User locale (e.g., en-US, nl-BE) |
timezone | string | No | IANA timezone (e.g., Europe/Brussels) |
metadata | object | No | Arbitrary key-value metadata for your application |
Example request
curl -X POST \ https://health-api.movetohappiness.com/api/v1/users \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "externalUserId": "user-123", "locale": "en-US", "timezone": "Europe/Brussels", "metadata": { "plan": "premium" } }'
Returns 201 Created when a new user is created, or 200 OK when the externalUserId already exists and a fresh token is issued for that user.
Example response
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"appId": "e5f6g7h8-i9j0-1234-klmn-op5678901234",
"externalUserId": "user-123",
"status": "Active",
"locale": "en-US",
"timezone": "Europe/Brussels",
"metadata": { "plan": "premium" },
"token": "usr_tok_abc123def456ghi789...",
"createdAt": "2026-03-17T10:00:00Z",
"updatedAt": "2026-03-17T10:00:00Z"
}/api/v1/users?external_user_id={externalUserId}Find a user by their external user ID. Returns 404 if not found. The token is not returned by read endpoints.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
external_user_id | query | string | The external user ID to look up |
Example request
curl -X GET \ "https://health-api.movetohappiness.com/api/v1/users?external_user_id=user-123" \ -H "Authorization: Bearer YOUR_API_KEY"
Example response
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"appId": "e5f6g7h8-i9j0-1234-klmn-op5678901234",
"externalUserId": "user-123",
"status": "Active",
"locale": "en-US",
"timezone": "Europe/Brussels",
"metadata": { "plan": "premium" },
"createdAt": "2026-03-17T10:00:00Z",
"updatedAt": "2026-03-17T10:00:00Z"
}/api/v1/users/{id}Retrieve a user by their MTH Health internal ID. The token is not returned by read endpoints.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id | path | string (UUID) | The user's MTH Health ID |
Example request
curl -X GET \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \ -H "Authorization: Bearer YOUR_API_KEY"
Example response
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"appId": "e5f6g7h8-i9j0-1234-klmn-op5678901234",
"externalUserId": "user-123",
"status": "Active",
"locale": "en-US",
"timezone": "Europe/Brussels",
"metadata": { "plan": "premium" },
"createdAt": "2026-03-17T10:00:00Z",
"updatedAt": "2026-03-17T10:00:00Z"
}/api/v1/users/{id}Partially update a user. Only include the fields you want to change. The token is not returned by update endpoints.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id | path | string (UUID) | The user's MTH Health ID |
Request body (partial)
| Field | Type | Description |
|---|---|---|
locale | string | Updated locale |
timezone | string | Updated timezone |
metadata | object | Updated metadata (replaces existing) |
Example request
curl -X PATCH \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "locale": "nl-BE", "metadata": { "plan": "enterprise" } }'
Example response
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"appId": "e5f6g7h8-i9j0-1234-klmn-op5678901234",
"externalUserId": "user-123",
"status": "Active",
"locale": "nl-BE",
"timezone": "Europe/Brussels",
"metadata": { "plan": "enterprise" },
"createdAt": "2026-03-17T10:00:00Z",
"updatedAt": "2026-03-19T09:30:00Z"
}/api/v1/users/{id}Soft-delete a user. The user's data is retained but the user is marked as inactive.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id | path | string (UUID) | The user's MTH Health ID |
Example request
curl -X DELETE \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \ -H "Authorization: Bearer YOUR_API_KEY"
Example response
(empty response body)/api/v1/users/{id}/rotate-tokenRotate a user's token. Invalidates the current token and returns a new one.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id | path | string (UUID) | The user's MTH Health ID |
Example request
curl -X POST \ https://health-api.movetohappiness.com/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890/rotate-token \ -H "Authorization: Bearer YOUR_API_KEY"
Example response
{
"token": "usr_tok_new123xyz456abc789..."
}Error codes
The API uses standard HTTP status codes to indicate the outcome of a request.
| Status | Meaning | Description |
|---|---|---|
| 400 | Bad Request | Invalid request body or missing required fields |
| 401 | Unauthorized | Missing or invalid API key / user token |
| 403 | Forbidden | Valid credentials but insufficient permissions for this endpoint |
| 404 | Not Found | Resource does not exist |
| 500 | Internal Server Error | Something went wrong on our end |