1.8k★by kesslerio
oura-analytics – OpenClaw Skill
oura-analytics is an OpenClaw Skills integration for data analytics workflows. Oura Ring data integration and analytics. Fetch sleep scores, readiness, activity, HRV, and trends from the Oura Cloud API. Generate automated reports, correlations with productivity, and trigger-based alerts for low recovery days. Requires OURA_API_TOKEN (get at cloud.ouraring.com).
Skill Snapshot
| name | oura-analytics |
| description | Oura Ring data integration and analytics. Fetch sleep scores, readiness, activity, HRV, and trends from the Oura Cloud API. Generate automated reports, correlations with productivity, and trigger-based alerts for low recovery days. Requires OURA_API_TOKEN (get at cloud.ouraring.com). OpenClaw Skills integration. |
| owner | kesslerio |
| repository | kesslerio/oura-analytics |
| language | Markdown |
| license | MIT |
| topics | |
| security | L1 |
| install | openclaw add @kesslerio/oura-analytics |
| last updated | Feb 7, 2026 |
Maintainer

name: oura-analytics description: Oura Ring data integration and analytics. Fetch sleep scores, readiness, activity, HRV, and trends from the Oura Cloud API. Generate automated reports, correlations with productivity, and trigger-based alerts for low recovery days. Requires OURA_API_TOKEN (get at cloud.ouraring.com). metadata: {"openclaw":{"requires":{"bins":["python3"],"env":["OURA_API_TOKEN"]},"homepage":"https://github.com/kesslerio/oura-analytics-openclaw-skill"}}
Oura Analytics
Quick Start
# Set Oura API token
export OURA_API_TOKEN="your_personal_access_token"
# Fetch sleep data (last 7 days)
python {baseDir}/scripts/oura_api.py sleep --days 7
# Get readiness summary
python {baseDir}/scripts/oura_api.py readiness --days 7
# Generate weekly report
python {baseDir}/scripts/oura_api.py report --type weekly
When to Use
Use this skill when:
- Fetching Oura Ring metrics (sleep, readiness, activity, HRV)
- Analyzing recovery trends over time
- Correlating sleep quality with productivity/events
- Setting up automated alerts for low readiness
- Generating daily/weekly/monthly health reports
Core Workflows
1. Data Fetching
export PYTHONPATH="{baseDir}/scripts"
python - <<'PY'
from oura_api import OuraClient
client = OuraClient(token="YOUR_TOKEN")
sleep_data = client.get_sleep(start_date="2026-01-01", end_date="2026-01-16")
readiness_data = client.get_readiness(start_date="2026-01-01", end_date="2026-01-16")
print(len(sleep_data), len(readiness_data))
PY
2. Trend Analysis
export PYTHONPATH="{baseDir}/scripts"
python - <<'PY'
from oura_api import OuraClient, OuraAnalyzer
client = OuraClient(token="YOUR_TOKEN")
sleep_data = client.get_sleep(start_date="2026-01-01", end_date="2026-01-16")
readiness_data = client.get_readiness(start_date="2026-01-01", end_date="2026-01-16")
analyzer = OuraAnalyzer(sleep_data, readiness_data)
avg_sleep = analyzer.average_metric(sleep_data, "score")
avg_readiness = analyzer.average_metric(readiness_data, "score")
trend = analyzer.trend(sleep_data, "average_hrv")
print(avg_sleep, avg_readiness, trend)
PY
3. Alerts
python {baseDir}/scripts/alerts.py --days 7 --readiness 60 --efficiency 80
Environment
Required:
OURA_API_TOKEN
Optional (used for alerts/reports/timezone/output):
KESSLER_TELEGRAM_BOT_TOKEN(fallback toTELEGRAM_BOT_TOKEN)TELEGRAM_CHAT_IDUSER_TIMEZONEOURA_OUTPUT_DIR
Scripts
scripts/oura_api.py- Oura Cloud API wrapper with OuraAnalyzer and OuraReporter classesscripts/alerts.py- Threshold-based notifications (CLI:python {baseDir}/scripts/alerts.py --days 7 --readiness 60)scripts/weekly_report.py- Weekly report generator
References
references/api.md- Oura Cloud API documentationreferences/metrics.md- Metric definitions and interpretations
Automation (Cron Jobs)
Cron jobs are configured in OpenClaw's gateway, not in this repo. Add these to your OpenClaw setup:
Daily Morning Briefing (8:00 AM)
openclaw cron add \
--name "Daily Oura Health Report (Hybrid)" \
--cron "0 8 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--wake next-heartbeat \
--deliver \
--channel telegram \
--target "<YOUR_TELEGRAM_CHAT_ID>" \
--message "Run the daily Oura health report with hybrid format: Execute bash /path/to/your/scripts/daily-oura-report-hybrid.sh"
Weekly Sleep Report (Sunday 8:00 AM)
openclaw cron add \
--name "Weekly Oura Sleep Report" \
--cron "0 8 * * 0" \
--tz "America/Los_Angeles" \
--session isolated \
--wake next-heartbeat \
--deliver \
--channel telegram \
--target "<YOUR_TELEGRAM_CHAT_ID>" \
--message "Run weekly Oura sleep report: bash /path/to/your/oura-weekly-sleep-alert.sh"
Daily Obsidian Note (8:15 AM)
openclaw cron add \
--name "Daily Obsidian Note" \
--cron "15 8 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--wake next-heartbeat \
--message "Create daily Obsidian note with Oura data. Run: source /path/to/venv/bin/activate && python /path/to/daily-note.py"
Note: Replace /path/to/your/ with your actual paths and <YOUR_TELEGRAM_CHAT_ID> with your Telegram channel/group ID.
Oura Analytics - OpenClaw Skill
Production-grade Oura Ring data integration for OpenClaw
Fetch sleep scores, readiness, activity, HRV, and trends from Oura Cloud API. Generate automated health reports and trigger-based alerts.
Features
✅ Oura Cloud API Integration - Personal Access Token authentication
✅ Sleep Analytics - Score, duration, efficiency, REM/deep stages
✅ Readiness Tracking - Recovery score, HRV balance, temperature
✅ Activity Metrics - Steps, calories, MET minutes
✅ Trend Analysis - Moving averages, correlations, anomaly detection
✅ Automated Alerts - Low readiness/sleep notifications via Telegram
Version
Current: v0.1.2
See CHANGELOG for version history.
Why This Exists
OpenClaw needs access to Oura Ring health data for:
- Daily morning briefings ("How did I sleep?")
- Correlating recovery with productivity/calendar
- Automated alerts for low recovery days
- Weekly/monthly health trend reports
This skill provides:
- Simple Python API client for Oura Cloud API v2
- Trend analysis and correlation tools
- Threshold-based alerting system
- Report generation templates
Installation
1. Get Oura Personal Access Token
- Go to https://cloud.ouraring.com/personal-access-tokens
- Create new token (select all scopes)
- Copy token to secrets file:
echo 'OURA_API_TOKEN="your_token_here"' >> ~/.config/systemd/user/secrets.conf
2. Install the skill
git clone https://github.com/kesslerio/oura-analytics-openclaw-skill.git ~/.openclaw/skills/oura-analytics
pip install -r requirements.txt
3. Add to OpenClaw's TOOLS.md
### oura-analytics
- Fetch Oura Ring metrics (sleep, readiness, activity, HRV)
- Generate health reports and correlations
- Set up automated alerts for low recovery
- Usage: `python ~/.openclaw/skills/oura-analytics/scripts/oura_api.py sleep --days 7`
Usage Examples
Note: For Python imports, set
PYTHONPATHto thescripts/folder:export PYTHONPATH="$(pwd)/scripts"
Fetch Sleep Data
# Last 7 days
python scripts/oura_api.py sleep --days 7
Get Readiness Summary
python scripts/oura_api.py readiness --days 7
Generate Reports
# Weekly summary (last 7 days)
python scripts/weekly_report.py --days 7
# Monthly trends (last 30 days)
python scripts/weekly_report.py --days 30
Trigger Alerts
# Check for low readiness and send Telegram notification
python scripts/alerts.py --days 7 --readiness 60 --efficiency 80 --telegram
Generate Hybrid Morning Briefing
# Daily hybrid report (morning briefing + 7-day trends)
python scripts/oura_briefing.py --format hybrid
Example hybrid output:
🌅 *Morning Briefing — Jan 22*
────────────────────────
💤 *Sleep*: 6h 47m (↑75min vs avg) ⚠️
⚡ *Readiness*: 80 (stable) ✅
*Drivers*: recovery_index, body_temperature
*Recovery*: 🟡 YELLOW
*Rec*: Moderate day. Avoid heavy training.
*📊 7-Day Trends*
────────────────────────
*Sleep Score*: `89.5` ↓
*Readiness*: `77.1` ↑
• *7.3h* sleep • *89.7%* eff • *21ms* HRV
*Recent*: 01-20 → `87.4`/`73` • 01-21 → `90.4`/`80`
Baseline & Comparison Analysis
# Compare last 7 days vs 30-day baseline
python scripts/baseline.py --current-days 7 --baseline-days 30
# View 90-day baseline statistics
python scripts/baseline.py --baseline-only --baseline-days 90
# JSON output for programmatic use
python scripts/baseline.py --json
Example output:
📈 Current vs Baseline (Last 7d vs 30d baseline)
↗️ Sleep Score: 89.5 (+10.6, z=0.53)
Above baseline
➡️ Readiness: 77.1 (+1.0, z=0.15)
Within baseline
↗️ Sleep Duration: 7.3 (+1.4, z=0.52)
Above baseline
↗️ Efficiency: 89.7 (+6.8, z=0.52)
Above baseline
✅ All metrics within or above baseline range
Interpretation:
- z-score: Standard deviations from baseline mean
z > 1.5: 🔥 Well above baseline0.5 < z < 1.5: ↗️ Above baseline-0.5 < z < 0.5: ➡️ Within baseline-1.5 < z < -0.5: ↘️ Below baselinez < -1.5: ⚠️ Well below baseline (needs attention)
- Baseline range: P25-P75 (middle 50% of your historical data)
- Sample size: Number of days used to calculate baseline
Core Workflows
1. Morning Health Check
from oura_api import OuraClient, OuraAnalyzer
client = OuraClient(token=os.getenv("OURA_API_TOKEN"))
sleep_data = client.get_sleep(start_date="2026-01-18", end_date="2026-01-18")
today = sleep_data[0] if sleep_data else {}
if today:
print(f"Sleep Score: {today.get('score', 'N/A')}/100")
print(f"Total Sleep: {today.get('total_sleep_duration', 0)/3600:.1f}h")
print(f"REM: {today.get('rem_sleep_duration', 0)/3600:.1f}h")
print(f"Deep: {today.get('deep_sleep_duration', 0)/3600:.1f}h")
2. Recovery Tracking
readiness = client.get_readiness(start_date="2026-01-11", end_date="2026-01-18")
avg_readiness = sum(d.get('score', 0) for d in readiness) / len(readiness) if readiness else 0
print(f"7-day avg readiness: {avg_readiness:.0f}")
3. Trend Analysis
from oura_api import OuraAnalyzer
analyzer = OuraAnalyzer(sleep_data, readiness_data)
avg_sleep = analyzer.average_metric(sleep_data, "score")
avg_readiness = analyzer.average_metric(readiness_data, "score")
print(f"Avg Sleep Score: {avg_sleep}")
print(f"Avg Readiness Score: {avg_readiness}")
API Client Reference
OuraClient
client = OuraClient(token="your_token")
# Sleep data (date range required)
sleep = client.get_sleep(start_date="2026-01-01", end_date="2026-01-16")
# Readiness data
readiness = client.get_readiness(start_date="2026-01-01", end_date="2026-01-16")
# Activity data
activity = client.get_activity(start_date="2026-01-01", end_date="2026-01-16")
# HRV trends
hrv = client.get_hrv(start_date="2026-01-01", end_date="2026-01-16")
OuraAnalyzer
from oura_api import OuraClient, OuraAnalyzer
client = OuraClient(token="your_token")
sleep = client.get_sleep(start_date="2026-01-01", end_date="2026-01-16")
readiness = client.get_readiness(start_date="2026-01-01", end_date="2026-01-16")
analyzer = OuraAnalyzer(sleep_data=sleep, readiness_data=readiness)
# Average metrics
avg_sleep = analyzer.average_metric(sleep, "score")
avg_readiness = analyzer.average_metric(readiness, "score")
# Trend analysis
trend = analyzer.trend(sleep, "score", days=7)
# Summary
summary = analyzer.summary()
OuraReporter
from oura_api import OuraClient, OuraReporter
client = OuraClient(token="your_token")
reporter = OuraReporter(client)
# Generate weekly report
report = reporter.generate_report(report_type="weekly", days=7)
print(json.dumps(report, indent=2))
Metrics Reference
| Metric | Description | Range |
|---|---|---|
| Sleep Score | Overall sleep quality | 0-100 |
| Readiness Score | Recovery readiness | 0-100 |
| HRV Balance | Heart rate variability | -3 to +3 |
| Sleep Efficiency | Time asleep / time in bed | 0-100% |
| REM Sleep | REM stage duration | hours |
| Deep Sleep | Deep stage duration | hours |
| Temperature Deviation | Body temp vs baseline | °C |
See references/metrics.md for full definitions.
Architecture
scripts/oura_api.py- Oura Cloud API v2 client with OuraAnalyzer and OuraReporter classesscripts/alerts.py- Threshold-based alerting CLIscripts/weekly_report.py- Weekly report generatorscripts/data_manager.py- Data storage and privacy controlsscripts/oura_data.py- Data management CLIscripts/schema.py- Canonical data structures with unit normalizationreferences/- API docs, metric definitions
Data Management & Privacy
What Data is Stored
All data is stored locally in ~/.oura-analytics/:
~/.oura-analytics/
├── cache/ # Cached API responses (cleanup is manual)
│ ├── sleep/ # Sleep records by date (YYYY-MM-DD.json)
│ ├── daily_readiness/ # Readiness records
│ └── daily_activity/ # Activity records
├── events.jsonl # User-logged events (optional)
├── config.yaml # User preferences (optional)
└── alert_state.json # Alert tracking (optional)
No data is sent to third parties. All Oura data stays on your local machine.
View Storage Info
python scripts/oura_data.py info
Output:
Data directory: /home/user/.oura-analytics
Total size: 187.1 KB
Cache:
Size: 187.1 KB
Files: 21
sleep: 7 files, 46.4 KB, 2026-01-14 to 2026-01-20
daily_readiness: 7 files, 3.6 KB, 2026-01-14 to 2026-01-20
daily_activity: 7 files, 137.2 KB, 2026-01-14 to 2026-01-20
Export Data (Backup)
Export all local data to a single JSON file:
# Full backup
python scripts/oura_data.py export --output backup.json
# Compressed tarball
python scripts/oura_data.py export --output backup.tar.gz --format tar.gz
# Export events only
python scripts/oura_data.py export-events --output events.csv --format csv
Clear Data (Privacy)
# Clear cache only (keeps events/config)
python scripts/oura_data.py clear-cache --confirm
# Clear specific endpoint
python scripts/oura_data.py clear-cache --endpoint sleep --confirm
# Clear events
python scripts/oura_data.py clear-events --confirm
# Clear ALL local data
python scripts/oura_data.py clear-all --confirm
Important: All clear commands require --confirm flag to prevent accidental deletion.
Automatic Cleanup
Delete cached data older than 90 days:
# Default: 90 days
python scripts/oura_data.py cleanup
# Custom retention period
python scripts/oura_data.py cleanup --days 180
GDPR Compliance
- ✅ Data ownership: You own your data (local storage only)
- ✅ Data retention: You control retention (manual cleanup)
- ✅ No data sharing: No third-party services
- ✅ Right to deletion: Clear data anytime with
clear-all
Note: This skill is NOT HIPAA-compliant. Do not use for medical decision-making. Consult healthcare professionals for health concerns.
Troubleshooting
Authentication Failed
# Check token is set
echo $OURA_API_TOKEN
# Or use explicit token
python scripts/oura_api.py sleep --days 7 --token "your_token"
No Data Returned
# Check date range (Oura data has ~24h delay)
python scripts/oura_api.py sleep --days 10
# Or fetch and inspect manually
python scripts/oura_api.py sleep --days 7 | python -m json.tool | head -50
Credits
Created for production OpenClaw health tracking
Developed by @kesslerio • Part of the ClawdHub ecosystem
Powered by:
- Oura Ring - Wearable health tracker
- Oura Cloud API v2 - Official API
License
Apache 2.0
Permissions & Security
Security level L1: Low-risk skills with minimal permissions. Review inputs and outputs before running in production.
Requirements
- OpenClaw CLI installed and configured.
- Language: Markdown
- License: MIT
- Topics:
FAQ
How do I install oura-analytics?
Run openclaw add @kesslerio/oura-analytics in your terminal. This installs oura-analytics into your OpenClaw Skills catalog.
Does this skill run locally or in the cloud?
OpenClaw Skills execute locally by default. Review the SKILL.md and permissions before running any skill.
Where can I verify the source code?
The source repository is available at https://github.com/openclaw/skills/tree/main/skills/kesslerio/oura-analytics. Review commits and README documentation before installing.
