Corsair
PluginsOura Ring

Oura Database Schema

Database entities and querying synced Oura data

The Oura plugin syncs health data from Oura Ring to your database for fast queries and historical analysis.

New to Corsair? Learn about database operations, data synchronization, and multi-tenancy.

Full Implementation: See the Oura plugin source code.

Synced Entities

  • personalInfo - User profile data
  • dailyActivity - Daily activity summaries
  • dailyReadiness - Daily readiness scores
  • dailySleep - Daily sleep summaries

Database API

const sleep = await corsair.oura.db.dailySleep.search({
    data: { score: 85 },
});

Personal Info

Schema

{
    id: string;
    age: number;
    weight: number;
    height: number;
    biological_sex: string;
    email: string;
}

Querying Personal Info

const profile = await corsair.oura.db.personalInfo.search({
    data: {},
});

Daily Activity

Schema

{
    id: string;
    day: string;           // YYYY-MM-DD
    score?: number;        // 0-100 activity score
    active_calories?: number;
    steps?: number;
    daily_movement?: number;
    high_activity_time?: number;
    medium_activity_time?: number;
    low_activity_time?: number;
}

Querying Daily Activity

Search by date:

const activity = await corsair.oura.db.dailyActivity.search({
    data: { day: "2024-01-15" }, 
});

Example: Weekly Activity Summary

const tenant = corsair.withTenant("user-123");

const weeklyActivity = await tenant.oura.db.dailyActivity.search({
    data: {},
    limit: 7,
});

const avgSteps = weeklyActivity.data.reduce((sum, d) => sum + (d.steps ?? 0), 0) / 7; 

Daily Readiness

Schema

{
    id: string;
    day: string;
    score?: number;                    // 0-100 readiness score
    temperature_deviation?: number;
    hrv_balance_score?: number;
    recovery_index_score?: number;
    resting_heart_rate_score?: number;
    sleep_balance_score?: number;
    previous_day_activity_score?: number;
    previous_night_score?: number;
}

Querying Readiness

Find low readiness days:

const lowReadiness = await corsair.oura.db.dailyReadiness.search({
    data: {},
    limit: 30,
});

const poorDays = lowReadiness.data.filter(d => (d.score ?? 100) < 60); 

Daily Sleep

Schema

{
    id: string;
    day: string;
    score?: number;            // 0-100 sleep score
    total_sleep_duration?: number;
    deep_sleep_duration?: number;
    rem_sleep_duration?: number;
    light_sleep_duration?: number;
    awake_time?: number;
    efficiency?: number;       // Sleep efficiency %
    latency?: number;          // Time to fall asleep (minutes)
    timing_score?: number;
    restfulness_score?: number;
}

Querying Sleep

Search by date range:

const sleepHistory = await corsair.oura.db.dailySleep.search({
    data: {},
    limit: 30,
});

Example: Average Sleep Score

const tenant = corsair.withTenant("user-123");

const sleep = await tenant.oura.db.dailySleep.search({ data: {}, limit: 30 });
const avg = sleep.data.reduce((sum, d) => sum + (d.score ?? 0), 0) / sleep.data.length; 

console.log(`30-day average sleep score: ${avg.toFixed(1)}`);