Open Wearables uses two authentication methods depending on your use case: API Keys for server-to-server communication, and SDK Tokens for user-scoped mobile/web applications.
Authentication Methods
API Keys Server-side authentication for backend services. Full access to all users and operations.
SDK Tokens User-scoped authentication for mobile/web apps. Limited to specific user’s data.
API Keys
API keys provide full access to your Open Wearables account and should only be used in secure, server-side environments.
Creating API Keys
Log in to dashboard
Navigate to the Open Wearables dashboard and authenticate as an admin.
Generate API key
Request a new API key via the API: curl -X POST https://api.openwearables.com/api/v1/api-keys \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Server"
}'
Response: {
"id" : "key_abc123def456" ,
"key" : "ow_live_1234567890abcdefghijklmnopqrstuvwxyz" ,
"name" : "Production Server" ,
"created_at" : "2026-03-07T10:30:00Z" ,
"last_used_at" : null
}
Store securely
The API key is only shown once. Store it securely in your environment variables or secrets manager.
# .env file
OPENWEARABLES_API_KEY = ow_live_1234567890abcdefghijklmnopqrstuvwxyz
Using API Keys
Include your API key in the Authorization header as a Bearer token:
curl -X GET https://api.openwearables.com/api/v1/users \
-H "Authorization: Bearer ow_live_1234567890abcdefghijklmnopqrstuvwxyz"
import requests
api_key = "ow_live_1234567890abcdefghijklmnopqrstuvwxyz"
headers = { "Authorization" : f "Bearer { api_key } " }
response = requests.get(
"https://api.openwearables.com/api/v1/users" ,
headers = headers
)
users = response.json()
Managing API Keys
List API Keys
curl -X GET https://api.openwearables.com/api/v1/api-keys \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
Update API Key
curl -X PATCH https://api.openwearables.com/api/v1/api-keys/key_abc123def456 \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Server - Updated"
}'
Rotate API Key
Rotate an API key to generate a new key and invalidate the old one:
curl -X POST https://api.openwearables.com/api/v1/api-keys/key_abc123def456/rotate \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
The old key is immediately invalidated. Update your application with the new key before rotating.
Delete API Key
curl -X DELETE https://api.openwearables.com/api/v1/api-keys/key_abc123def456 \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
SDK Tokens
SDK tokens are user-scoped JWTs designed for mobile and web applications. They provide access only to a specific user’s data.
Applications
Before generating SDK tokens, create an application to get credentials:
Create application
curl -X POST https://api.openwearables.com/api/v1/applications \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "My Mobile App"
}'
Response: {
"id" : "app_uuid" ,
"app_id" : "app_abc123" ,
"name" : "My Mobile App" ,
"app_secret" : "secret_xyz789" ,
"created_at" : "2026-03-07T10:30:00Z"
}
Store credentials
The app_secret is only shown once. Store it securely - you’ll need it to generate SDK tokens.
Generating SDK Tokens
SDK tokens are generated for specific users. Two methods are available:
Method 1: Using Application Credentials
Exchange your app credentials for a user-scoped token:
curl -X POST https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/token \
-H "Content-Type: application/json" \
-d '{
"app_id": "app_abc123",
"app_secret": "secret_xyz789"
}'
Response:
{
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"token_type" : "bearer" ,
"refresh_token" : "rt_abc123def456" ,
"expires_in" : 3600
}
Method 2: Using Admin Authentication
As an admin, generate tokens without app credentials:
curl -X POST https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/token \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
Admin-generated tokens include admin:{developer_id} in the token for audit trails.
Using SDK Tokens
curl -X GET https://api.openwearables.com/api/v1/users/550e8400-e29b-41d4-a716-446655440000/events/workouts?start_date=2026-03-01 & end_date = 2026-03-07 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
iOS/Swift
Android/Kotlin
React/JavaScript
import Foundation
class OpenWearablesSDK {
let userId: String
var accessToken: String
init ( userId : String ) {
self . userId = userId
self . accessToken = ""
}
func authenticate ( appId : String , appSecret : String ) async throws {
let url = URL ( string : "https://api.openwearables.com/api/v1/users/ \( userId ) /token" ) !
var request = URLRequest ( url : url)
request. httpMethod = "POST"
request. addValue ( "application/json" , forHTTPHeaderField : "Content-Type" )
let body = [ "app_id" : appId, "app_secret" : appSecret]
request. httpBody = try JSONEncoder (). encode (body)
let (data, _ ) = try await URLSession. shared . data ( for : request)
let response = try JSONDecoder (). decode (TokenResponse. self , from : data)
self . accessToken = response. accessToken
}
func getWorkouts ( startDate : Date, endDate : Date) async throws -> [Workout] {
let dateFormatter = ISO8601DateFormatter ()
let start = dateFormatter. string ( from : startDate)
let end = dateFormatter. string ( from : endDate)
let url = URL ( string : "https://api.openwearables.com/api/v1/users/ \( userId ) /events/workouts?start_date= \( start ) &end_date= \( end ) " ) !
var request = URLRequest ( url : url)
request. addValue ( "Bearer \( accessToken ) " , forHTTPHeaderField : "Authorization" )
let (data, _ ) = try await URLSession. shared . data ( for : request)
let response = try JSONDecoder (). decode (WorkoutsResponse. self , from : data)
return response. data
}
}
Token Expiration and Refresh
SDK tokens expire after 60 minutes by default. Use refresh tokens to get new access tokens without re-authenticating:
curl -X POST https://api.openwearables.com/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "rt_abc123def456"
}'
Response:
{
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"token_type" : "bearer" ,
"refresh_token" : "rt_new123new456" ,
"expires_in" : 3600
}
Refresh tokens are single-use. Each refresh returns a new access token AND a new refresh token.
Security Best Practices
Never expose API keys or app secrets in client-side code, version control, or public repositories.
API Keys
✅ Store in environment variables or secrets managers
✅ Use separate keys for development, staging, and production
✅ Rotate keys regularly
✅ Delete unused keys
❌ Never commit keys to version control
❌ Never share keys via email or chat
SDK Tokens
✅ Generate tokens server-side when possible
✅ Use short expiration times (default: 60 minutes)
✅ Implement token refresh logic
✅ Store tokens securely on device (Keychain/KeyStore)
❌ Never hardcode app secrets in mobile apps
❌ Never log tokens or include in crash reports
Application Credentials
✅ Keep app_secret on server-side only
✅ Use token exchange flow for mobile apps
✅ Implement rate limiting on token generation
❌ Never include app_secret in mobile app bundles
Rate Limits
Authentication Type Rate Limit Window API Key 1000 requests per minute SDK Token 100 requests per minute per user
Rate limit headers are included in all responses:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1709809200
Error Responses
401 Unauthorized
401 Token Expired
429 Rate Limited
{
"detail" : "Invalid API key"
}
Next Steps
User Management Create and manage users
Accessing Data Retrieve health metrics and workouts