{"slug": "noctua-a-privacy-first-oura-ring-sdk-with-on-device-ml-no-cloud", "title": "Noctua – A privacy-first Oura Ring SDK with on-device ML, no cloud", "summary": "Noctua, an open-source Kotlin SDK for the Oura Ring, provides on-device AI wellness insights and next-day readiness forecasts without uploading health data to the cloud. The SDK includes a typed Oura API v2 client, an on-device AI layer with explainable heuristic rules and a neural forecaster bridged to ExecuTorch, and an example app with demo mode. It targets Android and JVM backends, with modules noctua-core, noctua-ai, and example-app, and supports OAuth2 and personal access tokens.", "body_md": "**On-device AI wellness intelligence for Oura Ring — privacy-first Android SDK.**\n\nNoctua (the owl genus — nocturnal wisdom) is an open-source Kotlin toolkit that\ncombines a complete, typed client for the **Oura API v2** with an **on-device AI\nlayer** that turns raw biometrics into explainable insights and a next-day\nreadiness forecast — **without your health data ever leaving the phone**.\n\n| Dashboard | AI Coach (on-device) | Connect |\n|---|---|---|\n\n*Captured from the example app running in demo mode on a Pixel 7 Pro emulator.*\n\nMost wearable companion apps ship your biometric history to a cloud LLM to generate \"insights\". Noctua takes the opposite stance:\n\n| Cloud AI companions | Noctua |\n|\n|---|---|---|\n| Raw HRV / sleep / temperature data | uploaded to a server | never leaves the device |\n| Insight logic | opaque | transparent, unit-tested rules + open model |\n| Works offline | ✗ | ✓ |\n| Latency | network round-trip | < 5 ms on-device |\n\n``` php\ngraph TD\n    A[Oura Cloud API v2] -->|OAuth2 / PAT| B[noctua-core<br/>typed Kotlin client]\n    B --> C[WellnessSnapshot<br/>readiness · sleep · activity · HRV]\n    C --> D[noctua-ai<br/>FeatureExtractor]\n    D --> E1[HeuristicInsightEngine<br/>explainable rules]\n    D --> E2[ExecuTorchForecaster<br/>.pte neural model, on-device]\n    E1 --> F[NoctuaReport]\n    E2 --> F\n    E2 -.missing runtime.-> E3[LinearHeuristicForecaster<br/>zero-dependency fallback]\n    E3 --> F\n    F --> G[example-app<br/>Jetpack Compose]\n```\n\n| Module | What it is |\n|---|---|\n`noctua-core` |\nPure-Kotlin Oura API v2 client — OAuth2 helpers, auto-refreshing tokens, all `usercollection` endpoints, pagination, sandbox support. Runs on Android and any JVM backend. |\n`noctua-ai` |\nOn-device intelligence: feature extraction (sleep debt, HRV z-score vs personal baseline, readiness trend), explainable heuristic insights, and a neural readiness forecaster bridged to ExecuTorch. |\n`example-app` |\nMaterial 3 Compose app — score rings, 14-day readiness trend, AI coach feed, OAuth/token connect flow, and a built-in demo mode that needs no Oura account. |\n`model/` |\nPyTorch → ExecuTorch export script for the readiness forecaster. |\n\n**Personal use:** create a Personal Access Token at[cloud.ouraring.com/personal-access-tokens](https://cloud.ouraring.com/personal-access-tokens)*(note: Oura has been moving new integrations to OAuth2)*.**Multi-user apps:** register an OAuth2 application at[cloud.ouraring.com/oauth/applications](https://cloud.ouraring.com/oauth/applications)with redirect URI`noctua://callback`\n\n.\n\nThe modules are plain Gradle project dependencies (publish to Maven or use\nvia `includeBuild`\n\n/ JitPack):\n\n```\ndependencies {\n    implementation(\"com.noctua:noctua-core:0.1.0\")\n    implementation(\"com.noctua:noctua-ai:0.1.0\")\n    // Optional: enable the neural forecaster\n    implementation(\"org.pytorch:executorch-android:1.0.0\")\n}\nval oura = OuraClient.Builder()\n    .token(\"YOUR_TOKEN\")\n    .build()\n\n// Coroutine-first; pagination is handled for you.\nval readiness = oura.dailyReadiness(startDate = \"2026-08-01\", endDate = \"2026-08-21\")\nval sleep     = oura.dailySleep(startDate = \"2026-08-01\", endDate = \"2026-08-21\")\nval periods   = oura.sleep(startDate = \"2026-08-01\", endDate = \"2026-08-21\")\n```\n\nOAuth2 (client-side flow) in two lines:\n\n```\nval url = OuraOAuth.authorizationUrl(clientId, redirectUri = \"myapp://callback\")\n// open `url` in a Custom Tab, then in your deep-link handler:\nval token = OuraOAuth.parseClientSideRedirect(intent.dataString!!).accessToken\n```\n\nFor long-lived apps, `OAuthTokenProvider`\n\nrefreshes expiring tokens\nautomatically via Oura's `refresh_token`\n\ngrant.\n\n```\nval ai = NoctuaAI()\nval report = ai.analyze(WellnessSnapshot(\n    readiness = readiness,\n    sleep = sleep,\n    activity = oura.dailyActivity(\"2026-08-01\", \"2026-08-21\"),\n    sleepPeriods = periods,\n))\n\nprintln(report.forecastedReadiness)   // e.g. 74 — tomorrow's predicted score\nreport.insights.forEach { println(\"• ${it.title} (${it.confidence}%)\") }\n// • Sleep debt accumulating (88%)\n// • HRV below your baseline (80%)\ncd model\npip install torch executorch\npython export_readiness_forecaster.py   # → readiness_forecaster.pte\n```\n\nShip the `.pte`\n\nwith your app and swap the forecaster:\n\n```\nval ai = NoctuaAI(forecaster = ExecuTorchForecaster(pteFile.absolutePath))\n```\n\nIf the ExecuTorch runtime or model file is absent, Noctua silently falls back to the bundled linear model — the app never breaks.\n\n| Endpoint | `OuraClient` method |\nScope |\n|---|---|---|\n`/v2/usercollection/personal_info` |\n`personalInfo()` |\npersonal |\n`daily_sleep` / `daily_readiness` / `daily_activity` |\n`dailySleep()` · `dailyReadiness()` · `dailyActivity()` |\ndaily |\n`daily_spo2` · `daily_stress` · `daily_resilience` |\n`dailySpo2()` · `dailyStress()` · `dailyResilience()` |\nspo2 / daily |\n`daily_cardiovascular_age` · `vO2_max` |\n`dailyCardiovascularAge()` · `vo2Max()` |\nheart_health |\n`sleep` (detailed periods) · `sleep_time` |\n`sleep()` · `sleepTime()` |\ndaily |\n`heartrate` (time series) |\n`heartrate(start, end)` ISO-8601 datetimes |\nheartrate |\n`workout` · `session` · `tag` / `enhanced_tag` |\n`workouts()` · `sessions()` · `tags()` · `enhancedTags()` |\nworkout / session / tag |\n`rest_mode_period` · `ring_configuration` |\n`restModePeriods()` · `ringConfigurations()` |\ndaily / ring_configuration |\nSandbox (`/v2/sandbox/...` ) |\n`Builder().sandbox(true)` |\nnone |\n\nErrors map to typed `OuraException`\n\nsubtypes: `Unauthorized`\n\n, `RateLimited`\n\n(Oura allows ~5000 req / 5 min), `Http`\n\n, `Network`\n\n, `Serialization`\n\n.\n\n```\ngit clone https://github.com/RanjithRagavan/Noctua.git\ncd Noctua\n./gradlew :example-app:installDebug\n```\n\nThe app boots into **demo mode** with a deterministic 21-day dataset, so you\ncan evaluate the full UX — score rings, trend chart, forecast card, AI coach —\nbefore connecting a real ring. The [screenshots above](#screenshots) show\nexactly what demo mode renders.\n\n- On-device LLM sleep coach (ExecuTorch Llama runner, fully local chat)\n- Personal fine-tuning loop: retrain the forecaster nightly on-device\n- Health Connect write-back (share derived insights with Android Health)\n- Webhook subscription helpers (\n`/v2/webhook/subscription`\n\n) - Compose Multiplatform + iOS (KMP) port of\n`noctua-ai`\n\nIssues and PRs welcome. The heuristics in `HeuristicInsightEngine`\n\nare\ndeliberately readable — improving them with better evidence is a great first\ncontribution. Run `./gradlew test`\n\nbefore submitting.\n\n[Apache 2.0](/RanjithRagavan/Noctua/blob/main/LICENSE) — use it in personal or commercial apps.\n\n*Noctua is an independent open-source project and is not affiliated with,\nendorsed by, or sponsored by Ōura Health Oy.*", "url": "https://wpnews.pro/news/noctua-a-privacy-first-oura-ring-sdk-with-on-device-ml-no-cloud", "canonical_source": "https://github.com/RanjithRagavan/Noctua", "published_at": "2026-08-22 06:56:37+00:00", "updated_at": "2026-08-22 07:13:42.092185+00:00", "lang": "en", "topics": ["artificial-intelligence", "machine-learning", "ai-products", "developer-tools"], "entities": ["Noctua", "Oura Ring", "Oura API v2", "ExecuTorch", "PyTorch", "Jetpack Compose", "Kotlin", "Oura Cloud"], "alternates": {"html": "https://wpnews.pro/news/noctua-a-privacy-first-oura-ring-sdk-with-on-device-ml-no-cloud", "markdown": "https://wpnews.pro/news/noctua-a-privacy-first-oura-ring-sdk-with-on-device-ml-no-cloud.md", "text": "https://wpnews.pro/news/noctua-a-privacy-first-oura-ring-sdk-with-on-device-ml-no-cloud.txt", "jsonld": "https://wpnews.pro/news/noctua-a-privacy-first-oura-ring-sdk-with-on-device-ml-no-cloud.jsonld"}}