SDK Authentication
Associate an installed mobile SDK with one Sonar user without exposing your API key.
How Authentication Fits
Your backend remains responsible for creating users and reading their normalized data through the API. The mobile SDK receives a short-lived credential for one user and uses it only to synchronize on-device health data directly with Sonar.
Customer backend ── API key ──► create client token for Sonar user
│
▼
Mobile app ── client token ──► Sonar SDK session
│
Apple Health / Health Connect / Samsung Health
│
▼
Sonar ingestion
│
Customer backend ◄── webhook + API reads ── normalized dataHealth data does not need to pass through the customer backend, and the SDK session cannot read API data or manage the organization.
Register a Mobile Application
Create one mobile-application registration in the Sonar Developer Portal for each native app and environment.
| Setting | Description |
|---|---|
| Name | A recognizable name for your team |
| Platform | iOS or Android |
| Platform identifier | The iOS bundle ID or Android package name |
| Providers | Apple Health, Health Connect, and/or Samsung Health |
| Status | Enabled or disabled |
Sonar generates an app_id for the registration. It is an identifier, not a secret. React Native applications use separate iOS and Android registrations because each native build has its own platform identifier and provider configuration.
Session Ownership
One current SDK session represents one Sonar user using one installation of one customer application in one Sonar environment.
- A user can have multiple active sessions across mobile installations.
- V1 permits only one owning installation for each native provider. Another installation cannot connect the same provider until the existing connection is removed.
- One Android session can authorize Health Connect, Samsung Health, or both.
- The SDK creates a random installation ID. It does not use a hardware identifier and the value conveys no authority.
- Reinstalling the application creates a new installation ID and session.
- Signing out or switching users revokes the current session and removes its credentials from the device.
- Abandoned sessions expire automatically and can also be listed and revoked from the customer backend.
Session Lifecycle
Register the Application
Register the native app in the Developer Portal and add its app_id to the corresponding mobile build configuration.
Create or Retrieve the User
Your backend creates the user through POST /v1/users and stores the returned Sonar user ID alongside its own user reference.
Configure the SDK
The mobile app calls configure with its registered application ID and environment. The SDK creates and securely stores a random installation ID; it does not authenticate a user yet.
Authenticate the User
The mobile app calls authenticate with a client-token provider backed by your authenticated customer backend. The SDK passes its application and installation identifiers to that callback. Your backend resolves the signed-in customer to a Sonar user and creates a pending SDK session with its environment-scoped API key. The application registration already supplies the provider allowlist, and the app never receives the API key.
Exchange the Client Token
The SDK exchanges the client token directly with Sonar. A successful exchange consumes the token and activates a renewable session scoped to that user, environment, registered application, and permitted native providers.
Synchronize Directly with Sonar
The SDK requests operating-system permissions, reads authorized health-store changes, and uploads them to Sonar using a short-lived access token. Sonar processes the data and emits synchronization events.
Read Through the API
The customer backend handles the webhook and queries the existing daily, workout, sleep, score, or timeseries resources. The SDK is an ingestion client, not a second read API.
Create a Client Token
/v1/users/{id}/sdk-sessionsCreates a pending SDK session or issues a recovery client token for an existing installation.
Create the SDK session from your backend:
POST /v1/users/{user_id}/sdk-sessions
Authorization: Bearer $SONAR_API_KEY
Idempotency-Key: 88232d5b-f45e-4d12-b21a-643ab913b8e2
Content-Type: application/json{
"app_id": "app_01K4M7D9R3W2V8Y6T5Q1N0PABC",
"installation_id": "0d37df84-4a4e-4a89-a02e-e0b18203a146"
}{
"session_id": "5da61ca4-b8cb-4acf-a5cd-e90b23804e02",
"client_token": "sonar_sdk_init_...",
"expires_at": "2026-09-14T14:30:00Z"
}The client token is a secret. Return it only to the authenticated app user it represents, never log it, and never reuse it. In this response, expires_at is the client token’s five-minute exchange deadline, not the active session’s expiry.
A new installation returns 201 Created. Issuing a recovery token for an existing session or replaying an idempotent request returns 200 OK.
Retry a Client-Token Request
Your backend generates a unique Idempotency-Key for each client-token request. If it does not receive a response, it retries the same request with the same key. Sonar returns the original result instead of creating a duplicate. A different request must use a new key.
Requesting a recovery token does not interrupt a working SDK session. The existing credentials remain valid until the SDK successfully exchanges the new client token. At that point, Sonar replaces the previous credential generation atomically.
Only the newest unexchanged client token for an installation remains valid. Sonar rejects a request that attempts to assign an installation to a different user until the current session has been revoked.
The app_id must belong to the API key’s organization and environment. Its application registration is the provider allowlist; the client-token request cannot add or remove providers.
SDK Session Object
Management operations never return client, access, or refresh credentials. They return installation metadata:
{
"id": "5da61ca4-b8cb-4acf-a5cd-e90b23804e02",
"app_id": "app_01K4M7D9R3W2V8Y6T5Q1N0PABC",
"installation_id": "0d37df84-4a4e-4a89-a02e-e0b18203a146",
"platform": "android",
"providers": ["health_connect", "samsung_health"],
"status": "active",
"created_at": "2026-09-14T09:30:00.000Z",
"activated_at": "2026-09-14T09:30:03.000Z",
"last_refreshed_at": "2026-09-14T12:40:00.000Z",
"expires_at": "2026-10-14T12:40:00.000Z"
}| Field | Meaning |
|---|---|
id | Stable management identifier; not a credential |
app_id | Registered mobile application |
installation_id | Random identifier generated and persisted by the SDK |
platform | ios or android |
providers | Providers currently allowed by the application registration |
status | pending before client-token exchange or active afterward |
created_at | When Sonar first created the installation session |
activated_at | First successful client-token exchange, or null while pending |
last_refreshed_at | Most recent renewable-credential refresh, or null while pending |
expires_at | Current effective deadline for the pending or active session |
For an active session, expires_at is the earlier of its inactivity deadline and its 180-day maximum lifetime. It moves forward after successful refreshes only until the maximum lifetime is reached.
This management status describes whether the server-side session is pending or active. It is separate from the SDK’s local session state, which also reports refresh, temporary failure, and reauthorization conditions to the mobile app.
List SDK Sessions
/v1/users/{id}/sdk-sessionsLists the user’s pending and active mobile installations, newest first.
GET /v1/users/7e4e91a5-1e4f-4fc2-903c-251046d2a4d3/sdk-sessions
Authorization: Bearer $SONAR_API_KEY{
"sessions": [
{
"id": "5da61ca4-b8cb-4acf-a5cd-e90b23804e02",
"app_id": "app_01K4M7D9R3W2V8Y6T5Q1N0PABC",
"installation_id": "0d37df84-4a4e-4a89-a02e-e0b18203a146",
"platform": "android",
"providers": ["health_connect", "samsung_health"],
"status": "active",
"created_at": "2026-09-14T09:30:00.000Z",
"activated_at": "2026-09-14T09:30:03.000Z",
"last_refreshed_at": "2026-09-14T12:40:00.000Z",
"expires_at": "2026-10-14T12:40:00.000Z"
}
]
}Expired and revoked sessions are omitted. The first version returns the complete current list without pagination because a user normally has only a small number of installations.
Revoke an SDK Session
/v1/users/{id}/sdk-sessions/{session_id}Immediately invalidates the pending, access, and refresh credentials for one installation.
A successful revocation returns 204 No Content. Repeating the request for the same session also returns 204. An unknown session, or one owned by a different user, returns 404 not_found.
Revocation affects only that SDK installation. It does not disconnect Apple Health, Health Connect, or Samsung Health, delete imported data, or revoke another installation. Use the provider’s disconnect method when the user wants to remove a native connection and its data.
The affected SDK moves to reauthorization_required when it next contacts Sonar. If the mobile application is still signed in, its client-token provider may create a new session automatically.
Revoking a lost installation
If an installation must remain blocked, your backend must also refuse future client-token requests from that installation. Otherwise the SDK can authenticate again through the signed-in customer’s normal token provider.
Credential Lifetimes
| Credential | Lifetime |
|---|---|
| Client token | 5 minutes and single-use |
| SDK access token | 15 minutes |
| Session inactivity window | 30 days since the last successful refresh |
| Maximum session lifetime | 180 days |
The SDK refreshes access before expiry. Each successful refresh restarts the 30-day inactivity window, but it never extends the session beyond 180 days. After either session limit is reached, the SDK obtains a new client token through the mobile application’s callback.
The expiry timestamps returned by Sonar are authoritative. Applications must not hardcode these durations or schedule their own refresh calls.
Refresh and Recovery
The SDK owns ordinary access-token refresh directly with Sonar:
| Condition | SDK behavior | Customer-backend involvement |
|---|---|---|
| Access token expired | Refresh directly with Sonar | None |
| Network unavailable | Keep the session and retry with backoff | None |
| Refresh response lost | Retry with the same SDK request ID | None |
| Session expired or revoked | Request a new client token from the mobile app | Required |
| Customer app session expired | Report that reauthorization is required | Required after sign-in |
The SDK obtains a replacement client token through a callback supplied by the mobile application. It does not know the customer backend’s URL or authentication system.
Sonar.configure({ appId: SONAR_APP_ID, environment: "sandbox" });
await Sonar.authenticate({
clientTokenProvider: async (context) => {
const response = await customerApi.createSonarClientToken(context);
return response.client_token;
},
});The iOS and Android SDKs expose the same provider pattern through their platform-native APIs.
Session States
| State | Meaning |
|---|---|
signed_out | No Sonar user is associated with this installation |
ready | The SDK can synchronize |
refreshing | The SDK is renewing its Sonar access token |
temporarily_unavailable | A retryable network or Sonar failure interrupted work |
reauthorization_required | The mobile app must provide a new client token |
Temporary failures must not erase a valid session. An expired or revoked renewable credential moves the SDK to reauthorization_required, and synchronization resumes after the SDK authenticates with a new client token.
Credential Boundaries
- The API key remains in the customer backend.
- The client token is single-use, user-scoped, environment-scoped, and short-lived.
- SDK access cannot authorize API reads, user management, cloud connections, or organization administration.
- Renewable credentials are stored in Keychain or Android secure storage and are never returned to the customer backend.
- User deletion and explicit session revocation terminate the session.
- Logs and errors never contain client, access, or refresh token values.
Continue to the SDK Interface, return to the Mobile SDK overview, or choose iOS (Swift), Android (Kotlin), or React Native.
Sonar