📚 Withings API Documentation

Complete API reference for Withings Health Data Integration

📖 Overview

This API provides access to Withings health data including measurements, activity, sleep, and device information.

Base URL: http://localhost:5001
API Version: v1
Server Status: ● Running

🔐 Authentication

This API uses OAuth 2.0 authentication flow with Withings. You must authenticate before accessing protected endpoints.

GET /api/status
Check authentication status and token information.
Response (200 OK):
{
  "authenticated": true,
  "userid": "12345678",
  "access_token_preview": "abc123def456...",
  "token_age_minutes": 45,
  "expires_in_minutes": 135,
  "last_sync": "2026-02-10T12:00:00.000Z",
  "last_data_fetch": "2026-02-10T12:00:00.000Z"
}
⚠️ Authentication Required: Most endpoints require valid authentication tokens. Use the authentication flow to obtain tokens.

🔌 API Endpoints

Root Endpoint

GET /
Server home page. Displays server status and information.

Documentation

GET /docs
This documentation page. Provides complete API reference.

OAuth Callback

GET /callback
OAuth 2.0 callback endpoint. Handles authorization code exchange.
Query Parameters:
Parameter Type Required Description
code string Required Authorization code from Withings
state string Required State parameter for CSRF protection
error string Optional Error code if authentication failed

Push notifications (continuous sync)

Set WITHINGS_WEBHOOK_URL to your public HTTPS URL. Withings only POSTs after successful subscribe (JSON status: 0 per category); until then your webhook receives nothing.

  • Path: this server exposes /webhook/withings (not /withings/webhook).
  • Developer Portal: allowlist the exact callback URL (same string as WITHINGS_WEBHOOK_URL), HTTPS.
  • Subscribe API URL: default is https://wbsapi.withings.net/notify. Do not set WITHINGS_NOTIFY_USE_V2=1 on Render unless Withings requires it; /v2/notify often returns Insufficient_scope for Public API.
  • How to subscribe: complete OAuth again (auto-subscribe after callback), or call POST /api/withings/register-webhooks with cognitoUserId (see example below). Confirm logs: Withings notify subscribed appli=….

After each successful OAuth, the server subscribes to Withings data categories (weight, activity, sleep, …). New cloud data triggers POST /webhook/withings, which runs the same sync as POST /api/withings/sync and writes to user_vitals.

GET HEAD /webhook/withings
Health check for Withings / load balancers (200 OK).
POST /webhook/withings
Withings notification (application/x-www-form-urlencoded). Body includes userid, appli, optional startdate/enddate.
POST /api/withings/register-webhooks
Re-subscribe using stored tokens (optional JSON body cognitoUserId). Requires WITHINGS_WEBHOOK_URL env.

💡 Usage Examples

Check Authentication Status

curl http://localhost:5001/api/status

Re-register Withings push subscriptions

After fixing env (e.g. unset WITHINGS_NOTIFY_USE_V2), call with the Vitals7 user id (Cognito sub):

curl -sS -X POST "http://localhost:5001/api/withings/register-webhooks" \
  -H "Content-Type: application/json" \
  -d '{"cognitoUserId":"YOUR_COGNITO_SUB_UUID"}'

View Documentation

# Open in browser
http://localhost:5001/docs

# Or use curl
curl http://localhost:5001/docs
💡 Tip: Use the interactive menu by running npm start for easier access to all features.

📝 CLI (optional)

# Interactive menu
npm start

# Authenticate (standalone script — prefer Vitals7 + server /login)
npm run auth

# Sync Withings → DynamoDB user_vitals (tokens must exist in vitals-di-tokens)
COGNITO_USER_ID=<uuid> npm run get-data
# or
node src/sync-to-user-vitals-cli.js <uuid>

# Check status
npm run status

Health data is not written to local JSON. Tokens: vitals-di-tokens. Readings: user_vitals. Use POST /api/withings/sync from the app when possible.