Wearables

Set up a wearable provider

  • Sandbox: available
  • Staging: available
  • Production: unknown
POST
/v1/wearables/providers

Stores your project's OAuth app at a wearable provider, so the project's patients can connect their accounts.

Auth: bearer token of a project admin. Scope: the caller's project (from the token).

Before you call it

  1. Register an app in the provider's developer program. Garmin, Suunto and Polar approve apps before they work. For Suunto, subscribe the app to the Cloud API product to get its subscription key, both shown on your Suunto profile page.
  2. Set its redirect URL to the provider's redirectUri from GET /v1/wearables/providers.

Behaviour

  • clientId and secret are the app's OAuth client ID and secret. secret is never returned.
  • subscriptionKey is required for Suunto (its API-management subscription key) and refused for every other provider.
  • webhookSecret is Suunto's notification secret, the one set beside its notification URL in the Suunto developer portal. It is optional, never returned, and refused for every other provider with 422 WEBHOOK_SECRET_NOT_USED. Without it, ovok refuses Suunto's notifications and syncs Suunto only daily and on demand.
  • enabled defaults to true.
  • The credentials are encrypted before they are stored. A server that cannot encrypt answers 501 and stores nothing.
  • For Polar, when enabled is true, ovok then creates the client's webhook at Polar for the SLEEP and ACTIVITY_SUMMARY events, pointing at webhookUrl. Polar first sends it a PING, which ovok answers. ovok keeps the webhook's signing key with the credentials, encrypted and never returned. Should this fail, the credentials stay stored, webhookReady answers false, and saving them again retries.
  • A Polar client has one webhook. If it has one already for this project, ovok points it at webhookUrl and switches it back on. When ovok does not hold that webhook's signing key, which Polar shows only once, ovok replaces the webhook to get a new key. A webhook pointing at another project, or anywhere else, is left alone: webhookReady stays false; give each project its own Polar client.
  • Withings with the client ID of ovok's own Withings device integration answers 422 CLIENT_ID_RESERVED: register an app of your own.
  • A provider already set up answers 409 PROVIDER_CONFIGURED; change it with PATCH. A project changed by someone else while this request wrote also answers 409; read it again and retry.
  • The answer is 201 with a Location header naming the provider.

Example

curl -X POST 'https://api.sandbox.ovok.com/v1/wearables/providers' \  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' \  -H 'Content-Type: application/json' \  -d '{ "provider": "oura", "clientId": "your-client-id", "secret": "your-client-secret" }'

Authorization

bearer
headerAuthorizationBearer <JWT>

Request Body

application/json
  1. body
provider*string
Value in"oura""whoop""strava""withings""polar""suunto""garmin""ultrahuman"
clientId*string

The OAuth client ID of the project's app at the provider.

Length1 <= length <= 500
secret*string

The OAuth client secret. Never returned.

Length1 <= length <= 2000
subscriptionKey?string

Suunto only: the app's API-management subscription key. Never returned.

Length1 <= length <= 2000
Defaultnull
webhookSecret?string

Suunto only: the notification secret set in Suunto's portal, to check its notifications. Never returned.

Length1 <= length <= 2000
Defaultnull
enabled?boolean

Whether the project's users may connect this provider.

Defaulttrue

Response Body

The provider after the change; Location names it.

application/json
  1. response
provider*string
Value in"oura""whoop""strava""withings""polar""suunto""garmin""ultrahuman"
configured*boolean

Whether the project holds credentials for this provider.

enabled*boolean

Whether its users may connect it: configured and switched on.

clientId*string

The OAuth client ID, or null when not configured.

redirectUri*string

The callback URL to register in the provider's developer portal; null when this server has no APP_BASE_URL.

webhookUrl*string

Where the provider sends notifications, to paste in its developer portal where it asks for one. Withings' ends in a per-project token, so it is shown to admins only. Null when the provider sends none, is not set up, its webhook secret is not stored yet, or this server has no APP_BASE_URL.

webhookReady*boolean

Whether ovok holds the secret that checks this provider's notifications, so they are accepted: Polar's signing key from its webhook setup, Withings' generated URL secret, or the Suunto secret the admin sent. False until then, such as after a failed Polar webhook setup. Null when the provider sends no notifications.

Example Request
curl -X POST 'https://api.sandbox.ovok.com/v1/wearables/providers' \  -H 'Content-Type: application/json' \  -d '{  "provider": "oura",  "clientId": "string",  "secret": "string"}'
Example Response
{  "provider": "oura",  "configured": true,  "enabled": true,  "clientId": "string",  "redirectUri": "string",  "webhookUrl": "string",  "webhookReady": true}

List the project's wearable providers GET

Returns every cloud wearable provider ovok supports, and whether your current project has set each one up. It never returns a secret. **Auth:** bearer token of a project admin. The caller must also be a Practitioner, an admin or hold the System Owner access policy. **Scope:** the caller's project (from the token). ## Behaviour - `providers` lists `oura`, `whoop`, `strava`, `withings`, `polar`, `suunto`, `garmin` and `ultrahuman`. - `configured` is `true` when the project holds OAuth credentials for the provider that this server can read. Credentials stored with another key read as not configured; set them up again with `POST`. - `enabled` is `true` when the provider is configured and switched on. Only then can the project's patients connect it. - `clientId` is the OAuth client ID, or `null`. - `redirectUri` is the callback URL to register in the provider's developer portal, the same for every project. It is `null` when this server has no public base URL. - `webhookUrl` is where the provider sends notifications of new data, unique to the project. For Withings it ends in a per-project token that proves a notification's origin, so only admins see it; keep it private. Paste it where the provider's portal asks for one (Suunto). For Withings and Polar it is for information only: ovok registers it itself. It is `null` when the provider sends no notifications (Oura, Whoop, Strava, Garmin and Ultrahuman for now), is not set up, or this server has no public base URL. See `POST /v1/wearables/webhooks/<projectId>/<provider>`. - `webhookReady` is `true` when ovok holds the secret that checks the provider's notifications: Polar's signing key from its webhook setup, the secret ovok makes for Withings, or Suunto's `webhookSecret`. It is `false` until then, so a Polar webhook setup that failed shows here; save Polar again to retry. It is `null` when the provider sends no notifications. ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/wearables/providers' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ```

Get a wearable provider GET

Returns one wearable provider of your current project, set up or not, in the shape of `GET /v1/wearables/providers`. It never returns a secret. **Auth:** bearer token of a project admin. **Scope:** the caller's project (from the token). ## Example ```bash curl -X GET 'https://api.sandbox.ovok.com/v1/wearables/providers/oura' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NjcyNjg4MDAsImV4cCI6MTc2NzI3MjQwMH0.Ql3B_ztDvctlyZ2z0vp4sl3ExXRQGkzmxdmTAqxNzZk' ```