### Manual Local Development Setup Source: https://docs.openwearables.io/quickstart Commands for setting up the backend and frontend environments manually without Docker, including dependency installation, database migrations, and server startup. ```bash # Backend cd backend uv sync alembic upgrade head uvicorn app.main:api --reload # Frontend cd frontend npm install npm run dev ``` -------------------------------- ### Sync Suunto Data via API Source: https://docs.openwearables.io/api-reference/guides/provider-setup Provides examples for syncing Suunto data, including filtering by time range and data type. Demonstrates the use of shell variables for dynamic timestamp generation. ```bash # Sync all data from last 30 days THIRTY_DAYS_AGO=$(date -v-30d +%s) curl -X POST "http://localhost:8000/api/v1/providers/suunto/users/{user_id}/sync?data_type=all&since=${THIRTY_DAYS_AGO}&limit=100" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" # Sync only workouts curl -X POST "http://localhost:8000/api/v1/providers/suunto/users/{user_id}/sync?data_type=workouts" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` -------------------------------- ### Setup and Execution Commands Source: https://docs.openwearables.io/sdk/flutter/example-app Commands to clone the repository, install Flutter dependencies, and run the application on a connected device. ```bash git clone https://github.com/the-momentum/open_wearables_health_sdk.git cd open_wearables_health_sdk/example flutter pub get flutter run ``` -------------------------------- ### Offset Pagination Example Source: https://docs.openwearables.io/api-reference/introduction Example HTTP GET request demonstrating offset pagination for user resources. Uses 'page' and 'limit' query parameters to control the results. ```http GET /api/v1/users?page=2&limit=50 ``` -------------------------------- ### Clone and Configure Open Wearables Repository Source: https://docs.openwearables.io/quickstart Commands to clone the project repository and initialize the environment configuration files for both backend and frontend services. ```bash git clone https://github.com/the-momentum/open-wearables.git cd open-wearables cp ./backend/config/.env.example ./backend/config/.env cp ./frontend/.env.example ./frontend/.env ``` -------------------------------- ### Complete Health Sync Service Integration Example Source: https://docs.openwearables.io/sdk/ios/integration This Swift code provides a comprehensive example of a service class for integrating the OpenWearables Health SDK. It covers initialization, user connection with authentication, starting background sync, and handling disconnections and immediate syncs. Dependencies include the OpenWearablesHealthSDK and Foundation. ```swift import OpenWearablesHealthSDK import Foundation class HealthSyncService { static let shared = HealthSyncService() private let sdk = OpenWearablesHealthSDK.shared private let backendURL: String private var authToken: String? var isConnected: Bool { return sdk.isSessionValid } private init() { self.backendURL = "https://your-backend.com" } /// Initialize the health sync service func initialize() { sdk.onLog = { message in print("[HealthSync] \(message)") } sdk.onAuthError = { statusCode, message in print("[HealthSync] Auth error \(statusCode): \(message)") if statusCode == 401 { // Handle token expiration in your app NotificationCenter.default.post(name: .healthAuthExpired, object: nil) } } sdk.configure(host: "https://api.openwearables.io") } /// Connect health data for the current user func connect(authToken: String, completion: @escaping (Result) -> Void) { self.authToken = authToken // 1. Get credentials from your backend var request = URLRequest(url: URL(string: "\(backendURL)/api/health/connect")!) request.httpMethod = "POST" request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") URLSession.shared.dataTask(with: request) { [weak self] data, response, error in guard let self = self else { return } if let error = error { completion(.failure(error)) return } guard let data = data, let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any], let userId = json["userId"] as? String, let accessToken = json["accessToken"] as? String else { completion(.failure(NSError(domain: "", code: -1, userInfo: [ NSLocalizedDescriptionKey: "Failed to parse credentials" ]))) return } // 2. Sign in with SDK self.sdk.signIn( userId: userId, accessToken: accessToken, refreshToken: json["refreshToken"] as? String, apiKey: nil ) // 3. Request permissions and start sync self.sdk.requestAuthorization(types: [ .steps, .heartRate, .sleep, .workout, .activeEnergy ]) { granted in if granted { self.sdk.startBackgroundSync { started in if started { completion(.success(())) } else { completion(.failure(NSError(domain: "", code: -1, userInfo: [ NSLocalizedDescriptionKey: "Failed to start sync" ]))) } } } else { completion(.failure(NSError(domain: "", code: -1, userInfo: [ NSLocalizedDescriptionKey: "Health permissions not granted" ]))) } } }.resume() } /// Disconnect health data func disconnect() { sdk.stopBackgroundSync() sdk.signOut() } /// Trigger an immediate sync func syncNow(completion: @escaping () -> Void) { sdk.syncNow { completion() } } /// Force a full re-sync of all data func resyncAllData() { sdk.resetAnchors() sdk.syncNow { } // The completion handler for syncNow is optional here } } extension Notification.Name { static let healthAuthExpired = Notification.Name("healthAuthExpired") } ``` -------------------------------- ### Python: Open Wearables Client Usage Example Source: https://docs.openwearables.io/dev-guides/backend-e2e-integration This Python code demonstrates the core functionalities of the Open Wearables client. It shows how to initialize the client, create or retrieve a user, obtain an OAuth URL for Garmin, check connection status, sync data, and fetch workout data for a specified date range. It requires the OpenWearablesClient to be installed and configured. ```python async def main(): client = OpenWearablesClient( base_url="http://localhost:8000", api_key="sk-your-api-key" ) # 1. Create or get user user = await client.get_or_create_user( email="user@example.com", external_id="auth0|123456" ) user_id = user["id"] # 2. Get OAuth URL for Garmin auth_url = await client.get_auth_url( provider="garmin", user_id=user_id, redirect_uri="https://myapp.com/callback" ) print(f"Redirect user to: {auth_url}") # 3. After OAuth callback, check connections connections = await client.get_connections(user_id) garmin_connected = any( c["provider"] == "garmin" and c["status"] == "active" for c in connections ) if garmin_connected: # 4. Sync data await client.sync_provider("garmin", user_id) # 5. Fetch workouts workouts = await client.get_workouts( user_id, start_date="2025-01-01", end_date="2025-01-31" ) print(f"Found {len(workouts)} workouts") ``` -------------------------------- ### Start Open Wearables Backend Source: https://docs.openwearables.io/dev-guides/ngrok-setup Starts the Open Wearables backend services using Docker Compose. This command assumes you have Docker installed and the necessary docker-compose.yml file in your project directory. ```bash docker compose up ``` -------------------------------- ### Manage Application Services with Docker Source: https://docs.openwearables.io/quickstart Commands to orchestrate the full stack using Docker Compose, including production-ready startup and development modes with hot-reloading. ```bash docker compose up -d docker compose watch ``` -------------------------------- ### Test API and Seed Data Source: https://docs.openwearables.io/quickstart Commands to verify the server status, seed the database with sample data, and perform authenticated API requests. ```bash curl http://localhost:8000/ make seed curl http://localhost:8000/api/v1/users -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` -------------------------------- ### POST /api/v1/providers/suunto/users/{user_id}/sync Source: https://docs.openwearables.io/api-reference/guides/provider-setup Triggers a data sync for Suunto users, supporting pagination and filtering by modification time. ```APIDOC ## POST /api/v1/providers/suunto/users/{user_id}/sync ### Description Syncs Suunto data including workouts and 24/7 metrics. Supports pagination and time-based filtering. ### Method POST ### Endpoint /api/v1/providers/suunto/users/{user_id}/sync ### Parameters #### Path Parameters - **user_id** (string) - Required - The unique identifier for the user. #### Query Parameters - **data_type** (string) - Required - 'workouts', '247', or 'all'. - **since** (integer) - Optional - Unix timestamp to sync from (default: 0). - **limit** (integer) - Optional - Items per request (default: 50, max: 100). - **offset** (integer) - Optional - Pagination offset (default: 0). ### Request Example curl -X POST "http://localhost:8000/api/v1/providers/suunto/users/{user_id}/sync?data_type=all&since=1735689600&limit=100" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ### Response #### Success Response (200) - **status** (string) - Sync initiation status. ``` -------------------------------- ### Flutter Get Dependencies Source: https://docs.openwearables.io/sdk/flutter Command to run after updating pubspec.yaml to download and install project dependencies. ```bash flutter pub get ``` -------------------------------- ### Cursor Pagination Example Source: https://docs.openwearables.io/api-reference/introduction Example HTTP GET request illustrating cursor pagination for data endpoints like timeseries. Utilizes a 'cursor' parameter obtained from a previous response. ```http GET /api/v1/users/{user_id}/timeseries?cursor=abc123&limit=50 ``` -------------------------------- ### Install ngrok via Homebrew Source: https://docs.openwearables.io/dev-guides/ngrok-setup Installs ngrok on macOS using the Homebrew package manager. This is a convenient way to get ngrok set up for local development. ```bash # macOS brew install ngrok ``` -------------------------------- ### List Enabled Providers Source: https://docs.openwearables.io/api-reference/guides/provider-setup Fetches a list of all wearable providers currently enabled in the Open Wearables instance. Useful for determining which integrations are available for user authentication. ```bash curl -X GET "http://localhost:8000/api/v1/oauth/providers?enabled_only=true" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` ```json [ { "provider": "garmin", "name": "Garmin", "has_cloud_api": true, "is_enabled": true, "icon_url": "/static/provider-icons/garmin.svg" } ] ``` -------------------------------- ### Sync Polar Data via API Source: https://docs.openwearables.io/api-reference/guides/provider-setup Shows how to initiate a Polar data sync, with optional parameters to include detailed samples, heart rate zones, and GPS route data. ```bash # Basic sync curl -X POST "http://localhost:8000/api/v1/providers/polar/users/{user_id}/sync" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" # With additional data curl -X POST "http://localhost:8000/api/v1/providers/polar/users/{user_id}/sync?samples=true&zones=true&route=true" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` -------------------------------- ### Sync Garmin Data via API Source: https://docs.openwearables.io/api-reference/guides/provider-setup Demonstrates how to trigger a data sync for Garmin users using either ISO 8601 date strings or Unix timestamps. Requires an API key in the request header. ```bash # Using ISO 8601 dates curl -X POST "http://localhost:8000/api/v1/providers/garmin/users/{user_id}/sync?data_type=all&summary_start_time=2025-01-01T00:00:00Z&summary_end_time=2025-01-31T00:00:00Z" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" # Using Unix timestamps curl -X POST "http://localhost:8000/api/v1/providers/garmin/users/{user_id}/sync?data_type=all&summary_start_time=1735689600&summary_end_time=1738368000" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` -------------------------------- ### Configure Open Wearables Health SDK (Dart) Source: https://docs.openwearables.io/sdk/flutter/integration This Dart example shows how to configure the Open Wearables Health SDK at application startup. It requires importing the SDK and calling the `configure` method with the API host URL. This step is crucial for initializing the SDK and restoring any existing session. It also provides an example for self-hosted Open Wearables instances. ```dart import 'package:open_wearables_health_sdk/open_wearables_health_sdk.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); // Configure SDK with your backend host - this also restores any existing session await OpenWearablesHealthSdk.configure( host: 'https://api.openwearables.io', ); runApp(MyApp()); } // For self-hosted Open Wearables await OpenWearablesHealthSdk.configure( host: 'https://your-domain.com', ); ``` -------------------------------- ### POST /api/v1/providers/garmin/users/{user_id}/sync Source: https://docs.openwearables.io/api-reference/guides/provider-setup Triggers a data sync for Garmin users using optional time range parameters for backfilling data. ```APIDOC ## POST /api/v1/providers/garmin/users/{user_id}/sync ### Description Triggers a data synchronization for a specific Garmin user. Supports backfilling data using ISO 8601 or Unix timestamps. ### Method POST ### Endpoint /api/v1/providers/garmin/users/{user_id}/sync ### Parameters #### Path Parameters - **user_id** (string) - Required - The unique identifier for the user. #### Query Parameters - **data_type** (string) - Required - Type of data to sync (e.g., 'all'). - **summary_start_time** (string) - Optional - Start of sync range (ISO 8601 or Unix timestamp). - **summary_end_time** (string) - Optional - End of sync range (ISO 8601 or Unix timestamp). ### Request Example curl -X POST "http://localhost:8000/api/v1/providers/garmin/users/{user_id}/sync?data_type=all&summary_start_time=2025-01-01T00:00:00Z&summary_end_time=2025-01-31T00:00:00Z" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ### Response #### Success Response (200) - **status** (string) - Sync initiation status. ``` -------------------------------- ### Configure Whoop OAuth Environment Variables Source: https://docs.openwearables.io/api-reference/guides/provider-setup Sets the necessary environment variables for Whoop OAuth 2.0 integration, including client credentials and required scopes. ```bash WHOOP_CLIENT_ID=your-client-id WHOOP_CLIENT_SECRET=your-client-secret WHOOP_REDIRECT_URI=http://localhost:8000/api/v1/oauth/whoop/callback WHOOP_DEFAULT_SCOPE=offline read:cycles read:sleep read:recovery read:workout ``` -------------------------------- ### Restart Services using Docker Compose Source: https://docs.openwearables.io/dev-guides/aws-setup This command sequence restarts services managed by Docker Compose. It first stops and removes existing containers and then starts new ones based on the docker-compose configuration. This is essential after updating environment variables or configurations. ```bash # Using Docker Compose docker compose down docker compose up -d ``` -------------------------------- ### Update Environment Variables for AWS and SQS Source: https://docs.openwearables.io/dev-guides/aws-setup This example shows how to configure environment variables for AWS S3 and SQS. It includes necessary credentials and endpoint URLs. These variables are typically used by applications to interact with AWS services. ```dotenv # AWS S3 Configuration AWS_BUCKET_NAME=open-wearables-xml AWS_REGION=eu-north-1 AWS_ACCESS_KEY_ID=your-access-key-id AWS_SECRET_ACCESS_KEY=your-secret-access-key # SQS Configuration SQS_QUEUE_URL=https://sqs.eu-north-1.amazonaws.com/123456789012/owear-queue ``` -------------------------------- ### GET /api/v1/oauth/providers Source: https://docs.openwearables.io/api-reference/guides/provider-setup Retrieves a list of available OAuth providers that are enabled in your Open Wearables instance. This helps in determining which providers can be integrated for data synchronization. ```APIDOC ## GET /api/v1/oauth/providers ### Description Retrieves a list of available OAuth providers that are enabled in your Open Wearables instance. This helps in determining which providers can be integrated for data synchronization. ### Method GET ### Endpoint `/api/v1/oauth/providers` ### Parameters #### Query Parameters - **enabled_only** (boolean) - Optional - If set to `true`, only enabled providers will be returned. Defaults to `false`. ### Request Example ```bash curl -X GET "http://localhost:8000/api/v1/oauth/providers?enabled_only=true" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` ### Response #### Success Response (200) - **providers** (array) - A list of available OAuth providers. - **provider** (string) - The internal name of the provider (e.g., 'garmin'). - **name** (string) - The display name of the provider (e.g., 'Garmin'). - **has_cloud_api** (boolean) - Indicates if the provider offers a cloud API for data sync. - **is_enabled** (boolean) - Indicates if the provider is currently enabled in the instance. - **icon_url** (string) - The URL to the provider's icon. #### Response Example ```json [ { "provider": "garmin", "name": "Garmin", "has_cloud_api": true, "is_enabled": true, "icon_url": "/static/provider-icons/garmin.svg" } ] ``` ``` -------------------------------- ### GET /api/v1/users/{user_id}/connections Source: https://docs.openwearables.io/api-reference/guides/provider-setup Retrieves the connection status for a specific user across different providers. This endpoint is useful for verifying if a user has an active connection before initiating a data sync. ```APIDOC ## GET /api/v1/users/{user_id}/connections ### Description Retrieves the connection status for a specific user across different providers. This endpoint is useful for verifying if a user has an active connection before initiating a data sync. ### Method GET ### Endpoint `/api/v1/users/{user_id}/connections` ### Parameters #### Path Parameters - **user_id** (string) - Required - The unique identifier for the user. ### Request Example ```bash curl -X GET "http://localhost:8000/api/v1/users/{user_id}/connections" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` ### Response #### Success Response (200) - **connections** (array) - A list of connection objects for the user. - **id** (string) - The unique identifier for the connection. - **user_id** (string) - The ID of the user associated with the connection. - **provider** (string) - The name of the wearable provider (e.g., 'garmin'). - **status** (string) - The connection status. Possible values: `active`, `revoked`, `expired`. - **last_synced_at** (string) - The timestamp of the last successful sync. - **created_at** (string) - The timestamp when the connection was created. - **updated_at** (string) - The timestamp when the connection was last updated. #### Response Example ```json [ { "id": "550e8400-e29b-41d4-a716-446655440000", "user_id": "user-uuid", "provider": "garmin", "status": "active", "last_synced_at": "2025-01-15T12:00:00Z", "created_at": "2025-01-15T10:00:00Z", "updated_at": "2025-01-15T12:00:00Z" } ] ``` If no connection exists for a provider, the user needs to complete OAuth first. ``` -------------------------------- ### Local Development Environment Setup Source: https://docs.openwearables.io/sdk/flutter/example-app Commands to deploy a local instance of the Open Wearables backend using Docker for testing purposes. ```bash git clone https://github.com/the-momentum/open-wearables.git cd open-wearables docker compose up -d ``` -------------------------------- ### SDK Initialization and Authentication Source: https://docs.openwearables.io/sdk/flutter/example-app Demonstrates how to initialize the SDK with a host URL and authenticate a user by redeeming an invitation code to obtain credentials. ```dart await OpenWearablesHealthSdk.configure( host: hostUrl, ); // Redeem invitation code to get credentials final response = await http.post( Uri.parse('$host/api/v1/sdk/invitation-codes/$code/redeem'), ); if (response.statusCode != 200) { throw Exception('Invitation redeem failed: ${response.statusCode}'); } final data = json.decode(response.body); // Sign in with returned credentials await OpenWearablesHealthSdk.signIn( userId: data['user_id'], accessToken: data['access_token'], refreshToken: data['refresh_token'], ); ``` -------------------------------- ### Initialize and Configure OpenWearables SDK Source: https://docs.openwearables.io/sdk/android Demonstrates the minimal setup for the OpenWearables SDK, including initialization, logging, authentication error handling, and session management. It also covers the process of signing in, setting the data provider, and requesting health data permissions. ```kotlin import com.openwearables.health.sdk.OpenWearablesHealthSDK class HealthService(private val context: Context) { private lateinit var sdk: OpenWearablesHealthSDK fun initialize() { // 1. Initialize the SDK sdk = OpenWearablesHealthSDK.initialize(context) // 2. Set up logging (optional) sdk.logListener = { message -> Log.d("HealthSDK", message) } // 3. Handle auth errors (optional) sdk.authErrorListener = { error -> Log.e("HealthSDK", "Auth error: $error") } // 4. Configure with your backend host sdk.configure(host = "https://api.openwearables.io") // 5. Check if already signed in if (sdk.isSessionValid()) { Log.d("HealthSDK", "Session restored") return } } suspend fun connect(userId: String, accessToken: String, refreshToken: String?) { // 6. Sign in sdk.signIn( userId = userId, accessToken = accessToken, refreshToken = refreshToken, apiKey = null ) // 7. Set provider sdk.setProvider("google") // or "samsung" // 8. Request permissions val authorized = sdk.requestAuthorization( types = listOf("steps", "heartRate", "sleep", "workout") ) if (!authorized) { Log.w("HealthSDK", "Health permissions were denied") return } // 9. Start background sync sdk.startBackgroundSync() } } ``` -------------------------------- ### Strava Webhook Verification (GET /webhook) Source: https://docs.openwearables.io/dev-guides/how-to-add-new-provider Handles the GET request from Strava for webhook subscription verification. It checks the provided verify token and echoes back the challenge. ```APIDOC ## GET /webhook ### Description Handles the GET request from Strava for webhook subscription verification. It checks the provided verify token and echoes back the challenge. ### Method GET ### Endpoint /webhook ### Query Parameters - **hub_mode** (string) - Required - The mode of the subscription request (e.g., 'subscribe'). - **hub_verify_token** (string) - Required - The token provided by the user to verify the subscription. - **hub_challenge** (string) - Required - The challenge code sent by Strava to verify the endpoint. ### Response #### Success Response (200) - **hub.challenge** (string) - The challenge code echoed back to Strava. #### Response Example ```json { "hub.challenge": "some_challenge_code" } ``` #### Error Response (403) - **detail** (string) - Indicates an invalid verify token. #### Error Response Example ```json { "detail": "Invalid verify token" } ``` ``` -------------------------------- ### Start Background Sync with OpenWearables Health SDK Source: https://docs.openwearables.io/sdk/android/integration This function demonstrates how to initiate background synchronization of health data using the OpenWearables Health SDK. It logs whether the sync is active after starting. ```kotlin suspend fun startSync() { val sdk = OpenWearablesHealthSDK.getInstance() sdk.startBackgroundSync() Log.d("HealthSDK", "Background sync started: ${sdk.isSyncActive()}") } ``` -------------------------------- ### Data Normalization Example (JSON) Source: https://docs.openwearables.io/providers/coverage An example of how Open Wearables normalizes incoming data, including timestamp in UTC and standardized units for metrics like heart rate. ```json { "timestamp": "2025-01-07T14:30:00Z", "type": "heart_rate", "value": 72, "unit": "bpm" } ``` -------------------------------- ### Enable Background Sync Source: https://docs.openwearables.io/sdk/flutter/integration Starts the background synchronization process to ensure health data is updated while the application is not in the foreground. ```dart await OpenWearablesHealthSdk.startBackgroundSync(); // Check sync status print('Sync active: ${OpenWearablesHealthSdk.isSyncActive}'); ``` -------------------------------- ### GET /api/v1/users/{USER_ID}/events/workouts Source: https://docs.openwearables.io/dev-guides/backend-e2e-integration Retrieves a list of workout events for a specific user within a given date range. ```APIDOC ## GET /api/v1/users/{USER_ID}/events/workouts ### Description Retrieves a list of workout events for a specific user within a given date range. ### Method GET ### Endpoint `/api/v1/users/{USER_ID}/events/workouts` ### Parameters #### Path Parameters - **USER_ID** (string) - Required - The unique identifier for the user. #### Query Parameters - **start_date** (string) - Required - The start date for filtering workouts (YYYY-MM-DD). - **end_date** (string) - Required - The end date for filtering workouts (YYYY-MM-DD). ### Request Example ```bash curl "http://localhost:8000/api/v1/users/USER_ID/events/workouts?start_date=2025-01-01&end_date=2025-01-31" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` ### Response #### Success Response (200) - **data** (array) - An array of workout objects. - **id** (string) - Unique identifier for the workout. - **type** (string) - The type of workout (e.g., 'running'). - **name** (string) - The name of the workout. - **start_time** (string) - The start time of the workout in ISO 8601 format. - **end_time** (string) - The end time of the workout in ISO 8601 format. - **duration_seconds** (number) - The duration of the workout in seconds. - **calories_kcal** (number) - Calories burned during the workout in kcal. - **distance_meters** (number) - Distance covered in meters. - **avg_heart_rate_bpm** (number) - Average heart rate during the workout in BPM. - **max_heart_rate_bpm** (number) - Maximum heart rate during the workout in BPM. - **source** (object) - Information about the data source. - **provider** (string) - The wearable provider (e.g., 'garmin'). - **device** (string) - The specific device used. - **pagination** (object) - Pagination details. - **cursor** (string|null) - Cursor for next page. - **has_more** (boolean) - Indicates if there are more results. #### Response Example ```json { "data": [ { "id": "abc123...", "type": "running", "name": "Morning Run", "start_time": "2025-01-15T07:30:00Z", "end_time": "2025-01-15T08:15:00Z", "duration_seconds": 2700, "calories_kcal": 450.5, "distance_meters": 5200.0, "avg_heart_rate_bpm": 155, "max_heart_rate_bpm": 178, "source": { "provider": "garmin", "device": "Garmin Forerunner 255" } } ], "pagination": { "cursor": null, "has_more": false } } ``` ``` -------------------------------- ### Data Sync Success Response Source: https://docs.openwearables.io/sdk/flutter/integration Example JSON response returned by the sync endpoint upon successful data processing. ```json { "status": "ok", "synced_records": 42 } ``` -------------------------------- ### Create Provider Directory Structure (Bash) Source: https://docs.openwearables.io/dev-guides/how-to-add-new-provider This snippet shows the expected directory structure for a new provider integration within the OpenWearables backend. It includes essential files like strategy, OAuth handler, and workouts data handler. ```bash backend/app/services/providers/suunto/ ├── __init__.py ├── strategy.py # Provider strategy implementation ├── oauth.py # OAuth handler (skip if PUSH-only) └── workouts.py # Workouts data handler ``` -------------------------------- ### POST /api/v1/providers/polar/users/{user_id}/sync Source: https://docs.openwearables.io/api-reference/guides/provider-setup Triggers a data sync for Polar users, allowing for the inclusion of detailed samples, zones, and route data. ```APIDOC ## POST /api/v1/providers/polar/users/{user_id}/sync ### Description Initiates a sync for Polar user data. Optional parameters allow for fetching granular workout details. ### Method POST ### Endpoint /api/v1/providers/polar/users/{user_id}/sync ### Parameters #### Path Parameters - **user_id** (string) - Required - The unique identifier for the user. #### Query Parameters - **samples** (boolean) - Optional - Include detailed sample data (default: false). - **zones** (boolean) - Optional - Include heart rate zone information (default: false). - **route** (boolean) - Optional - Include GPS route data (default: false). ### Request Example curl -X POST "http://localhost:8000/api/v1/providers/polar/users/{user_id}/sync?samples=true&zones=true&route=true" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ### Response #### Success Response (200) - **status** (string) - Sync initiation status. ``` -------------------------------- ### Configure SDK Host and Initialize Source: https://docs.openwearables.io/sdk/android/troubleshooting Initializes the SDK and configures the host for data synchronization. This should be called on application launch to ensure proper connection to the OpenWearables API. ```kotlin // In Application.onCreate() val sdk = OpenWearablesHealthSDK.initialize(this) sdk.configure(host = "https://api.openwearables.io") ``` -------------------------------- ### Create user Source: https://docs.openwearables.io/api-reference/introduction Creates a new user. ```APIDOC ## POST /api/v1/users ### Description Creates a new user. ### Method POST ### Endpoint /api/v1/users #### Request Body - **name** (string) - Required - The name of the user. ### Request Example ```json { "name": "Jane Smith" } ``` ### Response #### Success Response (201) - **user_id** (string) - The ID of the newly created user. - **name** (string) - The name of the user. #### Response Example ```json { "user_id": "user456", "name": "Jane Smith" } ``` ``` -------------------------------- ### Configure SDK and Handle Authentication Source: https://docs.openwearables.io/sdk/flutter/troubleshooting Illustrates the mandatory initialization sequence for the SDK. It emphasizes calling configure() before performing sign-in or background sync operations to avoid NotConfiguredException. ```dart await OpenWearablesHealthSdk.configure(host: 'https://api.openwearables.io'); await OpenWearablesHealthSdk.signIn( userId: 'usr_abc123', accessToken: accessToken, refreshToken: refreshToken, ); await OpenWearablesHealthSdk.startBackgroundSync(); ``` -------------------------------- ### GET /api/v1/users/{USER_ID}/events/sleep Source: https://docs.openwearables.io/dev-guides/backend-e2e-integration Retrieves a list of sleep session events for a specific user within a given date range. ```APIDOC ## GET /api/v1/users/{USER_ID}/events/sleep ### Description Retrieves a list of sleep session events for a specific user within a given date range. ### Method GET ### Endpoint `/api/v1/users/{USER_ID}/events/sleep` ### Parameters #### Path Parameters - **USER_ID** (string) - Required - The unique identifier for the user. #### Query Parameters - **start_date** (string) - Required - The start date for filtering sleep sessions (YYYY-MM-DD). - **end_date** (string) - Required - The end date for filtering sleep sessions (YYYY-MM-DD). ### Request Example ```bash curl "http://localhost:8000/api/v1/users/USER_ID/events/sleep?start_date=2025-01-01&end_date=2025-01-31" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` ### Response #### Success Response (200) - **data** (array) - An array of sleep session objects. - **id** (string) - Unique identifier for the sleep session. - **start_time** (string) - The start time of the sleep session in ISO 8601 format. - **end_time** (string) - The end time of the sleep session in ISO 8601 format. - **duration_seconds** (number) - The duration of the sleep session in seconds. - **efficiency_percent** (number) - Sleep efficiency percentage. - **is_nap** (boolean) - Indicates if the session was a nap. - **stages** (object) - Details about sleep stages. - **awake_seconds** (number) - Seconds spent awake. - **light_seconds** (number) - Seconds spent in light sleep. - **deep_seconds** (number) - Seconds spent in deep sleep. - **rem_seconds** (number) - Seconds spent in REM sleep. - **source** (object) - Information about the data source. - **provider** (string) - The wearable provider (e.g., 'suunto'). - **pagination** (object) - Pagination details. - **cursor** (string|null) - Cursor for next page. - **has_more** (boolean) - Indicates if there are more results. #### Response Example ```json { "data": [ { "id": "def456...", "start_time": "2025-01-15T22:30:00Z", "end_time": "2025-01-16T06:45:00Z", "duration_seconds": 29700, "efficiency_percent": 92.5, "is_nap": false, "stages": { "awake_seconds": 1200, "light_seconds": 10800, "deep_seconds": 7200, "rem_seconds": 10500 }, "source": { "provider": "suunto" } } ], "pagination": { "cursor": null, "has_more": false } } ``` ``` -------------------------------- ### Configure Whoop Credentials in .env File Source: https://docs.openwearables.io/providers/whoop-api-integration Set up environment variables for Whoop integration. This includes your Client ID, Client Secret, Redirect URI, and desired scopes. Ensure the Redirect URI matches your Developer Dashboard configuration. ```bash #--- Whoop --- WHOOP_CLIENT_ID=your-whoop-client-id WHOOP_CLIENT_SECRET=your-whoop-client-secret WHOOP_REDIRECT_URI=http://localhost:8000/api/v1/oauth/whoop/callback WHOOP_DEFAULT_SCOPE=offline read:cycles read:sleep read:recovery read:workout ``` -------------------------------- ### Authenticate User via SDK Source: https://docs.openwearables.io/sdk/flutter/integration Demonstrates how to sign in using either token-based authentication (recommended for production) or API key authentication (for internal tools). ```dart Future connectHealth() async { try { // 1. Get credentials from YOUR backend final response = await yourApi.post('/api/health/connect'); final credentials = json.decode(response.body); // 2. Sign in with the SDK final user = await OpenWearablesHealthSdk.signIn( userId: credentials['userId'], accessToken: credentials['accessToken'], refreshToken: credentials['refreshToken'], ); print('Connected: ${user.userId}'); } on SignInException catch (e) { print('Sign-in failed: ${e.message} (status: ${e.statusCode})'); } } // API Key Authentication final user = await OpenWearablesHealthSdk.signIn( userId: 'user123', apiKey: 'your_api_key', ); ``` -------------------------------- ### Initialize SDK on App Launch Source: https://docs.openwearables.io/sdk/ios/troubleshooting Ensures the SDK is configured during application startup to restore sync state and resume background tasks. ```swift // In AppDelegate or app init sdk.configure(host: "https://api.openwearables.io") ``` -------------------------------- ### GET /api/v1/users/{USER_ID}/timeseries Source: https://docs.openwearables.io/dev-guides/backend-e2e-integration Retrieves timeseries health data for a specific user within a given time range and for specified data types. ```APIDOC ## GET /api/v1/users/{USER_ID}/timeseries ### Description Retrieves timeseries health data for a specific user within a given time range and for specified data types. ### Method GET ### Endpoint `/api/v1/users/{USER_ID}/timeseries` ### Parameters #### Path Parameters - **USER_ID** (string) - Required - The unique identifier for the user. #### Query Parameters - **start_time** (string) - Required - The start timestamp for the timeseries data (ISO 8601 format). - **end_time** (string) - Required - The end timestamp for the timeseries data (ISO 8601 format). - **types** (string) - Required - The type(s) of timeseries data to retrieve (e.g., 'heart_rate', 'steps'). This parameter can be repeated to request multiple types. ### Request Example ```bash curl "http://localhost:8000/api/v1/users/USER_ID/timeseries?start_time=2025-01-15T00:00:00Z&end_time=2025-01-15T23:59:59Z&types=heart_rate&types=steps" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` ### Response #### Success Response (200) - **data** (object) - An object containing timeseries data, keyed by data type. - **heart_rate** (array) - Array of heart rate data points. - **timestamp** (string) - Timestamp of the data point. - **value** (number) - Heart rate value in BPM. - **steps** (array) - Array of step count data points. - **timestamp** (string) - Timestamp of the data point. - **value** (integer) - Step count value. #### Response Example ```json { "data": { "heart_rate": [ {"timestamp": "2025-01-15T07:30:00Z", "value": 75}, {"timestamp": "2025-01-15T07:31:00Z", "value": 76} ], "steps": [ {"timestamp": "2025-01-15T00:00:00Z", "value": 0}, {"timestamp": "2025-01-15T00:01:00Z", "value": 10} ] } } ``` ### Error Handling - **Warning**: All three parameters (`start_time`, `end_time`, and `types`) are required. ``` -------------------------------- ### Fetch Workout Data (Bash) Source: https://docs.openwearables.io/api-reference/guides/quick-integration Retrieves workout session data for a user within a specified date range. Requires user ID, start date, and end date. ```bash curl -X GET "http://localhost:8000/api/v1/users/550e8400-e29b-41d4-a716-446655440000/events/workouts?start_date=2025-01-01T00:00:00Z&end_date=2025-01-31T00:00:00Z" \ -H "X-Open-Wearables-API-Key: YOUR_API_KEY" ``` -------------------------------- ### Configure Strava API Credentials in .env Source: https://docs.openwearables.io/providers/strava-api-integration Set up your Strava API credentials and webhook configuration by adding these variables to your .env file. This includes your Strava Client ID, Client Secret, redirect URI, default OAuth scopes, and a webhook verification token. ```bash #--- Strava --- STRAVA_CLIENT_ID=your-strava-client-id STRAVA_CLIENT_SECRET=your-strava-client-secret STRAVA_REDIRECT_URI=http://localhost:8000/api/v1/oauth/strava/callback STRAVA_DEFAULT_SCOPE=activity:read_all,profile:read_all STRAVA_WEBHOOK_VERIFY_TOKEN=your-secret-verify-token ```