Releases: StuMason/polar-flow-server
v1.3.4 - Fix 403 Forbidden for all self-hosted users
Bug Fix
Fixed: All self-hosted users getting 403 Forbidden errors on every sync (#19).
Root Cause
The Polar AccessLink API requires a user registration step (POST /v3/users) after OAuth authorization before any data endpoints can be accessed. This step was missing from the OAuth callback flow, causing all data sync requests to return 403.
What Changed
- Added user registration call during OAuth callback (handles already-registered users gracefully via 409)
- Existing users who re-authenticate will also benefit as the registration is idempotent
Action Required
Existing users experiencing 403 errors: After updating, disconnect and reconnect your Polar account via the admin panel (Settings → Reset OAuth → Re-authorize). This will trigger the registration step.
v1.3.3
[1.3.3] - 2026-01-21
Fixed
Partial Sync Failure Handling (Issue #19)
- Sync now continues when individual Polar API endpoints fail (e.g., 403 on sleep)
- Previously, a single endpoint failure would stop the entire sync with no data saved
- Now syncs each endpoint independently - failures are captured but don't block other data
Manual Sync Audit Logging
- Admin "Sync Now" button now creates
SyncLogentries for proper audit trail - Previously, manual syncs bypassed
SyncOrchestratorand weren't logged
Added
SyncResultdataclass to track both successful records and per-endpoint errors- Actionable error messages for common HTTP errors:
- 403: Guidance about Polar data sharing consent settings
- 401: Token expiration/re-authentication needed
- 429: Rate limit information
- Partial success UI template showing both synced data and errors
- Dynamic endpoint display in templates (all 13 data types now shown)
- API sync endpoint now returns
status: "partial"with error details when some endpoints fail - Expandable sync log rows in admin dashboard showing full details (records, errors, analytics, metadata)
Changed
SyncService.sync_user()now returnsSyncResultinstead ofdict[str, int]SyncOrchestratorproperly tracks partial success status inSyncLog- Admin sync templates dynamically iterate over all endpoints instead of hardcoding
v1.3.0 - Security Hardening & API Versioning
Breaking Changes ⚠️
All API data endpoints now use /api/v1 prefix:
/users/{id}/sleep→/api/v1/users/{id}/sleep/users/{id}/activity→/api/v1/users/{id}/activity/users/{id}/recharge→/api/v1/users/{id}/recharge- etc.
Unchanged: /health and /oauth/* remain at root level.
Security Improvements 🔒
- Login rate limiting - 5 failed attempts triggers 15min lockout
- Bounded OAuth state caches - Prevents memory exhaustion attacks (max 100 entries)
- Callback URL validation - HTTPS required in production, strict localhost check
- Session cookie security -
secure,httponly,samesite=laxflags - SRI integrity hashes - CDN scripts verified via subresource integrity
- IP spoofing prevention - Only trust proxy headers from localhost
- Tightened CSRF exclusions - Admin routes now require CSRF token
- Thread-safe locking - Async locks on all shared state
New Features ✨
- API key management - Regenerate/revoke keys from admin dashboard
- Per-user rate limiting - 1000 requests/hour per API key
Upgrade Notes
Update your API clients to use the new /api/v1 prefix:
# Before
curl -H "X-API-Key: pfk_..." "http://localhost:8000/users/{id}/sleep"
# After
curl -H "X-API-Key: pfk_..." "http://localhost:8000/api/v1/users/{id}/sleep"Docker
docker pull stumason/polar-flow-server:1.3.0
# or
docker pull stumason/polar-flow-server:latestv1.2.0 - Analytics Dashboard & Comprehensive Docs
What's New
Dashboard Analytics
- Personal Baselines section showing:
- All calculated baselines (HRV, sleep score, resting HR, training load, etc.)
- Rolling averages (7-day, 30-day) with percentage change indicators
- Min/max ranges and sample counts
- Status indicators (ready, partial, insufficient)
- Detected Patterns section displaying:
- Correlations (sleep-HRV, training-recovery, activity-sleep)
- Composite risk scores (overtraining risk, recovery readiness)
- Trends (HRV, sleep, fitness)
- Statistical significance levels with visual styling
- Interpretations and contributing factors
- Empty state guidance explaining analytics requirements (7+ days of data)
Documentation
- New Integration Guide for Laravel/SaaS consumers
- Complete Laravel service class example
- HTTP client setup and usage
- Caching strategies
- Error handling patterns
- LLM-friendly docs (
llms.txt) for AI tools - Mermaid diagrams replacing ASCII art throughout docs
Links
Full Changelog: v1.1.0...v1.2.0
v1.1.0 - Automatic Background Sync
What's New
Automatic Background Sync
- Smart Scheduler: APScheduler-powered background syncing with configurable intervals
- Priority Queue: Users prioritized by sync urgency (CRITICAL > HIGH > NORMAL > LOW)
- Rate-Limit Aware: Respects Polar API limits (15-min and 24-hour windows)
- Complete Audit Trail: Every sync logged with
SyncLogmodel
Admin Dashboard Updates
- Sync scheduler status (running state, next run, 24h stats)
- Recent sync history table
- Biosensing data counts (SpO2, ECG, Temperature)
- Analytics counts (Baselines, Patterns)
Configuration
SYNC_ENABLED=true # Enable/disable automatic syncing
SYNC_INTERVAL_MINUTES=60 # Minutes between sync cycles
SYNC_ON_STARTUP=false # Run sync immediately on startup
SYNC_MAX_USERS_PER_RUN=10 # Max users per sync cycle
SYNC_STAGGER_SECONDS=5 # Delay between user syncsBug Fixes
- Alertness scale corrected from /5 to /10
Upgrade Notes
Run migrations after upgrading:
uv run alembic upgrade headFull Changelog: v1.0.0...v1.1.0
v0.2.0 - SaaS OAuth Flow & Per-User API Keys
What's New
This release adds full SaaS/multi-user support, allowing any Polar user to connect their account to your application.
Features
- Per-User API Keys - Each user gets their own API key via OAuth flow
- Rate Limiting - 1000 requests/hour per key with
X-RateLimit-*headers - OAuth Integration - External apps (Laravel, mobile, etc.) can connect users
- Key Management - Regenerate, revoke, and check key status
- Settings UI - Reset OAuth credentials from admin dashboard
OAuth Flow for SaaS
Your App → polar-flow-server → Polar OAuth → User authorizes → API key returned
Any Polar user can:
- Click "Connect Polar" in your app
- Log in with their Polar credentials
- Authorize access
- Get an API key scoped to their data
Documentation
- Complete OAuth integration guide with diagrams
- Step-by-step instructions for Laravel/mobile integration
- Polar Admin setup instructions
Breaking Changes
None - fully backwards compatible with v0.1.x
Full Changelog: v0.1.0...v0.2.0