API
Introduction
The Sahha API lets you manage user profiles, upload data, and retrieve scores, biomarkers, archetypes, and insights. All endpoints use JSON and return standard HTTP status codes.
Quick Start
1. Get an Account Token
Exchange your credentials for an account token:
curl -X POST https://api.sahha.ai/api/v1/oauth/account/token \ -H "Content-Type: application/json" \ -d '{ "clientId": "your-client-id", "clientSecret": "your-client-secret" }' curl -X POST https://api.sahha.ai/api/v1/oauth/account/token \
-H "Content-Type: application/json" \
-d '{
"clientId": "your-client-id",
"clientSecret": "your-client-secret"
}'
Response:
{ "accountToken": "eyJhbGciOiJIUzI1NiIs...", "expiresIn": 86400} {
"accountToken": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 86400
}
2. Create a Profile
Register a user profile using your account token:
curl -X POST https://api.sahha.ai/api/v1/oauth/profile/register \ -H "Authorization: account your-account-token" \ -H "Content-Type: application/json" \ -d '{ "externalId": "user-123" }' curl -X POST https://api.sahha.ai/api/v1/oauth/profile/register \
-H "Authorization: account your-account-token" \
-H "Content-Type: application/json" \
-d '{
"externalId": "user-123"
}'
Response:
{ "profileToken": "eyJhbGciOiJIUzI1NiIs...", "expiresIn": 86400} {
"profileToken": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 86400
}
3. Retrieve Scores
Fetch health scores for a profile:
# Use externalId in the path when using account tokencurl "https://api.sahha.ai/api/v1/profile/score/user-123?types=activity,sleep" \ -H "Authorization: account your-account-token" # Use externalId in the path when using account token
curl "https://api.sahha.ai/api/v1/profile/score/user-123?types=activity,sleep" \
-H "Authorization: account your-account-token"
Response:
[ { "type": "activity", "value": 72.5, "state": "medium", "createdAt": "2024-01-15T10:30:00Z", "factors": [] }] [
{
"type": "activity",
"value": 72.5,
"state": "medium",
"createdAt": "2024-01-15T10:30:00Z",
"factors": []
}
]
Authentication
Sahha uses token-based authentication. You'll work with two types of tokens depending on your use case:
| Token Type | Use Case | Header Format |
|---|---|---|
| Account Token | Server-to-server operations: create profiles, query any user's data by externalId | Authorization: account {token} |
| Profile Token | Single-user operations: query own data, update demographics | Authorization: profile {token} |
How It Works
- Get an Account Token — Exchange your
clientIdandclientSecretfor an account token - Create Profiles — Use the account token to register user profiles and receive profile tokens
- Access Data — Use account tokens (server-side) or profile tokens (client-side) to retrieve data
Which token should I use?
- Building a backend service? Use your Account Token to manage all profiles and query data by
externalId - Building a client app? Use Profile Tokens so each user can only access their own data
Token Details
| Aspect | Details |
|---|---|
| Expiration | Tokens expire after 24 hours |
| Refresh | Profile tokens can be refreshed via /oauth/profile/refreshToken |
| Storage | Store tokens securely; never expose client secrets in client-side code |
Get your credentials
Find your clientId and clientSecret in the Sahha Dashboard under API Settings.
Common Tasks
Manage a Profile
Get a Profile
curl https://api.sahha.ai/api/v1/account/profile/user-123 \ -H "Authorization: account your-account-token" curl https://api.sahha.ai/api/v1/account/profile/user-123 \
-H "Authorization: account your-account-token"
Search Profiles
curl "https://api.sahha.ai/api/v1/account/profile/search?searchParameter=john&pageSize=10" \ -H "Authorization: account your-account-token" curl "https://api.sahha.ai/api/v1/account/profile/search?searchParameter=john&pageSize=10" \
-H "Authorization: account your-account-token"
Delete Profiles
curl -X DELETE https://api.sahha.ai/api/v1/profile \ -H "Authorization: account your-account-token" \ -H "Content-Type: application/json" \ -d '["user-123", "user-456"]' curl -X DELETE https://api.sahha.ai/api/v1/profile \
-H "Authorization: account your-account-token" \
-H "Content-Type: application/json" \
-d '["user-123", "user-456"]'
Refresh a Profile Token
curl -X POST https://api.sahha.ai/api/v1/oauth/profile/refreshToken \ -H "Authorization: profile your-profile-token" curl -X POST https://api.sahha.ai/api/v1/oauth/profile/refreshToken \
-H "Authorization: profile your-profile-token"
Retrieve Profile Data
All data endpoints support two authorization modes:
| Authorization | Endpoint Pattern | Use Case |
|---|---|---|
| Account Token | /profile/{endpoint}/{externalId} | Server-side, query any user |
| Profile Token | /profile/{endpoint} | Client-side, query own data |
Scores
curl "https://api.sahha.ai/api/v1/profile/score/user-123?\startDateTime=2024-01-01T00:00:00Z&\endDateTime=2024-01-31T23:59:59Z&\types=activity,sleep,wellbeing" \ -H "Authorization: account your-account-token" curl "https://api.sahha.ai/api/v1/profile/score/user-123?\
startDateTime=2024-01-01T00:00:00Z&\
endDateTime=2024-01-31T23:59:59Z&\
types=activity,sleep,wellbeing" \
-H "Authorization: account your-account-token"
Biomarkers
curl "https://api.sahha.ai/api/v1/profile/biomarker/user-123?\categories=activity,sleep&\startDateTime=2024-01-01T00:00:00Z" \ -H "Authorization: account your-account-token" curl "https://api.sahha.ai/api/v1/profile/biomarker/user-123?\
categories=activity,sleep&\
startDateTime=2024-01-01T00:00:00Z" \
-H "Authorization: account your-account-token"
Archetypes
curl "https://api.sahha.ai/api/v1/profile/archetypes/user-123?\name=sleep_balance&\periodicity=daily" \ -H "Authorization: account your-account-token" curl "https://api.sahha.ai/api/v1/profile/archetypes/user-123?\
name=sleep_balance&\
periodicity=daily" \
-H "Authorization: account your-account-token"
Trends
curl "https://api.sahha.ai/api/v1/profile/insight/trend/user-123?\category=sleep&\periodicity=weekly" \ -H "Authorization: account your-account-token" curl "https://api.sahha.ai/api/v1/profile/insight/trend/user-123?\
category=sleep&\
periodicity=weekly" \
-H "Authorization: account your-account-token"
Comparisons
curl "https://api.sahha.ai/api/v1/profile/insight/comparison/user-123?\category=activity" \ -H "Authorization: account your-account-token" curl "https://api.sahha.ai/api/v1/profile/insight/comparison/user-123?\
category=activity" \
-H "Authorization: account your-account-token"
Profile Metadata
Update user demographics to improve score accuracy:
curl -X PUT https://api.sahha.ai/api/v1/profile/demographic \ -H "Authorization: profile your-profile-token" \ -H "Content-Type: application/json" \ -d '{ "gender": "male", "birthDate": "1990-05-15" }' curl -X PUT https://api.sahha.ai/api/v1/profile/demographic \
-H "Authorization: profile your-profile-token" \
-H "Content-Type: application/json" \
-d '{
"gender": "male",
"birthDate": "1990-05-15"
}'
Endpoint Reference
Authentication
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/v1/oauth/account/token | Get account token | None (uses clientId/clientSecret) |
| POST | /api/v1/oauth/profile/register | Register profile, get profile token | Account |
| POST | /api/v1/oauth/profile/register/appId | Register profile via SDK credentials | AppId/AppSecret headers |
| POST | /api/v1/oauth/profile/token | Get profile token for existing profile | Account |
| POST | /api/v1/oauth/profile/refreshToken | Refresh profile token | Profile |
Manage Profiles
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/v1/account/profile/{externalId} | Get profile by externalId | Account |
| GET | /api/v1/account/profile/search | Search profiles | Account |
| DELETE | /api/v1/profile | Delete profiles | Account |
Upload Data
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/v1/profile/data/log | Post data logs | Profile |
Retrive Profile Data
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/v1/profile/score | Get scores | Profile |
| GET | /api/v1/profile/score/{externalId} | Get scores by externalId | Account |
| GET | /api/v1/profile/biomarker | Get biomarkers | Profile |
| GET | /api/v1/profile/biomarker/{externalId} | Get biomarkers by externalId | Account |
| GET | /api/v1/profile/archetypes | Get archetypes | Profile |
| GET | /api/v1/profile/archetypes/{externalId} | Get archetypes by externalId | Account |
| GET | /api/v1/profile/insight/trend | Get trends | Profile |
| GET | /api/v1/profile/insight/trend/{externalId} | Get trends by externalId | Account |
| GET | /api/v1/profile/insight/comparison | Get comparisons | Profile |
| GET | /api/v1/profile/insight/comparison/{externalId} | Get comparisons by externalId | Account |
Profile Metadata
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/v1/profile/demographic | Get demographics | Profile |
| PUT | /api/v1/profile/demographic | Replace demographics | Profile |
| PATCH | /api/v1/profile/demographic | Update demographics | Profile |
| GET | /api/v1/profile/deviceInformation | Get device info | Profile |
| PUT | /api/v1/profile/deviceInformation | Update device info | Profile |
Common Query Parameters
| Parameter | Type | Description |
|---|---|---|
startDateTime | ISO 8601 | Filter results from this date/time |
endDateTime | ISO 8601 | Filter results until this date/time |
types | string[] | Filter by type (e.g., activity, sleep) |
categories | string[] | Filter by category |
periodicity | string | Filter by periodicity ( daily, weekly) |
Response Codes
| Code | Status | Description |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Profile registered successfully |
| 204 | No Content | Request successful but no data found for the query |
| 400 | Bad Request | Invalid parameters, malformed request, or externalId already in use |
| 401 | Unauthorized | Missing, invalid, or expired token |
Handling 204 responses
A 204 response means the request was valid but there's no data yet—common for new profiles or date ranges with no activity. Don't treat this as an error.
Best Practices
- Secure your credentials — Store
clientIdandclientSecretin environment variables, never in client-side code - Handle token expiration — Tokens expire in 24 hours; implement automatic refresh logic
- Use appropriate authorization — Use account tokens server-side, profile tokens client-side
- Filter your queries — Use
startDateTimeandendDateTimeto limit response size - Handle errors gracefully — Check for
401(invalid token) and400(bad request) responses
Support
Need help? Contact support@sahha.ai or join the Slack Community .