Introduction

The Sahha API lets you manage user profiles, and send and receive data on demand. Explore endpoints with the API Reference, or interactively test queries in the dashboard with the Query Builder.


Getting Started

  1. Get an Account Token — Exchange your clientId and clientSecret for an account token.
  2. Create Profiles — Register user profiles via account token (server-side) or appId/appSecret headers (client-side) to receive a profile token and refresh token
  3. Access Data — Use account tokens (server-side) or profile tokens (client-side) to retrieve data

Find your clientId and clientSecret or appId and appSecret in the Sahha Dashboard under API Keys.

1. Get an Account Token

Exchange your credentials for an account token.

Get Credentials

Get Account Token
curl -X POST https://sandbox-api.sahha.ai/api/v1/oauth/account/token \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "your-client-id",
    "clientSecret": "your-client-secret"
  }'

Response:

Account Token Response
JSON
{
  "accountToken": "eyJhbGciOiJIUzI1NiIs...",
  "tokenType": "Account"
}

2. Create a Profile

Register a user profile using your account token:

Just exploring?

You can also create a Sample Profile in the dashboard to explore your project with sample data.

Register Profile
curl -X POST https://sandbox-api.sahha.ai/api/v1/oauth/profile/register \
  -H "Authorization: account your-account-token" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "user-123"
  }'

Response:

Profile Token Response
JSON
{
	"profileToken": "eyJhbGciOiJIUzI1NiIs...",
	"expiresIn": 86400,
	"tokenType": "Profile",
	"refreshToken": "hIw0LuHXHZKMD7bWV0Dl..."
}

3. Retrieve Scores

Fetch health scores for a profile:

Get Scores
curl "https://sandbox-api.sahha.ai/api/v1/profile/score/user-123?types=activity,sleep" \
  -H "Authorization: account your-account-token"

With a profile token, omit the externalId from the path — the token identifies the profile: /api/v1/profile/score?types=activity,sleep

Response:

Scores Response
JSON
[
	{
		"type": "activity",
		"value": 72.5,
		"state": "medium",
		"createdAt": "2024-01-15T10:30:00Z",
		"factors": []
	}
]

Try Query Builder


Environments

All API requests are made against one of two environments:

EnvironmentBase URLUse Case
Sandboxhttps://sandbox-api.sahha.aiDevelopment, testing, and getting started
Productionhttps://api.sahha.aiLive apps with real user data

The examples above use the Sandbox environment. When you're ready for production, replace sandbox-api.sahha.ai with api.sahha.ai.


Authentication

Sahha uses token-based authentication. You'll work with two types of tokens depending on your use case:

Token TypeUse CaseHeader Format
Account TokenServer-to-server operations: create profiles, query any user's data by externalIdAuthorization: account {token}
Profile TokenSingle-user operations: query own data, update demographicsAuthorization: profile {token}

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

AspectDetails
ExpirationTokens expire after 24 hours
RefreshUse the refreshToken from registration to get a new profile token via /oauth/profile/refreshToken
StorageStore tokens securely; never expose secrets in client-side code

Endpoints Summary

Quick overview of available endpoints.

Authentication

MethodEndpointDescriptionAuth Required
POST/api/v1/oauth/account/tokenGet account tokenNone (uses clientId/clientSecret)
POST/api/v1/oauth/profile/registerRegister profile, get profile tokenAccount
POST/api/v1/oauth/profile/register/appIdRegister profile via SDK credentialsAppId/AppSecret headers
POST/api/v1/oauth/profile/tokenGet profile token for existing profileAccount
POST/api/v1/oauth/profile/refreshTokenRefresh profile tokenProfile

Manage Profiles

MethodEndpointDescriptionAuth Required
GET/api/v1/account/profile/{externalId}Get profile by externalIdAccount
GET/api/v1/account/profile/searchSearch profilesAccount
DELETE/api/v1/profileDelete profilesAccount

Upload Data

MethodEndpointDescriptionAuth Required
POST/api/v1/profile/data/logPost data logsProfile

Tags

MethodEndpointDescriptionAuth Required
POST/api/v1/profile/tagUpload tagsProfile
GET/api/v1/profile/tagGet tagsProfile
POST/api/v1/profile/tag/{externalId}Upload tags by externalIdAccount
GET/api/v1/profile/tag/{externalId}Get tags by externalIdAccount

Retrieve Profile Data

MethodEndpointDescriptionAuth Required
GET/api/v1/profile/scoreGet scoresProfile
GET/api/v1/profile/score/{externalId}Get scores by externalIdAccount
GET/api/v1/profile/biomarkerGet biomarkersProfile
GET/api/v1/profile/biomarker/{externalId}Get biomarkers by externalIdAccount
GET/api/v1/profile/archetypesGet archetypesProfile
GET/api/v1/profile/archetypes/{externalId}Get archetypes by externalIdAccount
GET/api/v1/profile/insight/trendGet trendsProfile
GET/api/v1/profile/insight/trend/{externalId}Get trends by externalIdAccount
GET/api/v1/profile/insight/comparisonGet comparisonsProfile
GET/api/v1/profile/insight/comparison/{externalId}Get comparisons by externalIdAccount

Profile Metadata

MethodEndpointDescriptionAuth Required
GET/api/v1/profile/demographicGet demographicsProfile
PUT/api/v1/profile/demographicReplace demographicsProfile
PATCH/api/v1/profile/demographicUpdate demographicsProfile
GET/api/v1/profile/deviceInformationGet device infoProfile
PUT/api/v1/profile/deviceInformationUpdate device infoProfile

Common Query Parameters

ParameterTypeDescription
startDateTimeISO 8601Filter results from this date/time
endDateTimeISO 8601Filter results until this date/time
typesstring[]Filter by type (e.g., activity, sleep)
categoriesstring[]Filter by category
periodicitystringFilter by periodicity (daily, weekly)

View Full API Reference


Response Codes

CodeStatusDescription
200OKRequest successful
201CreatedProfile registered successfully
204No ContentRequest successful but no data found for the query
400Bad RequestInvalid parameters, malformed request, or externalId already in use
401UnauthorizedMissing, 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 clientId and clientSecret in 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 startDateTime and endDateTime to limit response size
  • Handle errors gracefully — Check for 401 (invalid token) and 400 (bad request) responses

Support

Need help? Contact support@sahha.ai or join the Slack Community.

Docs