Dashboard Sign InKR

AsleepTrack API

The AsleepTrack API is a sleep analysis AI API that tracks sleep states by analyzing sound data collected from a smartphone in real time. It provides the AsleepTrack SDK, which automatically manages the audio process and uploads data, enabling client apps to easily integrate sleep tracking functionality. Utilize this SDK to build a sample app that implements sleep tracking and basic sleep report features, allowing you to experience the AsleepTrack API in the fastest way possible.

Quickstart with Sample App

Generate API Key

To build the sample app, you need to add the API Key to your environment variables. Sign in to the AsleepTrack Dashboard to obtain your API Key. You can generate the API Key in the settings tab of your profile.

iOS Sample App

  1. Download the iOS sample app project from the GitHub repository to get started.
# iOS sample app
git clone https://github.com/asleep-ai/asleep-sdk-ios-sampleapp-public.git
  • If you are using Xcode’s Clone Git Repository feature,
https://github.com/asleep-ai/asleep-sdk-ios-sampleapp-public.git
  1. Enter the issued API Key in the YOUR_API_KEY field of Debug.xcconfig and Release.xcconfig.
API_KEY=YOUR_API_KEY
  1. If you want to receive sleep data via webhook, enter the callbackUrl information in MainView.swift.
struct MainView: View {
    ...
    @AppStorage("sampleapp+apikey") private var apiKey = Bundle.main.object(forInfoDictionaryKey: "API_KEY") as? String ?? ""
    @AppStorage("sampleapp+userid") private var userId = ""
    @AppStorage("sampleapp+baseurl") private var baseUrl = "yourProxyUrl"
    @AppStorage("sampleapp+callbackurl") private var callbackUrl = "yourCallbackUrl"
  1. Build and install the sample app on your iPhone.
  • If a Signing error occurs, change the Bundle Identifier.

Android Sample App

  1. Download the Android sample app project from the GitHub repository to get started.
# Android sample app
git clone https://github.com/asleep-ai/asleep-sdk-android-sampleapp-public.git
  • If you are using Project from Version Control in Android Studio,
https://github.com/asleep-ai/asleep-sdk-android-sampleapp-public.git
  1. Enter the API Key in local.properties.
asleep_api_key="ApiKey"
  1. If you want to receive sleep data via webhook, enter the callbackUrl information in Constants.kt.
object Constants {
    val BASE_URL: String? = null
    val CALLBACK_URL: String? = null
    const val ASLEEP_API_KEY = BuildConfig.ASLEEP_API_KEY
    const val SERVICE_NAME = "AsleepSampleApp"
  
    const val MIN_TRACKING_MINUTES = 5

    // intent extra names
    const val EXTRA_ASLEEP_USER_ID = "ASLEEP_USER_ID"
    const val EXTRA_SESSION_ID = "SESSION_ID"
    const val EXTRA_FROM_STATE = "FROM_STATE"

    enum class StateName {
        INIT, TRACKING
    }
}
  1. Build the sample app and install it on an Android smartphone.

Sleep Tracking and Sleep Report

You must track for at least 5 minutes to receive sleep analysis results.

Retrieving Sleep Data

Retrieving Sleep Data Using API / SDK

Sleep data tracked through the SDK can be retrieved by calling the Reports or Data API of the SDK. Since the uploaded sound data is processed asynchronously on the AI server, you need to use a polling approach to check sleep data in real time via the SDK Reports or Data API.

iOS SDK

var config: Asleep.Config?
var reports: Asleep.Reports?

if let config {
    reports = Asleep.createReports(config: config)
}

Android SDK

val reports = Asleep.createReports(asleepConfig)

reports?.getReport(sessionId, object : Reports.ReportListener {
    override fun onSuccess(report: Report?) {
    }

    override fun onFail(errorCode: Int, detail: String) {
    }
})

Data API

curl "https://api.asleep.ai/data/v3/sessions/{session_id}" -XGET \
  -H "x-api-key: <YOUR_API_KEY>" \
  -H "x-user-id: <USER_ID>"

Receiving Realtime Sleep Data via Webhook

You can receive a webhook when the AI server completes the analysis by registering a callback URL. To do this, you must register the callback URL during the SDK initialization phase. An example of the data sent via webhook is shown below.

Realtime Sleep Data

{
    "event": "INFERENCE_COMPLETE",
    "version": "V3",
    "data": {
        "user_id": "G-20250115025029-vLErWBfQNtnfvgDccFOQ",
        "session_id": "20250115025029_fvivn",
        "seq_num": 39,
        "inference_seq_num": 3,
        "sleep_stages": [0], // omitted
        "breath_stages": null,
        "snoring_stages": [0] // omitted
    }
}

Complete Sleep Data upon Session Termination

{
    "event": "SESSION_COMPLETE",
    "version": "V3",
    "data": {
        "timezone": "UTC",
        "peculiarities": ["NO_BREATHING_STABILITY"],
        "missing_data_ratio": 0.0,
        "user_id": "G-20250115025029-vLErWBfQNtnfvgDccFOQ",
        "session": {
            "id": "20250115025029_fvivn",
            "state": "COMPLETE",
            "start_time": "2025-01-15T02:50:29+00:00",
            "end_time": "2025-01-15T03:50:29+00:00",
            "unexpected_end_time": null,
            "created_timezone": "UTC",
            "sleep_stages": [0], // omitted
            "breath_stages": null, 
            "snoring_stages": [0] // omitted
        },
        "stat": {
            "sleep_time": "2025-01-15T03:05:29+00:00",
            "wake_time": "2025-01-15T03:26:29+00:00",
            "sleep_index": 50,
            "sleep_latency": 900,
            "wakeup_latency": 1440,
            "light_latency": 0,
            "deep_latency": null,
            "rem_latency": null,
            "time_in_bed": 3600,
            "time_in_sleep_period": 1260,
            "time_in_sleep": 1080,
            "time_in_wake": 180,
            "time_in_light": 1080,
            "time_in_deep": 0,
            "time_in_rem": 0,
            "time_in_stable_breath": null,
            "time_in_unstable_breath": null,
            "time_in_snoring": 0,
            "time_in_no_snoring": 1260,
            "sleep_efficiency": 0.3,
            "sleep_ratio": 0.86,
            "wake_ratio": 0.14,
            "light_ratio": 0.86,
            "deep_ratio": 0.0,
            "rem_ratio": 0.0,
            "stable_breath_ratio": null,
            "unstable_breath_ratio": null,
            "snoring_ratio": 0.0,
            "no_snoring_ratio": 1.0,
            "breathing_index": null,
            "breathing_pattern": null,
            "waso_count": 1,
            "longest_waso": 180,
            "sleep_cycle_count": 0,
            "sleep_cycle": null,
            "sleep_cycle_time": [],
            "unstable_breath_count": null,
            "snoring_count": 0
        }
    }
}

Retrieving Sleep Data from the Dashboard

On the dashboard, you can visually check the sleep data tracked using the API Key of your logged-in account. Before implementing the report UI in the client app, you can easily verify whether the sleep tracking in the test environment was successful through the dashboard.

Dashboard Account

This refers to an AsleepTrack dashboard account. Users who have conducted sleep tracking using the API Key issued from this account can log in to the dashboard to retrieve their data.

Each account provides two environments: Live and Test, and separate API Keys can be issued for each. Data tracked with an API Key from a specific environment can only be accessed using the corresponding API Key. Additionally, the statistics provided by the dashboard are separated by environment.

User

A user refers to the individual measuring sleep using the client app. You can generate a User ID through the SDK or API for sleep tracking. This allows you to track sleep sessions and manage sleep data on a per-user basis.

Session

A sleep session refers to a single sleep period (from starting the tracking at night to pressing the stop button in the morning). You can create a sleep session for a specific user, upload the data for analysis, and then close the session once the tracking is complete.

A session can have three states: OPEN, CLOSED, and COMPLETE.

  • OPEN: The session is created, and sound data can be uploaded for analysis.
  • CLOSED: The session is closed, meaning no more sound data can be uploaded, and it is waiting for AI server analysis to complete.
  • COMPLETE: All analyses have been completed.

Sleep Data Metrics

When a sleep session is in the OPEN state, only real-time analyzed sleep data is available. Once the session is closed and the AI server completes the analysis, transitioning the session state to COMPLETE, you can access various sleep metrics and generate a sleep report for the user.

The available sleep metrics depend on the Enterprise contract plan. Check the Data Plan to see which metrics are provided under each plan.

Basic Sleep Information

Data collection related to the start and end of sleep tracking, as well as sleep onset and wake-up times.

  • Sleep latency (sleep_latency) and Wakeup latency (wakeup_latency) can be used as data to infer the user's habits (e.g., difficulty falling asleep, lying in bed for a long time after waking up).

  • Total Measurement Time (time_in_bed) and Sleep Period Time (time_in_sleep_period) serve as the standard for different data metrics, so be careful to distinguish between the two data sets.

No.Data NameTypeDefinitionExample [Units] (= Actual Value)
1start_timeTimeExact time at which the tracking started.2023-11-22T00:00:10+09:00 [YYYY-MM-DDThh:mm:ss±hh:mm] (=2023-11-22 00:00:10)
2end_timeTimeExact time at which the tracking ended.2023-11-22T06:30:38+09:00 [YYYY-MM-DDThh:mm:ss±hh:mm] (=2023-11-22 06:30:38)
3time_in_bedDurationThe time duration between the start and the end of tracking.23428 [s] (=6h 30m 28s)
4sleep_timeTimeExact time at which ‘Sleep’ was first detected since the tracking started.2023-11-22T00:53:10+09:00 [YYYY-MM-DDThh:mm:ss±hh:mm] (=2023-11-22 00:53:10)
5wake_timeTimeExact time at which the last 'Wake' period was detected during tracking. No sleep will be detected after wake_time.2023-11-22T06:30:08+09:00 [YYYY-MM-DDThh:mm:ss±hh:mm] (= 2023-11-22 06:30:08)
6time_in_sleep_periodDurationThe time duration between the onset of ‘Sleep’ and the start of the last ‘Wake’ during tracking.20190 [s] (= 5h 36m 30s)
7sleep_latencyDurationThe time duration between the start of tracking and the detection of first 'Sleep'.3180 [s] (=53m 0s)
8wakeup_latencyDurationThe time duration between the start of the last 'Wake' and the end of tracking.30 [s] (= 0m 30s)
9sleep_indexScoreThe metric that comprehensively represents sleep quality, defined by learning from the distribution of sleep data.97 (range: 50 ~ 100)

Sleep Index

The sleep_index is defined by three indicators: total sleep time (time_in_sleep), which measures the quantity of sleep; sleep efficiency (sleep_efficiency), which measures the quality of sleep; and the number of awakenings (waso_count). The sleep_index ranges from 50 to 100 points and is designed to have the highest correlation with users’ subjective sleep satisfaction, based on medical definitions of sleep quality and sleep big data.

Awakenings during sleep are categorized into long awakenings that a person can perceive and short awakenings lasting 30 seconds to a few minutes, which are difficult to notice. Short awakenings that are distributed throughout sleep are reflected in the score through waso_count, while long awakenings that a person can perceive are reflected through sleep_efficiency.

Sleep Efficiency

Data related to Sleep Efficiency (sleep_efficiency), one of the key indicators representing the quality of sleep.

  • By figuring out the Total Sleep Time (time_in_sleep) during the Total Measurement Time (time_in_bed), you can calculate Sleep Efficiency (sleep_efficiency).
  • While there is no one-size-fits-all answer for sleep, having a high Sleep Efficiency suggests securing an optimal amount of sleep in relation to the time spent in bed.
  • While the Sleep Stage Ratio (sleep_ratio) data is based on the Sleep Period Time (time_in_sleep_period), please note that Sleep Efficiency (sleep_efficiency) data is based on the Total Measurement Time (time_in_bed)
No.Data NameTypeDefinitionExample [Units] (= Actual Value)
1time_in_sleepDurationThe actual time spent sleeping. It is the time duration calculated after subtracting all ‘Wake’ time from time_in_bed.19380 [s] (= 5h 23m 0s)
2sleep_efficiencyRatioThe ratio of time_in_sleep to time_in_bed0.83 [x.xx] (=83%)

Sleep Stage

Data collection related to the four sleep stages: Wake, Light Sleep, Deep Sleep, and REM Sleep.

  • During the Total Measurement Time (time_in_bed), the user's sleep is recorded every 30 seconds as one of the four stages. You can check this collection of sleep stages through the Sleep Stage List (sleep_stages)
  • The frequency and duration of awakenings during sleep can be crucial indicators affecting the subjective satisfaction of sleep, making them important metrics during result analysis. Relevant data, such as Wake After Sleep Onset Count (waso_count), Time in Wakeful Stage (time_in_wake), and Longest Wake After Sleep Onset (longest_waso), can be utilized for this purpose

No.Data NameTypeDefinitionExample [Units] (= Actual Value)
1sleep_stagesNumber ListA list of numbers, indicating sleep stages during time_in_bed
(0: Wake / 1: Light / 2: Deep / 3: REM)
[0,0,1,……,2,2,3,3,1,1,0,0,0] [list] (= wake, wake, light, .....)
2waso_countCountThe number of ‘Wake’ detected during time_in_sleep_period19 [#] (= 19 times)
3longest_wasoDurationThe longest time duration of ‘Wake’ during time_in_sleep_period90 [s] (=1m 30s)
4time_in_wakeDurationThe sum of all ‘Wake’ seconds detected during time_in_sleep_period810 [s] (=13m 30s)
5time_in_lightDurationThe sum of all ‘Light’ seconds detected during time_in_sleep_period8610 [s] (=2h 23m 30s)
6time_in_deepDurationThe sum of all ‘Deep’ seconds detected during time_in_sleep_period5700 [s] (=1h 35m 0s)
7time_in_remDurationThe sum of all ‘REM’ seconds detected during time_in_sleep_period5070 [s] (=1h 24m 30s)

Sleep Stage Ratio

Data collection related to the ratio of awakenings and each sleep stage during the Sleep Period Time (time_in_sleep_period)

  • The Sleep Stage Ratio (sleep_ratio) data represents the proportion of time recorded in Light, Deep, and REM stages during the Sleep Period Time (time_in_sleep_period), excluding wakefulness. To compare the ratio of awakening to sleep in the user's sleep period time, you can utilize both Sleep Stage Ratio (sleep_ratio) and Wake Ratio (wake_ratio).
  • To gain an overview of the user's overall sleep structure, you can compare and utilize the following four data: Wake Ratio (wake_ratio), Light Sleep Ratio (light_ratio), Deep Sleep Ratio (deep_ratio), and REM Sleep Ratio (rem_ratio).
No.Data NameTypeDefinitionExample [Units] (= Actual Value)
1sleep_ratioRatioRatio of time_in_sleep to time_in_sleep_period0.96 [x.xx] (=96%)
2wake_ratioRatioRatio of time_in_wake to time_in_sleep_period0.04 [x.xx] (=4%)
3light_ratioRatioRatio of time_in_light to time_in_sleep_period0.43 [x.xx] (=43%)
4deep_ratioRatioRatio of time_in_deep to time_in_sleep_period0.28 [x.xx] (=28%)
5rem_ratioRatioRatio of time_in_rem to time_in_sleep_period0.25 [x.xx] (=25%)

Sleep Stage-specific Latency

Data collection related to the time it takes for each sleep stage (Light Sleep, Deep Sleep, REM Sleep) to first appear from the onset of sleep.

  • Generally, as the Sleep Latency (sleep_latency) increases, the length of the REM Sleep Latency (rem_latency) also increases.
  • Since the first detected sleep after the user initiates sleep tracking is always Light Sleep, please note that, barring any errors, the value for Light Sleep Latency (light_latency) data is always 0.
No.Data NameTypeDefinitionExample [Units] (= Actual Value)
1light_latencyDurationThe time duration between sleep_time to the first detection of ‘Light’
(Normally, '0' as light sleep is the first sleep stage to be detected)
0 [s] (=0m 0s)
2deep_latencyDurationThe time duration between sleep_time to the first detection of ‘Deep’540 [s] (=9m 0s)
3rem_latencyDurationThe time duration between sleep_time to the first detection of ‘REM’4710 [s] (=1h 18m 30s)

Sleep Period

Data collection related to the sleep cycles that periodically occur within the Sleep Period Time (time_in_sleep_period).

  • Typical sleep involves a pattern of alternating between Non-REM (NREM) and REM sleep. A bundle of repeating NREM and REM sleep is referred to as a sleep cycle, and the start and end times of each sleep cycle can be confirmed through the Sleep Cycle Transition Time List (sleep_cycle_time) data.
  • A healthy adult typically experiences 4-6 cycles of sleep per night, each lasting 70-110 minutes, when obtaining around 8 hours of sleep. To comprehend the user's sleep cycle structure, you can utilize the Sleep Cycle Count (sleep_cycle_count) and Average Sleep Cycle Duration (sleep_cycle) data.
No.Data NameTypeDefinitionExample [Units] (= Actual Value)
1sleep_cycleDurationThe average time duration of sleep cycles. Each sleep cycle is consisted of both 'REM' and 'Non-REM' sleep.6520 [s] (=1h 38m 40s)
2sleep_cycle_countCountThe number of sleep cycles detected during the time_in_sleep_period3 [#] (=3 times)
3sleep_cycle_timeTime ListA list of the exact start and end times of each sleep cycle[2023-11-22T00:53:10+09:00,2023-11-22T02:26:10+09:00,2023-11-22T04:54:10+09:00,2023-11-22T06:19:10+09:00] [list] (= 2023-11-22 00:53:10, 2023-11-22 02:26:10, 2023-11-22 04:54:10, 2023-11-22 06:19:10)

Snoring

AsleepTrack can detect not only sleep stages but also various sleep events, such as snoring. Snoring data includes the occurrence time, frequency, and ratio, providing more detailed sleep analysis.

No.Data NameTypeDefinitionExample [Units] (= Actual Value)
1snoring_stagesNumber ListA list of snoring stages during the time_in_bed
(0: no snoring / 1: snoring)
[0,0,0,1,1,……,1,0,0,0,0] [list] (= no snoring, no snoring, no snoring, snoring, snoring .......)
2time_in_snoringDurationThe time duration, of which snoring is detected during time_in_sleep_period23400 [s] (=6h 30m 00s)
3time_in_no_snoringDurationThe time duration, of which no snoring is detected during time_in_sleep_period5400 [s] (=90m 0s)
4snoring_ratioRatioThe ratio of time_in_snoring to time_in_sleep_period0.72 [x.xx] (=72%)
5no_snoring_ratioRatioThe ratio of time_in_no_snoring to time_in_sleep_period0.28 [x.xx] (=28%)
6snoring_countCountThe number of times snoring is detected during the time_in_sleep_period20 [#] (=20 times)

Basic Sleep Analysis

The Basic Sleep Analysis feature allows you to review the following sleep data:

Data NameDefinition
sleep_stagesA list of numbers, indicating sleep stages during time_in_bed
(0: Wake / 1: Sleep)
start_timeExact time at which the tracking started
end_timeExact time at which the tracking ended.
time_in_bedThe time duration between the start and the end of tracking
sleep_timeExact time at which ‘Sleep’ was first detected since the tracking started
wake_timeExact time at which the last 'Wake' period was detected during tracking. No sleep will be detected after wake_time
time_in_sleep_periodThe time duration between the onset of ‘Sleep’ and the start of the last ‘Wake’ during tracking
sleep_latencyThe time duration between the start of tracking and the detection of first 'Sleep'
wakeup_latencyThe time duration between the start of the last 'Wake' and the end of tracking
time_in_sleepThe actual time spent sleeping. It is the time duration calculated after subtracting all ‘Wake’ time from time_in_bed
sleep_efficiencyThe ratio of time_in_sleep to time_in_bed
waso_countThe number of ‘Wake’ detected during time_in_sleep_period
longest_wasoThe longest time duration of ‘Wake’ during time_in_sleep_period
time_in_wakeThe sum of all ‘Wake’ seconds detected during time_in_sleep_period
sleep_ratioRatio of time_in_sleep to time_in_sleep_period
wake_ratioRatio of time_in_wake to time_in_sleep_period
sleep_indexThe metric that comprehensively represents sleep quality, defined by learning from the distribution of sleep data

4 Sleep Stages Analysis

The Advanced (4-Stage) Sleep Analysis feature allows you to additionally review the following sleep data in addition to the basic sleep analysis data:

Data NameDefinition
sleep_stagesA list of numbers, indicating sleep stages during time_in_bed
(0: Wake / 1: Light / 2: Deep / 3: REM)
time_in_lightThe sum of all ‘Light’ seconds detected during time_in_sleep_period
time_in_deepThe sum of all ‘Deep’ seconds detected during time_in_sleep_period
time_in_remThe sum of all ‘REM’ seconds detected during time_in_sleep_period
light_ratioRatio of time_in_light to time_in_sleep_period
deep_ratioRatio of time_in_deep to time_in_sleep_period
rem_ratioRatio of time_in_rem to time_in_sleep_period
light_latencyThe time duration between sleep_time to the first detection of ‘Light’
(Normally, '0' as light sleep is the first sleep stage to be detected)
deep_latencyThe time duration between sleep_time to the first detection of ‘Deep’
rem_latencyThe time duration between sleep_time to the first detection of ‘REM’
sleep_cycleThe average time duration of sleep cycles. Each sleep cycle is consisted of both 'REM' and 'Non-REM' sleep.
sleep_cycle_countThe number of sleep cycles detected during the time_in_sleep_period
sleep_cycle_timeA list of the exact start and end times of each sleep cycle

Snoring Analysis

The Snoring Analysis feature allows you to review the following sleep data

Data NameDefinition
snoring_stagesA list of snoring stages during the time_in_bed
(0: no snoring / 1: snoring)
time_in_snoringThe time duration, of which snoring is detected during time_in_sleep_period
time_in_no_snoringThe time duration, of which no snoring is detected during time_in_sleep_period
snoring_ratioThe ratio of time_in_snoring to time_in_sleep_period
no_snoring_ratioThe ratio of time_in_no_snoring to time_in_sleep_period
snoring_countThe number of times snoring is detected during the time_in_sleep_period

Realtime Sleep Analysis

By utilizing the Realtime Sleep Analysis feature, you can monitor the following data in real-time:

Data NameDefinition
sleep_stagesA list of numbers, indicating sleep stages during time_in_bed
snoring_stagesA list of snoring stages during the time_in_bed
(0: no snoring / 1: snoring)

API / SDK / Dashboard

The API analyzes sound data collected from a smartphone using AsleepTrack’s AI technology. It tracks the user’s sleep stages in real time and detects sleep-related sounds (e.g., snoring). After the measurement is complete, it generates a sleep report that includes total sleep time, sleep score, sleep stage distribution, sleep efficiency, and various other metrics.

The SDK simplifies the use of the API within an app by automatically processing audio data collected through the smartphone’s microphone. It converts the collected data into an analyzable format and periodically uploads it to the server. By integrating the SDK, client apps can implement sleep tracking functionality simply by calling the sleep measurement function.

The dashboard allows users to visually check sleep data measured using their logged-in account’s API Key. Before developing a report UI in the client app, the dashboard provides an easy way to verify whether sleep measurements in the test environment are functioning correctly.

Sleep Tracking Flow

Before starting full-scale development, understanding the sleep tracking flow is essential for efficient development and troubleshooting. Check the sample app’s source code to see how the following sleep tracking flow is implemented.

  1. Initialization: This step initializes the SDK. It involves creating a new User ID or closing any previously open sleep tracking sessions.
  2. Tracking: This step starts audio recording and periodically converts the data into a mel spectrogram, which is then uploaded to the server. This process allows real-time sleep state tracking.
    1. Once sleep tracking begins, the SDK operates within the client app to collect the user’s sound data and uploads it to the server every 30 seconds.
    2. The uploaded data is analyzed asynchronously by the AI server every 5 minutes, and the results are sent in real time to the client’s backend via the registered callback URL.
    3. Since the first analysis starts after 5 minutes, the user must track sleep for at least 5 minutes to receive sleep analysis results.
  3. Report: This step retrieves sleep analysis results. Once the sleep tracking session is closed and the AI server completes its analysis, sleep metrics (Stat Object) become available for review.

Valid Session and Invalid Session

A valid session refers to a session where sufficient sound data has been uploaded, allowing the AI to perform sleep analysis and provide meaningful sleep data. The minimum requirements for sleep analysis are as follows:

  • At least 5 consecutive minutes of sound data is required for sleep analysis.
    • If this condition is not met, the session will be marked as peculiarities == TOO_SHORT_FOR_ANALYSIS.
  • At least 70% of the total sleep tracking session must have properly uploaded sound data.
    • If this condition is not met, the session will be marked as peculiarities == TOO_MANY_DEFECTS_IN_SLEEP_STAGES.

An invalid session is a session where AI sleep analysis was not performed or the results were deemed invalid. Such sessions are excluded from billing.

Follow the instructions below for testing the sleep tracking

To accurately test Asleep Track's sleep tracking/analysis, 
please follow the test environment guide. Please note that sleep analysis results obtained 
in environments not adhering to this guide may not accurately reflect actual sleep patterns.

Auto Sleep Tracking

To measure sleep with an app, users typically need to press the Start Sleep Tracking button before falling asleep. However, many users forget to press this button, causing them to miss out on sleep tracking. With AsleepTrack, sleep tracking can automatically start at a specific time or under certain conditions.

Android Auto Sleep Tracking

On Android, you can directly implement the auto-tracking feature within the app. You can check how to implement automatic tracking through the Sample App provided by Asleep.

Permission

For auto tracking on Android, the Overlay permission is required. To start recording via the microphone at a specific time for automatic sleep tracking, you need the FOREGROUND_SERVICE permission.

For Android 12 (API level 31) and above, you must grant the Alarms & reminders permission to ensure precise alarms for starting auto tracking at the correct time.

After launching the app, microphone usage permission and push notification permission should be granted in advance.

Auto Sleep Tracking UX/UI

You can check the sample code for auto tracking UX/UI through the Sample App provided by Asleep. You can set up the auto tracking schedule through the Auto Tracking item in the top right corner of the app.

Select the start and end times for tracking, then set Auto Tracking to Enable and press the Save button. At this time, the alarm time is registered through the AlarmManager’s setExactAndAllowWhileIdle method.

When the tracking start time arrives, the app runs automatically in the background, a notification icon is created, and the microphone is shown as being in use. When the tracking end time arrives, a report is generated and displayed on the screen.

iOS Auto Sleep Tracking

Unlike Android, iOS requires users to manually register automation using the Shortcuts app’s Automation feature to enable auto tracking. To facilitate this, you need to implement the App intent for sleep tracking. You can check how to implement the App intent through the Sample App provided by Asleep.

Shortcuts app

The Shortcuts app, available since iOS 12, is a built-in app that allows users to set up personalized Automations based on various conditions. Through the Automation feature, you can start sleep tracking at a specific time or use various triggers supported by the Shortcuts app (e.g., Sleep Mode, WiFi connection, etc.) to start sleep tracking.

Sleep tracking start automation

Once you have selected the trigger to start sleep tracking, you need to register the sleep tracking start App Intent in the automation. First, use Open App to launch the app that integrates AsleepTrack, then register the sleep tracking start App Intent.

Sleep tracking stop automation

Just like starting sleep tracking, ending sleep tracking can also be registered for automation. Register the sleep tracking end App Intent in the automation.

Auto Sleep Tracking

When the start time for tracking arrives, the app will automatically open and begin sleep tracking. However, if the phone is locked, a modal will appear asking for confirmation to run the automation. The automation will proceed once the user accepts.

Requirements

🚧

Minimum requirements on Asleep SDK for iOS

  • Xcode 14.1 or later
  • iOS 14.0 or later
  • Swift 5.0 or later

API Key

An API key is required to use AsleepTrack SDK.

Regarding how to issue an API key, please refer to Generate API key.


Getting Ready

AsleepTrack SDK for iOS is distributed via the native Swift Package Manager built into Xcode.

Install AsleepTrack SDK

  1. In Xcode, click File > Add Packages.

  2. In the dialog that appears, enter the repository URL https://github.com/asleep-ai/asleep-sdk-ios.

  3. In Version, select Up to Next Major Version and the default option.

  4. Click Add Package button.

  5. Click Add Package button one more time.

  6. In Xcode, click Signing & Capabilities on your application target.

  7. Click + Capability button and double click Background Modes.

  8. Select Audio, AirPlay, and Picture in Picture.

  9. In Xcode, click Info on your app target.

  10. Click + and add Privacy - Microphone Usage Description.

  11. Write a microphone permission request message.

Import the Asleep SDK

import AsleepSDK

Sleep Tracking with AsleepTrack SDK

Initialize the AsleepTrack SDK

  1. Initialize config

    • If userId is nil, a new userId will be generated.
    • Enter the proxy server in baseUrl. If nil, the default base URL will be used.
    • Enter the server to receive the analysis results directly in callbackUrl. If nil, there is no callback.
    • If there is a nickname for the app you are developing, enter it in the service.
    let apiKey: String = "YOUR_API_KEY"
    let userId: String?
    let baseUrl: URL?
    let callbackUrl: URL?
    let service: String?
    let delegate: AsleepConfigDelegate = self  
    Asleep.initAsleepConfig(apiKey: apiKey,
                            userId: userId,
                            baseUrl: baseUrl,
                            callbackUrl: callbackUrl,
                            service: service,
                            delegate: self)
    
  2. Get config and user ID

    extension YourClass: AsleepConfigDelegate {
        func userDidJoin(userId: String, config: Asleep.Config) {
    	      self.userId = userId
    				self.config = config 
        }
    
        func didFailUserJoin(error: Asleep.AsleepError) {
            print(error)
        }
    
        func userDidDelete(userId: String) {
            print("\(userId) is deleted")
        }
    }
    

❗️

Should save userId in your permanent storage for join

Create SleepTrackingManager

var config: Asleep.Config?
let delegate: AsleepSleepTrackingManagerDelegate = self
var manager: Asleep.SleepTrackingManager?

if let config {
    manager = Asleep.createSleepTrackingManager(config: config,
                                                delegate: self)
}

🚧

You must use the Asleep.Config issued in userDidJoin.

Start Tracking

var manager: Asleep.SleepTrackingManager?
manager?.startTracking()

❗️

SDK needs microphone permission for startTracking()

Stop Tracking

var manager: Asleep.SleepTrackingManager?
manager?.stopTracking()
  1. Get session ID for the sleep report
    extension YourClass: AsleepSleepTrackingManagerDelegate {
        func didClose(sessionId: String) {
          	self.sessionId = sessionId
        }
    }
    

Create Reports

var config: Asleep.Config?
var reports: Asleep.Reports?

if let config {
    reports = Asleep.createReports(config: config)
}

🚧

You must use the Asleep.Config issued in userDidJoin.

Get Report

var reports: Asleep.Reports?
var sessionId: String?

if let reports, let sessionId {
    // Closure
    reports.report(sessionId: sessionId) {
        if let error = $1 {
            print(error)
            return
        }
        
        if let report = $0 {
        }
    }

    // Async
    Task {
        do {
            let report: Asleep.Model.Report = try await reports.report(sessionId: sessionId)	
        } catch {
            print(error)
        }
    }
}

📘

Run the Sample App to quickly familiarize yourself with the SDK and apply it to your actual project.

https://github.com/asleep-ai/asleep-sdk-io~~s-sampleapp-public~~

VersionHistory
v3.1.2Fixed a crash that occurred when the app was forcefully terminated.
v3.1.1Added library to enable simulator builds
v3.1.0The AI model has been upgraded to Highball, enabling two-person sleep tracking.
v2.4.7Fixed an issue where 'cannotActivateInBackground' error was being delegated when the microphone could not be reactivated after an interrupt.
v2.4.6Added signing in Asleep SDK.
v2.4.51. Added function ‘resumeTracking’ in SleepTrackingManager.
2. Added Error code ‘cannotActivateInBackground’.
3. Fixed issue in AVAudioEngineConfigurationChange when the app is in resumed state.
4. Removed retry logic for when the app resumes after being interrupted by the system.
v2.4.4Added retry logic for when the app resumes after being interrupted by the system.
v2.4.3Fixed Mic Recording abnormal behavior after sleeping calls.
v2.4.2Fix sdk version debug message.
v2.4.1Remove Personally Identifiable APIs (Does not need to be applied "PrivacyInfo.xcprivacy").
v2.4.0Add snoring data in Report and Average Stats.
Audio Interrupt Bug fix (Timing changes between audio-related interrupts and processing audio settings).
v2.3.0Average-stats, sleep_index are added.
v2.2.01. Add Developer Mode Function.
2. Add Error Codes related to audio processing- audioInitializationFailed, responseResult3. Add Session Object parameter in Reports.- Session: unexpectedEndTime, createdTimezone.- Stat: lightLatency, deepLatency, remLatency, unstableBreathCount, sleepCycle, sleepCycleCount, sleepCycleTime, wasoCount, longestWaso.
v2.1.21. Add related to TrackingStatus.
2. Add defensive logic to close the session when initAsleepConfig is called during SleepTracking.
v2.1.11. Modified Error handling. Audio process stop during session Open / Close error case.
2. Modified Debug SDK Log.
v2.1.01. The noise reduction processing has been modified.
v2.0.01. Change Reports Structure.
2. User-Agent has been added to HTTP.

Initialize Config

Asleep.initAsleepConfig()

let apiKey: String = "YOUR_API_KEY"
let userId: String?
let baseUrl: URL?
let callbackUrl: URL?
let service: String?
let delegate: AsleepConfigDelegate = self

Asleep.initAsleepConfig(apiKey: apiKey,
                        userId: userId,
                        baseUrl: baseUrl,
                        callbackUrl: callbackUrl,
                        service: service,
                        delegate: self)
Property NameTypeDescription
apiKeyStringEnter the value obtained from the Generate API key
userIdString?When there is no initial userId, enter nil, and later input the received userId.
baseUrlURL?Enter the proxy server address. If nil, default base url is used.
callbackUrlURL?Enter the URL of the server to receive sleep session analysis results.
serviceService?Enter the app name
delegateAsleepConfigDelegateDelegate to receive results and errors

AsleepConfigDelegate

protocol AsleepConfigDelegate {
    func userDidJoin(userId: String, config: Asleep.Config)
    func didFailUserJoin(error: Asleep.AsleepError)
    func userDidDelete(userId: String)
}
  1. If success, userDidJoin() is called.

    Property NameTypeDescription
    userIdStringgenerated userId
    configAsleep.Configgenearated config
  2. If failure, didFailUserJoin() is called.

    Property NameTypeDescription
    errorAsleep.AsleepErrorError Codes
  3. userDidDelete()
    If success, all user data including the userId will be deleted.

    Property NameTypeDescription
    userIdStringDeleted userId

Delete User

Asleep.deleteUser()

var config: Asleep.Config? 
if let config {
		Asleep.deleteUser(config: config)
}
Property NameTypeDescription
configAsleep.ConfigEnter the Asleep.Config instance

Create manager

Asleep.createSleepTrackingManager()

var config: Asleep.Config?
let delegate: AsleepSleepTrackingManagerDelegate = self
var manager: Asleep.SleepTrackingManager?

if let config {
    manager = Asleep.createSleepTrackingManager(config: config,
                                                delegate: delegate)
}
Property NameTypeDescription
configAsleep.ConfigEnter the Asleep.Config instance
delegateAsleepConfigDelegateDelegate to receive results and errors

AsleepSleepTrackingManagerDelegate

protocol AsleepSleepTrackingManagerDelegate {
    func didCreate()
    func didUpload(sequence: Int)
    func didClose(sessionId: String)
    func didFail(error: Asleep.AsleepError)
    func didInterrupt()
    func didResume()
    func micPermissionWasDenied()
    func analysing(session: Asleep.Model.Session)
}
  1. didCreate()
    Tracking is generated.

  2. didUpload()
    Data is uploaded.

    Property NameTypeDescription
    sequenceIntA value that starts from 0 and increases by 1 every 30 seconds
  3. didClose()
    Tracking is terminated.

    Property NameTypeDescription
    sessionIdStringReport result id value
  4. didFail()
    Due to error, tracking is ended

    Property NameTypeDescription
    errorAsleep.AsleepErrorError Codes
  5. didInterrupt()
    Tracking is interrupted due to events such as calls.

  6. didResume()
    Tracking resumes once the interrupting factor is resolved.

  7. micPermissionWasDenied()
    Tracking cannot be started without microphone permission.

  8. analysing()
    Latest session data

    Property NameTypeDescription
    sessionAsleep.Model.Sessionduring analysis, tracking session information

Start sleep tracking

Asleep.SleepTrackingManager.startTracking()

var manager: Asleep.SleepTrackingManager?
manager?.startTracking()

🚧

Follow the guideline for testing the sleep tracking

To accurately test Asleep's sleep tracking/analysis, 
please follow the test environment guide. Please note that sleep analysis results obtained 
in environments not adhering to this guide may not accurately reflect actual sleep patterns.

🔗 Check Test Environment Guideline


Request the latest analyzed sleep data

Asleep.SleepTrackingManager.requestAnalysis()

var manager: Asleep.SleepTrackingManager?
manager?.requestAnalysis()

Stop sleep tracking

Asleep.SleepTrackingManager.stopTracking()

var manager: Asleep.SleepTrackingManager?
manager?.stopTracking()

Get sleep tracking status

Asleep.SleepTrackingManager.getTrackingStatus()

var manager: Asleep.SleepTrackingManager?
let trackingStatus = manager?.getTrackingStatus()

Resume tracking

Asleep.SleepTrackingManager.resumeTracking()

  • If a cannotActivateInBackground error occurs during sleep tracking, notify the user (e.g., through a notification), and run Asleep.SleepTrackingManager.resumeTracking() while the app is in the foreground.
var manager: Asleep.SleepTrackingManager?
manager?.resumeTracking()

Data Type

Asleep.SleepTrackingManager.TrackingStatus

struct TrackingStatus {
    var sessionId: String?
}
Property nameTypeDescription
sessionIdString?Currently tracking session id
Available from the didCreate function of AsleepSleepTrackingManagerDelegate
Valid until the corresponding Session is closed

Asleep.Model.Session

struct Session {
    let id: String
    let state: State
    let startTime: Date
    let endTime: Date?
    let unexpectedEndTime: Date?
    let createdTimezone: String
    let sleepStages: [Int]?
    let snoringStages: [Int]?
}

enum State {
    case open
    case closed
    case complete
}

Property nameTypeDescriptionVersion
idStringSleep session id
stateAsleep.Model.StateSleep session state (OPEN, CLOSED, or COMPLETE)
startTimeDateSession start time
endTimeDate?Session end date
unexpectedEndTimeDate?If a session fails to proceed and terminate properly due to app crashes or similar issues, and the client later executes initConfig to terminate the session, the time at which this happens is recorded. In this case, the "end_time" is calculated based on the sequence number of the last uploaded audio file. Therefore, if "end_time" is not null, it indicates an abnormal session.
createdTimezoneStringTimezone of session creation (Timezone List)
sleepStagesArray<Int>Sleep stages
-1: error
0 : wake
1 : light
2 : deep
3 : rem
snoringStagesArray<Int>Snoring stages
-1: error
0 : no snoring
1 : snoring

Create report

Asleep.createReports()

var config: Asleep.Config?
var reports: Asleep.Reports?

if let config {
    reports = Asleep.createReports(config: config)
}
Property NameTypeDescription
configAsleep.ConfigEnter Asleep.Config instance

Get a single report

Asleep.Reports.report()

var reports: Asleep.Reports?
let sessionId: String

// Closure
reports?.report(sessionId: sessionId, completionBlock: { (report: Asleep.Report?, error: Asleep.AsleepError?) in
    if let error {
        print(error)
        return
    }
    
    if let report {
    }
})

// Async
Task {
    do {
        let report = try await reports?.report(sessionId: sessionId)
    } catch {
        print(error)
    }
}
Property NameTypeDescription
sessionIdStringsessionId that can be received when stopping tracking
completionBlockAsleep.Model.Report?If nil, an error occurs.
Asleep.AsleepError?Error Codes

Get multiple reports

Asleep.Reports.reports()

var reports: Asleep.Reports?
let fromDate: String = "2023-05-01"
let toDate: String = "2023-05-07"

// Closure
reports?.reports(fromDate: fromDate, toDate: toDate, completionBlock: { (reportSessions: [Asleep.Model.SleepSession]?, error: Asleep.AsleepError?) in
    if let error {
        print(error)
        return
    }
    
    if let reportSessions {
    }
})

// Async
Task {
    do {
        let reportSessions = try await reports?.reports(fromDate: fromDate, toDate: toDate)
    } catch {
        print(error)
    }
}
Property NameTypeDescription
fromDateString (YYYY-MM-DD)View date start
toDateString (YYYY-MM-DD)View date end
orderBy

- default value: .descending
Asleep.Model.OrderBy [.ascending, .descending]DESC: Descending prder
ASC: Ascending order
offset

- default value: 0
IntNumber of reports to skip
limit

- default value: 20
IntMaximum number of report
(0~100)
completionBlockArray<Asleep.Model.SleepSession>?If nil, an error occurs.
Asleep.AsleepError?Error Codes

Get average stats

Asleep.Reports.getAverageReport()

var reports: Asleep.Reports?
let fromDate: String = "2023-05-01"
let toDate: String = "2023-05-07"

// Closure
reports?.getAverageReport(fromDate: fromDate, toDate: toDate, completionBlock: { (averageReport: Asleep.Model.AverageReport?, error: Asleep.AsleepError?) in
    if let error {
        print(error)
        return
    }
    
    if let averageReport {
    }
})

// Async
Task {
    do {
        let averageReport = try await reports?.getAverageReport(fromDate: fromDate, toDate: toDate)
    } catch {
        print(error)
    }
}
Property NameTypeDescription
fromDateString (YYYY-MM-DD)The starting time for the period you want to check the average
toDateString (YYYY-MM-DD)The ending time for the period you want to check the average
completionBlockAsleep.Model.AverageReport?If nil, an error occurs.
Asleep.AsleepError?Error Codes

Delete report

❗️

Caution: Data Deletion

When session data is deleted from the Asleep server upon a request, it becomes difficult to provide specific evidence for the deleted sessions during subsequent billing usage analysis.

Asleep.Reports.deleteReport()

var reports: Asleep.Reports?
let sessionId: String

// Closure
reports?.deleteReport(sessionId: sessionId, completionBlock: { (error: Asleep.AsleepError?) in
    if let error {
        print(error)
        return
    }
})

// Async
Task {
    do {
        try await deleteReport?.deleteReport(sessionId: sessionId)
    } catch {
        print(error)
    }
}
Property NameTypeDescription
sessionIdStringsessionId to be deleted
completionBlockAsleep.AsleepError?Error Codes

Data Type

Asleep.Model.Report

struct Report {
    let timezone: String
    let peculiarities: [Peculiarity]
    let missingDataRatio: Float
    let session: Session
    let stat: Stat?
}

enum Peculiarity {
    case inProgress
    case neverSlept
    case tooShortForAnalysis
    case tooLongForAnalysis
    case tooManyDefectsInSleepStages
    case noBreathingStability
    case noRealtimePolling
}
Property nameTypeDescription
timezoneStringThe adjusted time zone of the analysis result
e.g. UTC, Asia/Seoul (Timezone List)
peculiaritiesAsleep.Model.PeculiarityA field for describing any specific details or peculiarities of the sleep session. This field can include multiple labels below.

IN_PROGRESS: If the session is OPEN, CLOSED
NEVER_SLEPT: If it is determined that there was no sleep at all during the session measurement time
TOO_SHORT_FOR_ANALYSIS: When the measurement time is too short to conduct a valid analysis (currently less than 5 minutes)
TOO_LONG_FOR_ANALYSIS: Analysis has been conducted successfully, but the session measurement time is excessively long, making it difficult to trust (currently exceeding 24 hours)
TOO_MANY_DEFECTS_IN_SLEEP_STAGES: When the error rate is high due to factors like missing audio uploads, resulting in insufficient sleep analysis results.
NO_BREATHING_STABILITY: When the customer's contract conditions do not support breathing stability analysis.
NO_REALTIME_POLLING: When, according to the customer's contract, real-time access to sleep information is not available.
missing_data_ratioFloatt(0~1 range, decimal points)The error rate in sleep analysis results due to reasons such as missing audio uploads
sessionAsleep.Model.SessionSession Report information
statAsleep.Model.StatAnalysis Report information

Asleep.Model.Session

struct Session {
    let id: String
    let state: State
    let startTime: Date
    let endTime: Date?
    let unexpectedEndTime: Date?
    let createdTimezone: String
    let sleepStages: [Int]?
    let snoringStages: [Int]?
}

enum State {
    case open
    case closed
    case complete
}
Property nameTypeDescriptionVersion
idStringSession Id
stateAsleep.Model.StateSleep session state (OPEN, CLOSED, or COMPLETE)
startTimeDateSession start time
endTimeDate?Session end time
unexpectedEndTimeDate?If a session fails to proceed and terminate properly due to app crashes or similar issues, and the client later executes initConfig to terminate the session, the time at which this happens is recorded. In this case, the "end_time" is calculated based on the sequence number of the last uploaded audio file. Therefore, if "end_time" is not null, it indicates an abnormal session.
createdTimezoneStringTimezone of session creation (Timezone List)
sleepStagesArray<Int>Sleep stages
-1: error
0 : wake
1 : light
2 : deep
3 : rem
snoringStagesArray<Int>Snoring stages
-1: error
0 : no snoring
1 : snoring

Asleep.Model.Stat

struct Stat {
    let sleepEfficiency: Float?
    let sleepLatency: Int?
    let sleepTime: Date?
    let wakeupLatency: Int?
    let wakeTime: Date?
    let lightLatency: Int?
    let deepLatency: Int?
    let remLatency: Int?
    let timeInWake: Int?
    let timeInSleepPeriod: Int?
    let timeInSleep: Int?
    let timeInBed: Int?
    let timeInRem: Int?
    let timeInLight: Int?
    let timeInDeep: Int?
    let timeInSnoring: Int?
    let timeInNoSnoring: Int?
    let wakeRatio: Float?
    let sleepRatio: Float?
    let remRatio: Float?
    let lightRatio: Float?
    let deepRatio: Float?
    let snoringRatio: Float?
    let noSnoringRatio: Float?
    let sleepCycle: Int?
    let sleepCycleCount: Int?
    let sleepCycleTime: [Date]?
    let wasoCount: Int?
    let longestWaso: Int?
    let sleepIndex: Int?
    let snoringCount: Int?
}
Property nameTypeDescriptionVersion
sleepEfficiencyFloat?The percentage of time you actually slept during sleep measurement
sleepLatencyInt?time it took to fall asleep
sleepTimeDate?The time it takes to fall asleep after the start of sleep measurement
wakeupLatencyInt?The time it takes to wake up and end your sleep measurement
wakeTimeDate?wake up time
lightLatencyInt?The time it takes to the first Light after the start of sleep.
deepLatencyInt?The time it takes to the first Deep after the start of sleep.
remLatencyInt?The time it takes to the first REM after the start of sleep.
timeInWakeInt?wake during sleep
timeInSleepPeriodInt?During sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
timeInSleepInt?During sleep measurement time, the time you were actually sleeping
Classified into three stages: deep, light, rem
timeInBedInt?The time from the start of the sleep measurement to the end of the sleep measurement
timeInRemInt?Total time the sleep phase progressed to rem
timeInLightInt?Total time the sleep phase progressed to light
timeInDeepInt?Total time the sleep phase progressed to deep
timeInSnoringInt?Total time of snoring
timeInNoSnoringInt?Total time of no snoring
wakeRatioFloat?Rate of waking time in the middle during sleep stage
sleepRatioFloat?The percentage of time you sleep without waking during the sleep phase
remRatioFloat?Rate of REM sleep during sleep stage
lightRatioFloat?Rate of light sleep during sleep stage
deepRatioFloat?Rate of deep sleep during sleep stage
snoringRatioFloat?The percentage of time during the sleep phase that there was a snoring section
noSnoringRatioFloat?The percentage of time during the sleep phase that there was no snoring.
sleepCycleInt?The average duration of one sleep cycle.
sleepCycleCountInt?The number of sleep cycles.
sleepCycleTime[Date]?Transition time for sleep cycles
[First sleep cycle onset time, first sleep cycle end time, second sleep cycle end time, ..., last sleep cycle end time]
wasoCountInt?The number of times 'wake' occurred during the sleep period
longestWasoInt?The duration of the longest 'wake' during the sleep period
sleepIndexInt?The metric that comprehensively represents sleep quality, defined by learning from the distribution of sleep data
snoringCountInt?The number of times snoring occurred

Asleep.Model.SleepSession

struct SleepSession {
    let sessionId: String
    let state: State
    let sessionStartTime: Date
    let sessionEndTime: Date?
    let createdTimezone: String
    let unexpectedEndTime: Date?
    let lastReceivedSeqNum: Int
    let timeInBed: Int
}

enum State {
    case open
    case closed
    case complete
}
Property nameTypeDescriptionVersion
sessionIdStringSleep session ID
stateAsleep.Model.StateStatus of Session
'OPEN': An in-progress session, with audio uploads available
'CLOSED': The session terminated by sending an end session request. Unable to upload audio files. Analysis of uploaded sleep audio is still in progress
'COMPLETE': All sleep analysis completed after the end of the session
sessionStartTimeDateSession start time
sessionEndTimeDate?Session end time
createdTimezoneStringTimezone of session creation (Timezone List)
unexpectedEndTimeDate?If a session fails to proceed and terminate properly due to app crashes or similar issues, and the client later executes initConfig to terminate the session, the time at which this happens is recorded. In this case, the "end_time" is calculated based on the sequence number of the last uploaded audio file. Therefore, if "end_time" is not null, it indicates an abnormal session.
lastReceivedSeqNumIntThe sequence number of the last uploaded audio file
timeInBedIntThe time from the start of the sleep measurement to the end of the sleep measurement

Asleep.Model.AverageReport

struct AverageReport {
    let period: Period
    let peculiarities: [Peculiarity]
    let averageStats: AverageStats?
    let neverSleptSessions: [NeverSleptSession]
    let sleptSessions: [SleptSession]
}
Property nameTypeDescription
periodAsleep.Model.Period Timezone (Timezone List)
peculiarities[Asleep.Model.Peculiarity]Special considerations when calculating the average of sleep sessions

NO_BREATHING_STABILITY: When the customer's contract conditions do not support breathing stability analysis
averageStatsAsleep.Model.AverageStats?An object containing the averages of sleep metrics for "sleptSessions"
neverSleptSessions[Asleep.Model.NeverSleptSession]A list of sessions during which it is determined that no sleep occurred at all during the measurement time.
sleptSessions[Asleep.Model.SleptSession]A list of sessions during which it is determined that sleep occurred during the measurement time.

Asleep.Model.Period

struct Period {
    let timezone: String
    let startDate: Date
    let endDate: Date
}
Property nameTypeDescription
timezoneStringrequested timezone
예. UTC, Asia/Seoul
startDateDaterequested start date
endDateDaterequested end date

Asleep.Model.AverageStats

struct AverageStats {
    let startTime: String
    let endTime: String
    let sleepTime: String
    let wakeTime: String
    let sleepLatency: Int
    let wakeupLatency: Int
    let timeInBed: Int
    let timeInSleepPeriod: Int
    let timeInSleep: Int
    let timeInWake: Int
    let timeInLight: Int?
    let timeInDeep: Int?
    let timeInRem: Int?
		let timeInSnoring: Int?
	  let timeInNoSnoring: Int?
  	let sleepEfficiency: Double
    let wakeRatio: Double
    let sleepRatio: Double
    let lightRatio: Double?
    let deepRatio: Double?
    let remRatio: Double?
	  let snoringRatio: Double?
		let noSnoringRatio: Double?
    let wasoCount: Int
    let longestWaso: Int
    let sleepCycleCount: Int
  	let snoringCount: Int?
}
Property nameTypeDescription
startTimeString(hh:mm:ss)Session start time
endTimeString(hh:mm:ss)Session end time
sleepTimeString(hh:mm:ss)The time it takes to fall asleep after the start of sleep staging
wakeTimeString(hh:mm:ss)Wake time
sleepLatencyIntTime to fall asleep
wakeupLatencyIntThe time it takes to wake up and end your sleep measurement
timeInBedIntThe time from the start of the sleep measurement to the end of the sleep measurement
timeInSleepPeriodIntDuring sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
(time_in_bed - sleep_latency - wakeup_latency)
timeInSleepIntDuring sleep measurement time, the time you were actually sleeping
This time is divided into three stages: deep,light,and rem
timeInWakeIntWake time during sleep
timeInLightInt?Total time the sleep phase progressed to light
timeInDeepInt?Total time the sleep phase progressed to deep
timeInRemInt?Total time the sleep phase progressed to rem
timeInSnoringInt?Total time of snoring
timeInNoSnoringInt?Total time of no snoring
sleepEfficiencyDoubleThe percentage of time you actually slept during sleep measurement
wakeRatioDoubleRate of waking time in the middle during sleep phase
sleepRatioDoubleDuring sleep stage, sleep ratio, not wake
lightRatioDouble?Rate of light sleep during sleep phase
deepRatioDouble?Rate of deep sleep during sleep phase
remRatioDouble?rem sleep ratio
snoringRatioDouble?The percentage of time during the sleep phase that there was a snoring section
noSnoringRatioDouble?The percentage of time during the sleep phase that there was no snoring.
wasoCountIntThe number of times 'wake' occurred during the sleep period
longestWasoIntThe duration of the longest 'wake' during the sleep period
sleepCycleCountInt?The number of sleep cycles.
snoringCountInt?The number of times snoring occurred.

Asleep.Model.NeverSleptSession

struct NeverSleptSession {
    let id: String
    let startTime: Date
    let endTime: Date
    let completedTime: Date
}
Property nameTypeDescription
idStringsession id
startTimeDateSession start time
endTimeDateSession end time
completedTimeDateTime of session analysis completion

Asleep.Model.SleptSession

struct SleptSession {
    let id: String
    let createdTimezone: String
    let startTime: Date
    let endTime: Date
    let completedTime: Date
    let sleepEfficiency: Double
    let sleepLatency: Int?
    let wakeupLatency: Int?
    let lightLatency: Int?
    let deepLatency: Int?
    let remLatency: Int?
    let sleepTime: Date?
    let wakeTime: Date?
    let timeInWake: Int
    let timeInSleepPeriod: Int
    let timeInSleep: Int
    let timeInBed: Int
    let timeInRem: Int?
    let timeInLight: Int?
    let timeInDeep: Int?
    let timeInSnoring: Int?
    let timeInNoSnoring: Int?
    let wakeRatio: Double
    let sleepRatio: Double
    let remRatio: Double?
    let lightRatio: Double?
    let deepRatio: Double?    
    let snoringRatio: Double?
    let noSnoringRatio: Double?
    let sleepCycle: Int?
    let sleepCycleCount: Int?
    let wasoCount: Int?
    let longestWaso: Int?
    let snoringCount: Int?
}
Property nameTypeDescription
idStringsession id
createdTimezoneStringTimezone of session creation
(Timezone List)
startTimeDateSession start time
endTimeDateSession end time
completedTimeDateTime of session analysis completion
sleepEfficiencyDoubleThe percentage of time you actually slept during sleep measurement
sleepLatencyInt?Time to fall asleep
wakeupLatencyInt?The time it takes to wake up and end your sleep measurement
lightLatencyInt?The time it takes to the first Light after the start of sleep
deepLatencyInt?The time it takes to the first Deep after the start of sleep
remLatencyInt?The time it takes to the first REM after the start of sleep
sleepTimeDate?The time it takes to fall asleep after the start of sleep staging
wakeTimeDate?Wake time
timeInWakeIntWake time during sleep
timeInSleepPeriodIntDuring sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
(time_in_bed - sleep_latency - wakeup_latency)
timeInSleepIntDuring sleep measurement time, the time you were actually sleeping
This time is divided into three stages: deep,light,and rem
timeInBedIntThe time from the start of the sleep measurement to the end of the sleep measurement
timeInRemInt?Total time the sleep phase progressed to rem
timeInLightInt?Total time the sleep phase progressed to light
timeInDeepInt?Total time the sleep phase progressed to deep
timeInSnoringInt?Total time of snoring
timeInNoSnoringInt?Total time of no snoring
wakeRatioDoubleRate of waking time in the middle during sleep phase
sleepRatioDoubleDuring sleep stage, sleep ratio, not wake
remRatioDouble?rem sleep ratio
lightRatioDouble?Rate of light sleep during sleep phase
deepRatioDouble?Rate of deep sleep during sleep phase
snoringRatioDouble?The percentage of time during the sleep phase that there was a snoring section
noSnoringRatioDouble?The percentage of time during the sleep phase that there was no snoring.
sleepCycleInt?The average duration of one sleep cycle
sleepCycleCountInt?The number of sleep cycles
wasoCountInt?The number of times 'wake' occurred during the sleep period
longestWasoInt?The duration of the longest 'wake' during the sleep period
snoringCountInt?The number of times snoring occurred.

Asleep.setDebugLoggerDelegate()

let delegate: AsleepDebugLoggerDelegate = self
Asleep.setDebugLoggerDelegate(self)
protocol AsleepDebugLoggerDelegate {
    func didPrint(message: String)
}
Property NameTypeDescription
messageStringLog message

Asleep.AsleepError

enum AsleepError: Error {
    case unknown(systemError: Error)    
    case shouldResume
    case over24hours
    case audioInitializationFailed
    case unsupportedInDeveloperMode
    case cannotActivateInBackground
    case startTrackingNetworkFail(code: Int, message: String?)
    case stopTrackingNetworkFail(code: Int, message: String?)  
    case responseResult(endpoint: String)
    case httpStatus(code: Int, errorCode: Int, message: String?)
}

unknown: Unknown system error

  • systemError: Error - error due to system

shouldResume: unable to resume microphone recording after interrupt

over24Hours: recording exceeded 24 hours and is forcibly stopped

  • The Asleep SDK does not support sleep tracking exceeding 24 hours.

audioInitializationFailed: Audio configuration error

  • iOS device audio initialization error
    • Call "createSleepTrackingManager()" again for Audio setting initialization

cannotActivateInBackground: Failed to resume the microphone after the interrupt ends

  • If this error occurs, notify the user (e.g., through a notification), and run Asleep.SleepTrackingManager.resumeTracking() while the app is in the foreground.

startTrackingNetworkFail: occurred Network error during startTracking initialization

  • code: http codes of 400 and above
  • message: String type - description of the error

stopTrackingNetworkFail: occurred Network error during stopTracking

  • code: http codes of 400 and above
  • message: String type - description of the error

responseResult: error due to api reponse result value

  • endpoint - The endpoint where the problem occurred

httpStatus: http error

  • code: Int - 400 or more http code
  • errorCode: Int - not using
  • message: String - error reason explanation

HTTP Status code

State: COMMON, INIT, TRACKING, REPORT

CodeTypeDescriptionStateHandling
401UnauthorizedUnauthorizedCOMMONClient Handling
401Unauthorizedinvalid user idCOMMONClient Handling
403Plan is expiredPlan is expiredCOMMONSDK Stop
403Rate limit exceededRate limit exceededCOMMONSDK Stop
403Quota exceededQuota exceededCOMMONSDK Stop
400Bad RequestInvalid callback urlTRACKINGClient Handling
400Bad Request[WARNING] Invalid session end time. format(YYYY-MM-DDTHH:mm:ssz), 'session_end_time' must always be greater than 'session_start_time’TRACKINGSDK Handling
403Forbiddenthe sleep session is already closedTRACKINGSDK Stop
404Not Foundsession does not exist.TRACKINGClient Handling
409Conflictprevious sleep session is not closed yetTRACKINGSDK Stop
422Validation ErrorInvalid parameterTRACKINGSDK Handling
422Unprocessable EntityInvalid parameter.TRACKINGSDK Handling
400Bad Requestinvalid timezoneREPORTClient Handling
400Unprocessable EntityThe format of sleep session id {session_id} is not validREPORTClient Handling
401UnauthorizedThe api key is not providedREPORTClient Handling
404Not FoundUnable to find the sleep session of id {session_id}REPORTClient Handling

Definition for SDK Error Handling

Definition of SDK Segment Operation

  • Init (initAsleepConfig) : SDK Initialization State
  • Tracking (SleepTrackingManager): Audio recording environment and server communication protocol management for sleep monitoring
  • Report (Reports): Request sleep monitoring results

Error Case Definition

  • SDK Stop: Termination process within the SDK. The SDK needs to be restarted for a new start because it is terminated internally. Depending on the status of the SDK, the session and audio recording function are terminated by itself. You need to start from the "initAsleepConfig" request to activate the SDK
  • SDK Handling: The SDK updates the error internally and performs the next action. If you want to terminate after receiving an error, you need to handle it depending on the state of the SDK call. To terminate the SDK, you need to call stopTracking only in the Tracking state, and no separate processing is required in other sections
  • Client Handling: An error that needs to be handled by the client. Used for error checking during development.
  • Do not used: An error that is not used in the current version.

Error Handling Classification

  • The error codes that commonly occur when using the SDK are marked in red. The error codes that are crossed out have a low probability of occurring.

Requirements

🚧

Minimum requirements on AsleepTrack SDK for Android

  • Android 7.0 (API level 24) or higher
  • Java 1.8 or higher
  • Android Gradle plugin 8.0 or higher

API Key

  • The API key is required to use the Asleep Track SDK.
  • For how to issue an API key, see this link [Generate API key]

Getting Ready

Install AsleepTrack SDK and Settings

  1. Create a project using Android Studio.
  2. Open the AndroidManifest.xml file to add permissions.
<manifest ...>
  	
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"/>
  <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

  <application ...>
    ...
  </application>
</manifest>
    
  1. Open the app-level build.gradle file and add lifecycle-service, okhttp, gson, and asleepsdk.
dependencies {
  ...
  implementation("androidx.lifecycle:lifecycle-service:2.8.7")
  implementation("com.squareup.okhttp3:okhttp:4.11.0")
  implementation("com.google.code.gson:gson:2.10")
  implementation("ai.asleep:asleepsdk:3.1.0")
}
dependencies {
		...
    implementation 'androidx.lifecycle:lifecycle-service:2.8.7'
    implementation 'com.squareup.okhttp3:okhttp:4.11.0'
    implementation 'com.google.code.gson:gson:2.10'
    implementation 'ai.asleep:asleepsdk:3.1.0'
}

Sleep Tracking with AsleepTrack SDK

Permission Acquisition

  • Acquire the required permissions: RECORD_AUDIO and POST_NOTIFICATIONS (for Android 13 and above).
class MainActivity : AppCompatActivity() {
  
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...

    ActivityCompat.requestPermissions(
      this@MainActivity,
      arrayOf(android.Manifest.permission.RECORD_AUDIO,
              android.Manifest.permission.POST_NOTIFICATIONS),
      0)
      ...
  }

UI

  • Create buttons for Init, Begin, End, and Report to be displayed on the screen.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_init"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="200dp"
        android:text="init"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_begin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="32dp"
        android:text="begin"
        app:layout_constraintEnd_toStartOf="@+id/btn_end"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_init" />

    <Button
        android:id="@+id/btn_end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:text="end"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/btn_begin"
        app:layout_constraintTop_toBottomOf="@+id/btn_init" />

    <Button
        android:id="@+id/btn_report"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="report"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_init" />
          
</androidx.constraintlayout.widget.ConstraintLayout>
  • Declare the buttons as variables.
    ...
    private lateinit var btnInit: Button
    private lateinit var btnBegin: Button
    private lateinit var btnEnd: Button
    private lateinit var btnReport: Button

    ...
    btnInit = findViewById(R.id.btn_init)
    btnBegin = findViewById(R.id.btn_begin)
    btnEnd = findViewById(R.id.btn_end)
    btnReport = findViewById(R.id.btn_report)

AsleepTrack SDK Initialization

  • Replace [YOUR API KEY] in apiKey with the actual issued API Key.
  • If userId is null, the SDK will generate a new userId.
  • In a real app implementation, the generated userId should be stored and retrieved as needed.
  • service: If the app has a specific service name, enter it here.
  • asleepConfigListener: Provides a callback for initialization success or failure.
    • On success, userId and asleepConfig are returned.
val TAG = "[AsleepSDK]"
private var createdUserId: String? = null
private var createdAsleepConfig: AsleepConfig? = null
private var createdSessionId: String? = null

...
btnInit.setOnClickListener {
  Asleep.initAsleepConfig(
    context = this,
    apiKey = "[YOUR API KEY]",
    userId = null,
    service = "Test App",
    asleepConfigListener = object: Asleep.AsleepConfigListener {
      override fun onFail(errorCode: Int, detail: String) {
        Log.d(TAG, "initAsleepConfig onFail $errorCode $detail")
      }

      override fun onSuccess(userId: String?, asleepConfig: AsleepConfig?) {
        Log.d(TAG, "initAsleepConfig onSuccess $userId")
        createdUserId = userId
        createdAsleepConfig = asleepConfig
      }
    })
}

Begin SleepTracking

  • Start sleep tracking.
    1. Pass the asleepConfig generated from initAsleepConfig and the asleepTrackingListener to monitor the sleep tracking status.
    2. When tracking begins, the onStart() callback is triggered.
    3. The onPerform() callback is called every 30 seconds to provide progress updates.
    4. When tracking ends, the onFinish() callback is triggered.
btnBegin.setOnClickListener {
  createdAsleepConfig?.let { asleepConfig ->

    Asleep.beginSleepTracking(
      asleepConfig = asleepConfig,
      asleepTrackingListener = object : Asleep.AsleepTrackingListener {
        override fun onFail(errorCode: Int, detail: String) {
          Log.d(TAG, "beginSleepTracking onFail $errorCode $detail")
        }

        override fun onFinish(sessionId: String?) {
          Log.d(TAG, "beginSleepTracking onFinish $sessionId")
        }

        override fun onPerform(sequence: Int) {
          Log.d(TAG, "beginSleepTracking onPerform $sequence")
        }

        override fun onStart(sessionId: String) {
          Log.d(TAG, "beginSleepTracking onStart $sessionId")
          createdSessionId = sessionId
        }
      })
  }
}

End SleepTracking

  • End sleep tracking.
btnEnd.setOnClickListener {
  Asleep.endSleepTracking()
}

Get Report

  • Retrieve the recorded sleep data.
    1. Create a Reports object by passing the asleepConfig generated from initAsleepConfig.
    2. Provide the sessionId that was created during sleep tracking.
btnReport.setOnClickListener {
  createdSessionId?.let { sessionId ->

    val reports = Asleep.createReports(createdAsleepConfig)

    reports?.getReport(
      sessionId = sessionId,
      reportListener = object : Reports.ReportListener {
        override fun onFail(errorCode: Int, detail: String) {
          Log.d(TAG, "getReport onFail $errorCode $detail")
        }
        override fun onSuccess(report: Report?) {
          Log.d(TAG, "getReport onSuccess $report")
        }
      })
  }
}

Logcat Verification

  • If the logcat logs show that userId, sessionId, and report have been successfully created as shown below, the SDK is functioning correctly.

📘

Important Considerations for App Development

  • Using Foreground Service
    For sleep tracking, the app must continuously record, process data, and perform network operations throughout the night.
    To prevent interruptions, it is essential to implement a Foreground Service in your app.
    Refer to the Android Foreground Service Guide for more details.

    Our SDK supports two development approaches:

    1. Begin-End Method
      • The foreground service is built into the SDK, abstracting all sleep tracking operations.
      • Developers do not need to implement a foreground service in the app.
      • Simply call beginSleepTracking() and endSleepTracking() to implement sleep tracking easily.
      • Refer to the Begin-End Sample App.
    2. SleepTrackingManager Method
      • This approach provides more control by allowing developers to implement the foreground service directly.
      • While it is more complex, it is useful for controlling hardware based on sleep stages or implementing custom actions.
      • Refer to the FGS Process Separation Sample App.
      • Choose the method that best fits your app’s requirements.
  • Recommended: In-App Update Feature

    • In-App Update Guide
    • If an Android app update occurs automatically after sleep tracking starts, the app may close unexpectedly, causing an abnormal session termination.
    • To avoid this, use In-App Updates, which allow users to update the app in advance, preventing unintended interruptions.
  • Battery Optimization Exception

    • Doze-Standby Guide
    • To ensure stable sleep tracking, battery optimization exceptions are required.
    • This prevents the device from entering Doze Mode during sleep tracking.
    • The permission is set using REQUEST_IGNORE_BATTERY_OPTIMIZATIONS.
VersionHistory
v3.1.2Fixed an issue where changes to the apiKey were not recognized.
Added missing libraries for 32-bit devices.
v3.1.1Exception handling for errors occurring only on Android 13.
v3.1.0The AI model has been upgraded to Highball, enabling two-person sleep tracking.
Added begin and end functions to manage foreground services within the SDK.
v2.4.21. Added AsleepLogger Interface: A new interface, AsleepLogger, has been introduced, featuring four methods: d, e, i, and w.
2. Enhanced Configuration with Logging: The initAsleepConfig function has been updated to include an AsleepLogger parameter as its final argument.
3. Removed Direct Android Log Outputs: In alignment with our new logging approach, direct usage of the Android Log class within the SDK has been removed.
v2.4.1Added an optional ‘isPrivacySensitive’ parameter to ‘startSleepTracking()’ to optionally select the privacy sensitive feature of the AudioRecord. The default is true.
v.2.4.0Add snoring data to Report and Average Stats.
Add setPrivacySensitive during Recording.
v2.3.0Average-stats, sleep_index are added.
Added functionality to continue the session.
Changed some functions to asynchronous processing.
v2.2.2Android 14 compatibility has been addressed in the hotfix.
v2.2.1Fixed obfuscation bug for sessionId in getTrackingStatus.
v2.2.01. Add Developer Mode Function.
2. Add Error Codes related to audio processing- ERR_AUDIO_SILENCED, ERR_AUDIO_UNSILENCED3. Add Session Object parameter in Reports- createdTimezone, unexpectedEndTime, sleepCycle, sleepCycleCount, wasoCount, longestWaso, unstableBreathCount, lightLatency, remLatency, deepLatency.
v2.1.21. Redefine errorCode.
2. Add related to TrackingStatus.
3. Add defensive logic to close the session when initAsleepConfig is called during SleepTracking.
v2.1.11. Ensuring Visibility of AsleepErrorCode Interface.
2. Implementing ERR_NETWORK Listener for Handing Internet Coneection Issues.
3. Changing HTTP Keep-Alive Time to 10 Seconds.
v2.1.01. The noise reduction processing has been modified.
2. User-Agent has been added to HTTP.
v2.0.01. Change Reports Structure.

Initialize Config

Asleep.initAsleepConfig()

  • Initialize the SDK.
initAsleepConfig(
    context: Context, 
    apiKey: String, 
    userId: String?, 
    baseUrl: String?, 
    callbackUrl: String?, 
    service: String?, 
    asleepConfigListener: Asleep.AsleepConfigListener,
    asleepLogger: AsleepLogger?
)
Parameter NameTypeDescription
contextContextEnter ApplicationContext
apiKeyStringEnter the value issued by Generate API key
userIdString?Enter null if there is no initial userId, and enter the userId that has been issued since
baseUrlString?If null, use the default value, enter the proxy server address
callbackUrlString?Enter the url of the server to receive sleep session analysis results
serviceString?your app name
asleepConfigListenerAsleepConfigListenerlistener to receive callback for userId
asleepLoggerAsleepLogger?A listener for receiving SDK log callbacks

Asleep.ConfigListener

interface AsleepConfigListener {
    fun onSuccess(userId: String?, asleepConfig: AsleepConfig?)
    fun onFail(errorCode: Int, detail: String)
}
  • If success, onSuccess()is called.
Parameter NameTypeDescription
userIdString?Newly issued or entered userId
asleepConfigAsleepConfig?Required set value to use the SDK
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntAsleepErrorCode
detailStringerrorCode Message

Asleep.AsleepLogger

interface AsleepLogger {
  fun d(tag: String, msg: String, throwable: Throwable? = null)
  fun e(tag: String, msg: String, throwable: Throwable? = null)
  fun i(tag: String, msg: String, throwable: Throwable? = null)
  fun w(tag: String, msg: String, throwable: Throwable? = null)
}
  • Inside the SDK, it is called when d(debug), e(error), i(info), and w(warn) occur, respectively.
Parameter NameTypeDescription
tagString"[Asleep SDK]"
msgStringlog message
throwableThrowable?A class that represents problems that can occur during SDK execution.

Delete User

Asleep.deleteUser()

  • Delete all data of the user, including userId.
fun deleteUser(deleteUserIdListener: DeleteUserIdListener?)
Parameter NameTypeDescription
deleteUserIdListenerDeleteUserIdListener?listener to receive callback for deleted userId

Asleep.DeleteUserIdListener

interface DeleteUserIdListener {
    fun onSuccess(userId: String?)
    fun onFail(errorCode: Int, detail: String)
}
  • If success, onSuccess()is called.
Parameter NameTypeDescription
userIdString?deleted userId
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode Message

Continue Session

Asleep.hasUnfinishedSession()

  • After the foreground service is forcibly terminated and restarted, it checks if there is any session that has not been terminated.
hasUnfinishedSession(context: Context): Boolean
Parameter NameTypeDescription
contextContext?Enter ApplicationContext

Asleep.getSavedAsleepConfig()

  • After the foreground service is forcibly terminated and restarted, it retrieves the previously saved asleepConfig.
getSavedAsleepConfig(context: Context, apiKey: String): AsleepConfig?
Parameter NameTypeDescription
contextContext?Enter ApplicationContext
apiKeyStringEnter the value issued by Generate API key

For sleep tracking, the app must continuously perform recording, data processing, and network operations throughout the night. However, the Android OS may enter Doze Mode, which can disable microphone and network resources or suspend running processes, imposing various restrictions. As a result, the sleep tracking process may be interrupted.

To address this issue, developers typically use a Foreground Service to separate tasks into a persistent process. However, this approach can be complex and challenging to implement.

To simplify this process, we have abstracted all these complexities within the SDK. Now, developers can easily start and stop sleep tracking by simply calling beginSleepTracking() and endSleepTracking(). This reduces the development burden and enables a faster and more stable implementation of sleep tracking functionality.

📘

Additional Guidance for Hardware Control

If hardware control must be guaranteed based on Sleep Stage values during sleep, the built-in SDK functionality may have limitations.
In such cases, you should either:

  • Implement control using a Webhook Server.
  • Design a custom Foreground Service to ensure uninterrupted operation throughout the night.

Begin SleepTracking

Asleep.beginSleepTracking()

  • This function starts the sleep tracking process, and the following tasks are performed automatically:

    1. Foreground Service Execution: The Foreground Service starts automatically, ensuring background tasks remain stable.
    2. Notification Display:
      • According to Android system policies, a notification will be displayed in the status bar while the foreground service is running.
      • This notification informs the user that sleep tracking is in progress and can support user interaction if needed.
    3. Start Sleep Tracking:
      • The SleepTrackingManager immediately begins the sleep tracking process.
beginSleepTracking(
		asleepConfig: AsleepConfig,
  	notificationClass: Class<*>? = null,
  	notificationTitle: String? = null,
  	notificationText: String? = null,
  	notificationIcon: Int? = null,
  	asleepTrackingListener: AsleepTrackingListener
)
ParameterTypeDescription
asleepConfigAsleepConfigValue received from initAsleepConfig.
notificationClassClass<*>?Activity to open when tapping the foreground service notification.
notificationTitleString?Title of the foreground service notification.
notificationTextString?Body text of the foreground service notification.
notificationIconInt?Icon resource for the foreground service notification.
asleepTrackingListenerAsleep.AsleepTrackingListenerListener to receive callbacks during sleep tracking

Asleep.AsleepTrackingListener

  • An interface that provides callbacks for the start, end, and status of sleep tracking.
interface AsleepTrackingListener {
  	fun onStart(sessionId: String)
  	fun onPerform(sequence: Int)
  	fun onFinish(sessionId: String)
  	fun onFail(errorCode: Int, detail: String)
}
FunctionParameterTypeDescription
onStartsessionIdStringCalled when sleep tracking starts, providing the session ID.
onPerformsequenceIntCalled every 30 seconds during analysis, providing a sequence value starting from 0.
onFinishsessionIdStringCalled when sleep tracking ends, providing the session ID of the completed session.
onFailerrorCodeIntCalled if an error occurs during the sleep tracking process, returning an errorCode.
detailStringAdditional description related to the errorCode.

Termination Based on Error Codes

If the following errors are returned in the errorCode parameter of onFail(), sleep tracking is considered unable to continue and will automatically terminate, triggering the onFinish() callback.

ERR_AUDIO, ERR_CREATE_FAILED, ERR_CREATE_UNAUTHORIZED, ERR_CREATE_CONFLICT, ERR_CREATE_VALIDATION, ERR_CREATE_SERVER_ERROR, ERR_UPLOAD_BAD_REQUEST, ERR_UPLOAD_UNAUTHORIZED, ERR_UPLOAD_FORBIDDEN, ERR_UPLOAD_NOT_FOUND, ERR_UPLOAD_TOO_LARGE, ERR_CLOSE_FAILED, ERR_CLOSE_BAD_REQUEST, ERR_CLOSE_UNAUTHORIZED, ERR_CLOSE_FORBIDDEN, ERR_CLOSE_NOT_FOUND, ERR_CLOSE_SERVER_ERROR

For other errors, sleep tracking will not be terminated, even if temporary issues prevent proper measurement:

ERR_AUDIO_SILENCED, ERR_AUDIO_UNSILENCED, ERR_UPLOAD_FAILED

Asleep.getCurrentSleepData()

  • Retrieves real-time sleep data measured so far.
Asleep.getCurrentSleepData(asleepSleepDataListener = object: Asleep.AsleepSleepDataListener {
  	override fun onSleepDataReceived(session: Session) {
  	}
  	override fun onFail(errorCode: Int, detail: String) {
  	}
})

Asleep.AsleepSleepDataListener

  • On success, retrieves the session values through the onSleepDataReceived() function.
  • On failure, returns an errorCode through the onFail() function.
interface AsleepSleepDataListener {
  	fun onSleepDataReceived(session: Session)
		fun onFail(errorCode: Int, detail: String)
}

Asleep.isSleepTrackingProcessAlive()

  • This function checks whether sleep tracking is currently in progress.
  • If the Foreground Service is running, it returns true.
  • When the app starts, calling this function will determine if sleep tracking is active.
    • If true is returned, the app should display a UI indicator to inform the user that sleep tracking is in progress.
Asleep.isSleepTrackingProcessAlive(context: Context)

Asleep.connectSleepTracking()

  • If isSleepTrackingProcessAlive() returns true, it means sleep tracking is running normally.
  • In this case, re-register the AsleepTrackingListener to receive events and data related to the sleep tracking status.
  • This ensures synchronization between the sleep tracking process and the UI state.
Asleep.connectSleepTracking(asleepTrackingListener: AsleepTrackingListener)

End SleepTracking

Asleep.endSleepTracking()

This function stops the sleep tracking session started with beginSleepTracking().

  • Calling this function immediately halts sleep tracking.
  • The Foreground Service is also terminated, ensuring that all sleep tracking-related processes are safely and completely stopped.
Asleep.endSleepTracking()

📘

Refer to the Sample App for Sleep Tracking using the Begin-End method.

Create manager

Asleep.createSleepTrackingManager

  • Create SleepTrackingManager that manages Sleep Tracking Feature.
fun createSleepTrackingManager(
    asleepConfig: AsleepConfig?, 
    trackingListener: SleepTrackingManager.TrackingListener
): SleepTrackingManager?
Parameter NameTypeDescription
asleepConfigAsleepConfig?Enter the set value received by the callback in the initAsleepConfig call
trackingListenerTrackingListenerListener to receive callback status for Sleep Tracking

Asleep.SleepTrackingManager.TrackingListener

interface TrackingListener {
    fun onCreate()
    fun onUpload(sequence: Int)
    fun onClose(sessionId: String)
    fun onFail(errorCode: Int, detail: String)
}
  • When Sleep Tracking starts, onCreate() is called, and onUpload() is called every 30 seconds.
Parameter NameTypeDescription
sequenceIntA value that starts from 0 and increases by 1 every 30 seconds
  • When Sleep Tracking is ended, onClose()is called.
Parameter NameTypeDescription
sessionIdStringReport Result id value
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode Message

Start sleep tracking

Asleep.SleepTrackingManager.startSleepTracking

  • Start Sleep Tracking. If called without parameters, 'isPrivacySensitive' is set to true (recommended).
fun startSleepTracking()
// or
fun startSleepTracking(isPrivacySensitive = true)
Parameter NameTypeDescription
isPrivacySensitiveBooleanIf true, PrivacySensitive is enabled; if false, it is disabled

🚧

Follow the guideline for testing the sleep tracking

To accurately test Asleep's sleep tracking/analysis, 
please follow the test environment guide. Please note that sleep analysis results obtained 
in environments not adhering to this guide may not accurately reflect actual sleep patterns.

🔗 Check Test Environment Guideline

Sleep Analysis

Asleep.SleepTrackingManager.requestAnalysis()

  • Received the sleep data measured to date.
fun requestAnalysis(analysisListener: SleepTrackingManager.AnalysisListener)
Parameter NameTypeDescription
analysisListenerAnalysisListenersleep analysis listener

Asleep.SleepTrackingManager.AnalysisListener

interface AnalysisListener {
    fun onSuccess(session: Session)
    fun onFail(errorCode: Int, detail: String)
}
  • If success, onSuccess() is called.

Session data type

data class Session(
    val id: String?,
    val state: String?,
    val startTime: String?,
    val endTime: String?,
    val sleepStages: List<Int?>?,
    val snoringStages: List<Int?>?
)
Parameter NameTypeDescription
idString?Sleep session id
stateString?Sleep session state (OPEN, CLOSED or COMPLETE)
startTimeString?Session start time
endTimeString?Session end date
sleepStagesList<Int?>?Sleep stages
snoringStagesList<Int?>?Snoring
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode message

Stop sleep tracking

Asleep.SleepTrackingManager.stopSleepTracking

  • Stop Sleep Tracking.
fun stopSleepTracking()

Get sleep tracking status

Asleep.SleepTrackingManager.getTrackingStatus()

fun getTrackingStatus(): TrackingStatus

Asleep.SleepTrackingManager.TrackingStatus

class TrackingStatus (var sessionId: String? = null)
Property nameTypeDescription
sessionIdString?Currently tracking session id
Available from the onCreate function of TrackingListener
Valid until the corresponding Session is closed

Create Reports

  • Asleep.createReports :Generate Reports to get results for sleep tracking.
fun createReports(asleepConfig: AsleepConfig?): Reports?
Parameter NameTypeDescription
asleepConfigAsleepConfig?Enter the set value received by the callback in the initasleepconfig call

Get Single Report

  • Asleep.Reports.getReport :Bring sessionId Report.
fun getReport(sessionId: String, reportListener: ReportListener)
Parameter NameTypeDescription
sessionIdStringWhen Sleep Tracking stops, sessionId value
reportListenerReportListenerReport Callback listener
  • Asleep.Reports.ReportListener
interface ReportListener {
    fun onSuccess(report: Report?)
    fun onFail(errorCode: Int, detail: String)
}
  • If success, onSuccess() is called.
data class Report(
    val timezone: String,
    val peculiarities: List<String>,
    val missingDataRatio: Float,
    val session: Session?,
    val stat: Stat?
)

data class Session(
    val id: String,  
    val state: String,
    val startTime: String,
    val endTime: String?,
    val sleepStages: List<Int>?,  
    val createdTimezone: String,
    val unexpectedEndTime: String?
)

data class Stat(
    val sleepEfficiency: Float?,
    val sleepLatency: Int?,
    val sleepTime: String?,
    val wakeupLatency: Int?,
    val wakeTime: String?,
    val timeInWake: Int?,
    val timeInSleepPeriod: Int?,
    val timeInSleep: Int?,  
    val timeInBed: Int?,
    val timeInRem: Int?,  
    val timeInLight: Int?,  
    val timeInDeep: Int?,
    val wakeRatio: Float?,  
    val sleepRatio: Float?,
    val remRatio: Float?,    
    val lightRatio: Float?,  
    val deepRatio: Float?,
    val sleepCycle: Int?,
    val sleepCycleCount: Int?,
    val wasoCount: Int?,
    val longestWaso: Int?,
    val lightLatency: Int?,
    val remLatency: Int?,
    val deepLatency: Int?
    val sleepIndex: Int?,
    val timeInSnoring: Int?,
    val timeInNoSnoring: Int?,
    val snoringRatio: Float?,
    val noSnoringRatio: Float?,
    val snoringCount: Int?,
    val sleepCycleTime: List<String>?
)
Parameter NameTypeDescriptionVersion
timezoneStringTimezone (Timezone List)
peculiaritiesListA field for describing any specific details or peculiarities of the sleep session. This field can include multiple labels below.

IN_PROGRESS: If the session is OPEN, CLOSED
NEVER_SLEPT: If it is determined that there was no sleep at all during the session measurement time
TOO_SHORT_FOR_ANALYSIS: When the measurement time is too short to conduct a valid analysis (currently less than 5 minutes)
TOO_LONG_FOR_ANALYSIS: Analysis has been conducted successfully, but the session measurement time is excessively long, making it difficult to trust (currently exceeding 24 hours)
TOO_MANY_DEFECTS_IN_SLEEP_STAGES: When the error rate is high due to factors like missing audio uploads, resulting in insufficient sleep analysis results.
NO_BREATHING_STABILITY: When the customer's contract conditions do not support breathing stability analysis.
NO_REALTIME_POLLING: When, according to the customer's contract, real-time access to sleep information is not available.
missingDataRatioFloatThe error rate in sleep analysis results due to reasons such as missing audio uploads
sessionSession?Session analysis information
statStat?Analysis statistical information
idStringSession Id
stateStringStatus of Session
OPEN: An in-progress session, with audio uploads available
CLOSED: The session terminated by sending an end session request. Unable to upload audio files. Analysis of uploaded sleep audio is still in progress
'COMPLETE: All sleep analysis completed after the end of the session
startTimeStringSession start time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
endTimeString?Session end time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
sleepStagesList<Int>?Sleep Stages List
createdTimezoneStringTimezone of session creation (Timezone List)
unexpectedEndTimeString?Abnormal session termination time. This assign the next initAsleepConfig time.
sleepEfficiencyFloat?The percentage of time you actually slept during sleep measurement
sleepLatencyInt?time it took to fall asleep
sleepTimeString?The time it takes to fall asleep after the start of sleep staging
wakeupLatencyInt?The time it takes to wake up and end your sleep measurement
wakeTimeString?wake up time
timeInWakeInt?wake during sleep
timeInSleepPeriodInt?During sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
(time_in_bed - sleep_latency - wakeup_latency)
timeInSleepInt?During sleep measurement time, the time you were actually sleeping
This time is divided into three stages: deep, light, and rem
timeInBedInt?The time from the start of the sleep measurement to the end of the sleep measurement
timeInRemInt?Total time the sleep phase progressed to rem
timeInLightInt?Total time the sleep phase progressed to light
timeInDeepInt?Total time the sleep phase progressed to deep
wakeRatioFloat?Rate of waking time in the middle during sleep stage
sleepRatioFloat?During sleep stage, sleep ratio, not wake
remRatioFloat?Rate of rem sleep during sleep stage
lightRatioFloat?Rate of light sleep during sleep stage
deepRatioFloat?Rate of deep sleep during sleep stage
sleepCycleInt?The average duration of one sleep cycle.
sleepCycleCountInt?The number of sleep cycles.
wasoCountInt?The number of times 'wake' occurred during the sleep period
longestWasoInt?The duration of the longest 'wake' during the sleep period
lightLatencyInt?The time it takes to the first Light after the start of sleep.
remLatencyInt?The time it takes to the first REM after the start of sleep.
deepLatencyInt?The time it takes to the first Deep after the start of sleep.
sleepIndexInt?The metric that comprehensively represents sleep quality, defined by learning from the distribution of sleep data
timeInSnoringInt?Total time in the snoring
timeInNoSnoringInt?Total time in the no snoring
snoringRatioFloat?Percentage of time spent snoring during sleep stages
noSnoringRatioFloat?Percentage of time spent not snoring during sleep stages
snoringCountInt?Number of occurrences of snoring episodes
sleepCycleTimeList?Sleep cycle transition timestamps.
Example: [First sleep cycle start time, First sleep cycle end time, Second sleep cycle end time, …, Last sleep cycle end time]
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode Message

Get Multiple Reports

  • Asleep.Reports.getReports :Gets a list of Report that are within the range of the date you entered.
fun getReports(
    fromDate: String, 
  	toDate: String, 
  	orderBy: String = "DESC", 
  	offset: Int = 0, 
  	limit: Int = 20, 
  	reportsListener: ReportsListener?)
    
Parameter NameTypeDescription
fromDateString (YYYY-MM-DD)View start date
toDateString (YYYY-MM-DD)View last date
orderBy = "DESC"StringDESC: descending order, ASC: ascending order
offset = 0Intnumber of skipped Report
limit = 20Intmax number of Report (0~100)
reportsListenerReportsListener?Report list callback listener
  • Asleep.Reports.ReportsListener
interface ReportsListener {
    fun onSuccess(reports: List<SleepSession>?)
    fun onFail(errorCode: Int, detail: String)
}
  • If success, onSuccess() is called.
data class SleepSession(
    val sessionId: String?,
    val lastReceivedSeqNum: Int?,
    val sessionEndTime: String?,  
    val sessionStartTime: String?,
    val state: String?,
    val timeInBed: Int?,
    val createdTimezone: String,
    val unexpectedEndTime: String?
)
Parameter NameTypeDescriptionVersion
sessionIdString?Sleep session ID
lastReceivedSeqNumInt?The sequence number of the last uploaded audio file
sessionEndTimeString?Session end time
sessionStartTimeString?Session start time
stateString?Sleep session state (OPEN, CLOSED or COMPLETE)
timeInBedInt?The time from the start of the sleep measurement to the end of the sleep measurement
createdTimezoneStringTimezone of session creation (Timezone List)
unexpectedEndTimeString?Abnormal session termination time. This assign the next initAsleepConfig time.
  • When getReport() is called with a sessionId, it acquires a comprehensive report.
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode Message

Average-stats

  • Asleep.Reports.getAverageReport
  • You can check the average sleep metrics for a specific period of time.
fun getAverageReport(fromDate: String, toDate: String, averageReportListener: AverageReportListener?)
Parameter NameTypeDescription
fromDateStringThe starting time for the period you want to check the average
toDateStringThe ending time for the period you want to check the average
averageReportListenerAverageReportListenerAverage Report callback listener
  • Asleep.Reports.AverageReportListener
interface AverageReportListener {
    fun onSuccess(averageReport: AverageReport?)
    fun onFail(errorCode: Int, detail: String)
}
  • If success, onSuccess() is called.

AverageReport

data class AverageReport (
    val period: Period,
    val peculiarities: List<String>,
    val averageStats: AverageStats?,
    val neverSleptSessions: List<NeverSleptSessions>,
    val sleptSessions: List<SleptSessions>
)
Parameter NameTypeDescription
periodPeriodTimezone
peculiaritiesListSpecial considerations when calculating the average of sleep sessions
averageStatsAverageStats?An object containing the averages of sleep metrics for "sleptSessions"
neverSleptSessionsListA list of sessions during which it is determined that no sleep occurred at all during the measurement time.
sleptSessionsListA list of sessions during which it is determined that sleep occurred during the measurement time.

Period

data class Period (
    val timezone: String,
    val endDate: String,
    val startDate: String,
)
Parameter NameTypeDescription
timezoneStringrequested timezone
Ex. UTC, Asia/Seoul
startDateStringrequested start date
endDateStringrequested end date

AverageStats

data class AverageStats(
    val startTime: String,
    val endTime: String,
    val sleepTime: String,
    val wakeTime: String,
    val sleepLatency: Int,
    val wakeupLatency: Int,
    val timeInBed: Int,
    val timeInSleepPeriod: Int,
    val timeInSleep: Int,
    val timeInWake: Int,
    val timeInLight: Int?,
    val timeInDeep: Int?,
    val timeInRem: Int?,
    val sleepEfficiency: Float,
    val wakeRatio: Float,
    val sleepRatio: Float,
    val lightRatio: Float?,
    val deepRatio: Float?,
    val remRatio: Float?,
    val wasoCount: Int?,
    val longestWaso: Int?,
    val sleepCycleCount: Int?,
    val timeInSnoring: Int?,
    val timeInNoSnoring: Int?,
    val snoringRatio: Float?,
    val noSnoringRatio: Float?,
    val snoringCount: Int?
)
Parameter NameTypeDescriptionVersion
startTimeStringSession start time
endTimeStringSession end time
sleepTimeStringThe time it takes to fall asleep after the start of sleep staging
wakeTimeStringWake time
sleepLatencyIntTime to fall asleep
wakeupLatencyIntThe time it takes to wake up and end your sleep measurement
timeInBedIntThe time from the start of the sleep measurement to the end of the sleep measurement
timeInSleepPeriodIntDuring sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
(time_in_bed - sleep_latency - wakeup_latency)
timeInSleepIntDuring sleep measurement time, the time you were actually sleeping
This time is divided into three stages: deep,light,and rem
timeInWakeIntWake time during sleep
timeInLightInt?Total time the sleep phase progressed to light
timeInDeepInt?Total time the sleep phase progressed to deep
timeInRemInt?Total time the sleep phase progressed to rem
sleepEfficiencyFloat?The percentage of time you actually slept during sleep measurement
wakeRatioFloat?Rate of waking time in the middle during sleep phase
sleepRatioFloat?During sleep stage, sleep ratio, not wake
lightRatioFloat?Rate of light sleep during sleep phase
deepRatioFloat?Rate of deep sleep during sleep phase
remRatioFloat?rem sleep ratio
wasoCountInt?The number of times 'wake' occurred during the sleep period
longestWasoInt?The duration of the longest 'wake' during the sleep period
sleepCycleCountInt?The number of sleep cycles.
timeInSnoringInt?Total time in the snoring
timeInNoSnoringInt?Total time in the no snoring
snoringRatioFloat?Percentage of time spent snoring during sleep stages
noSnoringRatioFloat?Percentage of time spent not snoring during sleep stages
snoringCountInt?Number of occurrences of snoring episodes

NeverSleptSessions

data class NeverSleptSessions (
    val id: String,
    val startTime: String,
    val endTime: String,
    val completedTime: String
)
Parameter NameTypeDescription
idStringsession id
startTimeStringSession start time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
endTimeStringSession end time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
completedTimeStringTime of session analysis completion
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)

SleptSessions

data class SleptSessions (
    val id: String,
    val createdTimezone: String,
    val startTime: String,
    val endTime: String,
    val completedTime: String,
    val sleepEfficiency: Float,
    val sleepLatency: Int?,
    val sleepTime: String?,
    val wakeupLatency: Int?,
    val wakeTime: String?,
    val lightLatency: Int?,
    val deepLatency: Int?,
    val remLatency: Int?,
    val timeInWake: Int,
    val timeInSleepPeriod: Int,
    val timeInSleep: Int,
    val timeInBed: Int,
    val timeInRem: Int?,
    val timeInLight: Int?,
    val timeInDeep: Int?,
    val wakeRatio: Float,
    val sleepRatio: Float,
    val remRatio: Float?,
    val lightRatio: Float?,
    val deepRatio: Float?,
    val sleepCycle: Int?,
    val sleepCycleCount: Int?,
    val wasoCount: Int?,
    val longestWaso: Int?,
    val timeInSnoring: Int?,
    val timeInNoSnoring: Int?,
    val snoringRatio: Float?,
    val noSnoringRatio: Float?,
    val snoringCount: Int?,
)
Parameter nameTypeDescriptionVersion
idStringsession id
createdTimezoneStringTimezone of session creation (Timezone List)
startTimeStringSession start time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
endTimeStringSession end time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
completedTimeStringTime of session analysis completion
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
sleepEfficiencyFloatThe percentage of time you actually slept during sleep measurement
sleepLatencyInt?Time to fall asleep
sleepTimeString?The time it takes to fall asleep after the start of sleep staging
wakeupLatencyInt?The time it takes to wake up and end your sleep measurement
wakeTimeString?Wake time
lightLatencyInt?The time it takes to the first Light after the start of sleep
deepLatencyInt?The time it takes to the first Deep after the start of sleep
remLatencyInt?The time it takes to the first REM after the start of sleep
timeInWakeIntWake time during sleep
timeInSleepPeriodIntDuring sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
(time_in_bed - sleep_latency - wakeup_latency)
timeInSleepIntDuring sleep measurement time, the time you were actually sleeping
This time is divided into three stages: deep,light,and rem
timeInBedIntThe time from the start of the sleep measurement to the end of the sleep measurement
timeInRemInt?Total time the sleep phase progressed to rem
timeInLightInt?Total time the sleep phase progressed to light
timeInDeepInt?Total time the sleep phase progressed to deep
wakeRatioFloatRate of waking time in the middle during sleep phase
sleepRatioFloatDuring sleep stage, sleep ratio, not wake
remRatioFloat?rem sleep ratio
lightRatioFloat?Rate of light sleep during sleep phase
deepRatioFloat?Rate of deep sleep during sleep phase
sleepCycleInt?The average duration of one sleep cycle
sleepCycleCountInt?The number of sleep cycles
wasoCountInt?The number of times 'wake' occurred during the sleep period
longestWasoInt?The duration of the longest 'wake' during the sleep period
timeInSnoringInt?Total time in the snoring
timeInNoSnoringInt?Total time in the no snoring
snoringRatioFloat?Percentage of time spent snoring during sleep stages
noSnoringRatioFloat?Percentage of time spent not snoring during sleep stages
snoringCountInt?Number of occurrences of snoring episodes
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode Message

Delete Report

❗️

When session data is deleted from the Asleep server upon a request, it becomes difficult to provide specific evidence for the deleted sessions during subsequent billing usage analysis.

  • Asleep.deleteReport :Delete sessionId Report.
fun deleteReport(sessionId: String, deleteReportListener: DeleteReportListener)
Parameter NameTypeDescription
sessionIdStringDelete sessionId value
deleteReportListenerDeleteReportListenerReport delete callback listener
  • Asleep.Reports.DeleteReportListener
interface DeleteReportListener {
    fun onSuccess(sessionId: String?)
    fun onFail(errorCode: Int, detail: String)
}
  • If success, onSuccess() is called.
Parameter NameTypeDescription
sessionIdString?delete sessionId value
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode Message

Asleep.AsleepErrorCode

  • version>SDK: Usable before a specific SDK version, version<=SDK: Usable from a specific SDK version or higher
  • SDK Error Codes for Audio Input by Android OS Version
    • For Android OS versions 9 and below: If more than one app using the audio input feature is running, only the first app launched will receive audio input correctly. Subsequent apps will encounter an internal error at the point of audio input setup, and the SDK will deliver an ‘ERR_AUDIO’ error code.
    • For Android OS versions 10 and above: If more than one app using the audio input feature is running, the last app launched will receive audio input correctly. The previously launched apps will receive a ‘zero’ value in a ‘SILENCED’ state. The SDK will deliver an ‘ERR_AUDIO_SILENCED’ error code when it receives a ‘zero’ sound source. When it starts receiving the sound source correctly again, it will deliver an ‘ERR_AUDIO_UNSILENCED’ error code.
ErrorCodeDescriptionHandlingVersion
ERR_SETUP_INCOMPLETE10000Setup process is not completed.SDK Stop3.1.0
ERR_UNABLE_ODA10001ODA is unavailable.SDK Stop3.1.0
ERR_UNKNOWN11000UnknownSDK Stop
ERR_UNINITIALIZED11001Uninitialized SDKSDK Stop
ERR_MIC_PERMISSION11002No mic permissionClient Handling
ERR_AUDIO11003Android Audio ErrorSDK Stop
ERR_INVALID_URL11004Invalid URL FormatSDK Stop
ERR_AUDIO_SILENCED11005Recording Audio SilencedSDK Handling
ERR_AUDIO_UNSILENCED11006Recording Audio UnsilencedSDK Handling
ERR_COMMON_UNAUTHORIZED11401UnauthorizedSDK Stop
ERR_COMMON_EXPIRED11403Plan is expired | Rate limit exceeded | Quota exceededSDK Stop
ERR_COMMON_NOT_FOUND11404user not existSDK Stop
ERR_NETWORK11500HTTP 500 error | Network errorSDK Stop
ERR_INIT_FAILED21000Failed to initAsleepConfig | Network error occurred.Client Handling
ERR_INIT_SERVER_ERROR21500internal server errorClient Handling
ERR_CREATE_FAILED22000Failed to create a session | Network error occurred.Client Handling
ERR_CREATE_CONFLICT22409The previous sleep session is not closed yet.SDK Stop
ERR_CREATE_SERVER_ERROR22500internal server errorSDK Stop
ERR_UPLOAD_FAILED23000Failed to upload | Network error occurred.SDK Handling
ERR_UPLOAD_UNAUTHORIZED23401invalid customer uuid | user_agent is emptySDK Handling
ERR_UPLOAD_FORBIDDEN23403The session is already closed.SDK Stop
ERR_UPLOAD_NOT_FOUND23404The session does not exist.SDK Stop
ERR_UPLOAD_BAD_REQUEST23400Invalid callback_url
or
audio format should be <sleep_session.sleep_sound_length> sec (16khz, 44.1khz, 48khz) (mp3, wav) under 10MB
or
cannot upload MELSPECTROGRAM file. only upload AUDIO file.
SDK Handling
ERR_UPLOAD_TOO_LARGE23413HTTP content length exceeded {size} bytes.SDK Handling
ERR_UPLOAD_UNPROCESSABLE23422Invalid parameter | Invalid seq_num (seq_num starts from 0)SDK Handling
ERR_UPLOAD_SERVER_ERROR23500internal server errorSDK Handling
ERR_CLOSE_FAILED24000Failed to close a session | Network error occurred.Client Handling
ERR_CLOSE_UNAUTHORIZED24401Unauthorized | invalid customer uuidSDK Stop
ERR_CLOSE_FORBIDDEN24403The session is already closed.SDK Stop
ERR_CLOSE_BAD_REQUEST24400[WARNING] Invalid session end time. format(YYYY-MM-DDTHH:mm:ssz), must be less than session_start_timeSDK Stop
ERR_CLOSE_NOT_FOUND24404The session does not exist.SDK Stop
ERR_CLOSE_SERVER_ERROR24500internal server errorClient Handling
ERR_DELETE_FAILED25000Failed to delete a session | Network error occurred.Client Handling
ERR_DELETE_UNAUTHORIZED25401Invalid customer uuidClient Handling
ERR_DELETE_SERVER_ERROR25500internal server errorClient Handling
ERR_DELETE_USER_FAILED26000Failed to delete a customer uuid | Network error occurred.Client Handling
ERR_DELETE_USER_UNAUTHORIZED26401Invalid customer uuidClient Handling
ERR_DELETE_USER_SERVER_ERROR26500internal server errorClient Handling
ERR_ANALYSE_FAILED31000Failed to analyse | Network error occurred.Client Handling
ERR_ANALYSE_UNAUTHORIZED31401UnauthorizedClient Handling
ERR_ANALYSE_NOT_FOUND31404Unable to find the sleep session of id {session_id}Client Handling
ERR_ANALYSE_SERVER_ERROR31500internal server errorClient Handling
ERR_REPORT_FAILED32000Failed to report | Network error occurred.Client Handling
ERR_REPORT_UNAUTHORIZED32401UnauthorizedClient Handling
ERR_REPORT_NOT_FOUND32404Unable to find the sleep session of id {session_id}Client Handling
ERR_REPORT_SERVER_ERROR32500internal server errorClient Handling
ERR_REPORTS_FAILED33000Failed to reports | Network error occurred.Client Handling
ERR_REPORTS_UNAUTHORIZED33401The API key is not provided.Client Handling
ERR_REPORTS_SERVER_ERROR33500internal server errorClient Handling
ERR_AVERAGE_REPORT_FAILED34000Failed to average report | Network error occurred.Client Handling
ERR_AVERAGE_REPORT_BAD_REQUEST34400The period should be less than or equal to 100 daysClient Handling
ERR_AVERAGE_REPORT_NOT_FOUND34404Unable to find the user of id {user_id}Client Handling
ERR_AVERAGE_REPORT_SERVER_ERROR34500internal server errorClient Handling

Definition for SDK Error Handling

Definition of SDK Segment Operation

  • Init (initAsleepConfig) : SDK Initialization State
  • Tracking (SleepTrackingManager): Audio recording environment and server communication protocol management for sleep monitoring
  • Report (Reports): Request sleep monitoring results

Error Case Definition

  • SDK Stop: Termination process within the SDK. The SDK needs to be restarted for a new start because it is terminated internally. Depending on the status of the SDK, the session and audio recording function are terminated by itself. You need to start from the "initAsleepConfig" request to activate the SDK
  • SDK Handling: The SDK updates the error internally and performs the next action. If you want to terminate after receiving an error, you need to handle it depending on the state of the SDK call. To terminate the SDK, you need to call stopTracking only in the Tracking state, and no separate processing is required in other sections
  • Client Handling: An error that needs to be handled by the client. Used for error checking during development.
  • Do not used: Error not in use in the current version.

Error Handling Classification

  • Indicate commonly occurring Error Codes in red. Error codes that are unlikely to appear should be struck through.

  • Added Error Code for Audio
  • ERR_AUDIO(11003): If the audio recording does not function properly due to an internal error at the setup stage, the ‘ERR_AUDIO’ error code is delivered.
  • ERR_AUDIO_SILENCED(11005): If the sound source being measured during audio recording is read as a ‘zero’ value, the ‘ERR_AUDIO_SILENCED’ error code is delivered.
  • ERR_AUDIO_UNSILENCED(11006): If the sound source being measured during audio recording recovers normally after the ‘ERR_AUDIO_SILENCED’ error code has been raised, the ‘ERR_AUDIO_UNSILENCED’ error code is delivered.

The versioning of each API is independent of the document version.

Requirements

All APIs require an API Key in the header when making a call. If you haven't issued an API Key, you can issue one in Generate API key.

FieldTypeDescription
x-api-keyStringAPI Key

Response Structure

All API responses follow the structure of the response object below.

FieldTypeDescription
detailStringMessage value according to the API call result.
resultObjectResult value according to the API call.
(Provided in case of a successful API call)

Common Error Responses

The following are common error responses that can occur when making API calls.

  1. 401 Unauthorized
  • API Key is missing or invalid
    {
      "detail": "Unauthorized"
    }
    
  1. 403 Plan is expired
  • Plan usage period has expired
    {
      "detail": "Plan is expired"
    }
    
  1. 403 Rate limit exceeded
  • API call count has exceeded the defined Rate limit
    {
      "detail": "Rate limit exceeded"
    }
    
  1. 403 Quota exceeded
  • API call count has exceeded the defined Quota
    {
      "detail": "Quota exceeded"
    }
    

Versioning

By default, the versions for APIs and Callbacks are managed separately. For example, GET v1/A and GETv2/B APIs can have different versions.

The versioning policy for APIs and Callbacks is as follows:

No version upgrade

  • Adding new columns to the response object

Version upgrade

  • Changing the column names in the response object
  • Changing the values of specific columns in the response object (data type, ENUM values, etc.)
  • Changing the structure of the response object
  • Adding new features that are not supported in previous versions

Generates an identifier (user id) for the user to record sleep, and one can use this identifier to continuously manage the user's sleep.
The identifier of the generated user can be stored and managed in the appropriate storage of the customer for continuous use.

Request

URL

POST https://api.asleep.ai/ai/v1/users

Header

ParameterTypeRequiredDescription
x-api-keyStringOAPI Key

Example

curl "https://api.asleep.ai/ai/v1/users" -XPOST \
  -H "x-api-key: <YOUR_API_KEY>"

Response

201 Created

  • new user has been successfully created

Body (result field)

FieldTypeDescription
user_idStringuser id
{
  "detail": "success",
  "result": {
    "user_id": "<USER_ID>"
  }
}

You can retrieve the information of an existing user using the user identifier.

Request

URL

GET https://api.asleep.ai/ai/v1/users/{user_id}

Header

FieldTypeRequiredDescription
x-api-keyStringOAPI Key

Path Parameter

FieldTypeRequiredDescription
user_idStringOuser id

Example

curl "https://api.asleep.ai/ai/v1/users/{user_id}" -XGET \
  -H "x-api-key: <YOUR_API_KEY>"

Response

200 OK

Body (result field)

FieldTypeDescription
user_idStringuser id
to_be_deletedBooleanwhether the user is marked for deletion
last_session_infoSession Object or nullinformation about the last session

Session Object

if state == OPEN: session_end_time is null

if state != COMPLETE: complete_end_time is null

FieldTypeDescription
session_idStringsession id
inference_typeStringformat of the audio data uploaded in the session
serviceStringname of the service specified when creating the session
start_timeString (YYYY-MM-DDThh:mm:ssZ)start time of the session
end_timeString (YYYY-MM-DDThh:mm:ssZ)?end time of the session
stateString (OPEN,CLOSED,COMPLETE)state of the session
complete_timeString (YYYY-MM-DDThh:mm:ssZ)?completion time of the final session analysis
if state != COMPLETE complete_tims is null
{
  "detail": "success",
  "result": {
    "user_id": "<USER_ID>",
    "to_be_deleted": false,
    "last_session_info": {
      "session_id": "20230630224117",
      "inference_type": "MELSPECTROGRAM",
      "service": "NOSERVICE",
      "start_time": "2023-06-30T22:41:17",
      "end_time": "2023-07-01T05:36:12",
      "state": "COMPLETE",
      "complete_time": "2023-07-01T05:41:12"
    }
  }
}

404 Not Found

  • user corresponding to x-user-id does not exist
{
  "detail": "user does not exist"
}

You can delete a user using the user identifier. All of the user's data will be deleted.

Request

URL

DELETE https://api.asleep.ai/ai/v1/users/{user_id}

Header

FieldTypeRequiredDescription
x-api-keyStringOAPI Key

Path Parameter

FieldTypeRequiredDescription
user_idStringOuser id

Example

curl "https://api.asleep.ai/ai/v1/users/{user_id}" -XDELETE \
  -H "x-api-key: <YOUR_API_KEY>"

Response

204 No Content

  • user information has been successfully deleted

401 Unauthorized

  • user_idis empty or in an invalid format
{
  "detail": "user_id is invalid"
}

404 Not Found

  • user corresponding to user_id does not exist
{
  "detail": "user does not exist"
}

You can refer this document when you want to delete data from a specific session. Session data, uploaded audio data, and analysis data will all be deleted. If the requested session data is deleted from the Asleep server, it will be difficult to provide specific evidence for the deleted session during future billing analysis.

Request

URL

DELETE https://api.asleep.ai/ai/v1/sessions/{session_id}

Header

FieldTypeRequiredDescription
x-api-keyStringOAPI Key
x-user-idStringOIssued user id

Path parameter

FieldTypeRequiredDescription
session_idStringOCreated session id

Example

curl "https://api.asleep.ai/ai/v1/sessions/{session_id}" -XDELETE \
  -H "x-api-key: <YOUR_API_KEY>" \
  -H "x-user-id: <USER_ID>"

Response

204 No Content

  • session corresponding to session_id has been successfully deleted

401 Unauthorized

  • x-user-id is empty or in an invalid format
{
  "detail": "x-user-id is invalid"
}

404 Not Found

  • user corresponding to x-user-id does not exist
{
  "detail": "user does not exist"
}
  • session corresponding to session_id does not exist
{
  "detail": "session does not exist"
}

Use this method when you want to delete all data of a specific user. This includes all sessions, uploaded audio data, and analysis data. Please note that if the requested session data is successfully deleted from the Asleep server, providing detailed evidence of the deleted sessions for future billing analysis may be difficult.

Request

URL

DELETE https://api.asleep.ai/ai/v1/sessions

Header

FieldTypeRequiredDescription
x-api-keyStringOAPI Key
x-user-idStringOIssued user id

Example

curl "https://api.asleep.ai/ai/v1/sessions" -XDELETE \
  -H "x-api-key: <YOUR_API_KEY>" \
  -H "x-user-id: <USER_ID>"

Response

204 No Content

  • all sessions of the user have been successfully deleted

401 Unauthorized

  • x-user-id is empty or in an invalid format
{
  "detail": "x-user-id is invalid"
}

404 Not Found

  • user corresponding to x-user-id does not exist
{
  "detail": "user does not exist"
}

Request sleep analysis data for a specific session.

Request

URL

GET https://api.asleep.ai/data/v3/sessions/{session_id}

Header

FieldTypeRequiredDefaultDescription
x-api-keyStringO-API Key
x-user-idStringO-Issued user id
timezoneStringXUTCChange the timezone of the analysis results to the corresponding timezone and return
UTC, Asia/Seoul

Path parameter

FieldTypeRequiredDescription
session_idStringOid of the session in which you want to request data

Example

curl "https://api.asleep.ai/data/v3/sessions/{session_id}" -XGET \
  -H "x-api-key: <YOUR_API_KEY>" \
  -H "x-user-id: <USER_ID>"

Response

200 OK

  • Session details lookup success
{
    "detail": "OK",
    "result": {
        "timezone": "UTC",
        "peculiarities": ["NO_BREATHING_STABILITY"],
        "missing_data_ratio": 0.0,
        "session": {
            "id": "20250115025029_fvivn",
            "state": "COMPLETE",
            "start_time": "2025-01-15T02:50:29+00:00",
            "end_time": "2025-01-15T03:50:29+00:00",
            "unexpected_end_time": null,
            "created_timezone": "UTC",
            "sleep_stages": [0], //omitted
            "breath_stages": null,
            "snoring_stages": [0] // omitted
        },
        "stat": {
            "sleep_time": "2025-01-15T03:05:29+00:00",
            "wake_time": "2025-01-15T03:26:29+00:00",
            "sleep_index": 50,
            "sleep_latency": 900,
            "wakeup_latency": 1440,
            "light_latency": 0,
            "deep_latency": null,
            "rem_latency": null,
            "time_in_bed": 3600,
            "time_in_sleep_period": 1260,
            "time_in_sleep": 1080,
            "time_in_wake": 180,
            "time_in_light": 1080,
            "time_in_deep": 0,
            "time_in_rem": 0,
            "time_in_stable_breath": null,
            "time_in_unstable_breath": null,
            "time_in_snoring": 0,
            "time_in_no_snoring": 1260,
            "sleep_efficiency": 0.3,
            "sleep_ratio": 0.86,
            "wake_ratio": 0.14,
            "light_ratio": 0.86,
            "deep_ratio": 0.0,
            "rem_ratio": 0.0,
            "stable_breath_ratio": null,
            "unstable_breath_ratio": null,
            "snoring_ratio": 0.0,
            "no_snoring_ratio": 1.0,
            "breathing_index": null,
            "breathing_pattern": null,
            "waso_count": 1,
            "longest_waso": 180,
            "sleep_cycle_count": 0,
            "sleep_cycle": null,
            "sleep_cycle_time": [],
            "unstable_breath_count": null,
            "snoring_count": 0
        }
    }
}

Body (result field)

The nullability of the stat object is determined based on the session status and contract conditions.

  • Invalid session:

    • if peculiarities == TOO_SHORT_FOR_ANALYSIS or TOO_MANY_DEFECTS_IN_SLEEP_STAGES
    • All other sessions where sleep analysis has been conducted are considered valid sessions.
  • stat object is null if:

    • peculiarities == IN_PROGRESS or NO_REALTIME_POLLING or TOO_SHORT_FOR_ANALYSIS or TOO_MANY_DEFECTS_IN_SLEEP_STAGES
FieldTypeDescription
timezoneStringTimezone (Timezone List)
peculiaritiesListA field for describing any specific details or peculiarities of the sleep session. This field can include multiple labels below.

IN_PROGRESS: If the session is OPEN, CLOSED
NEVER_SLEPT: If it is determined that there was no sleep at all during the session measurement time
TOO_SHORT_FOR_ANALYSIS: When the measurement time is too short to conduct a valid analysis (currently less than 5 minutes)
TOO_LONG_FOR_ANALYSIS: Analysis has been conducted successfully, but the session measurement time is excessively long, making it difficult to trust (currently exceeding 24 hours)
TOO_MANY_DEFECTS_IN_SLEEP_STAGES: When the error rate is high due to factors like missing audio uploads, resulting in insufficient sleep analysis results.
NO_BREATHING_STABILITY: When the customer's contract conditions do not support breathing stability analysis.
NO_REALTIME_POLLING: When, according to the customer's contract, real-time access to sleep information is not available.
missing_data_ratiofloat(0~1 range, decimal points)The error rate in sleep analysis results due to reasons such as missing audio uploads
sessionSession ObjectSession Report Information
statStat Object?Session Report Information

Session Object

  • if state == OPEN: session_end_time is null
FieldTypeDescription
idStringsession id
stateString (OPEN,CLOSED,COMPLETE)Status of Session
OPEN: An in-progress session, with audio uploads available
CLOSED: The session terminated by sending an end session request. Unable to upload audio files. Analysis of uploaded sleep audio is still in progress
COMPLETE: All sleep analysis completed after the end of the session
start_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)Session start time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
end_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)?Session end time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
unexpected_end_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)?If a session fails to proceed and terminate properly due to app crashes or similar issues, and the client later ends the session with an unexpected parameter set to 1, the time at which this happens is recorded. In this case, the "end_time" is calculated based on the sequence number of the last uploaded audio file. Therefore, if "end_time" is not null, it indicates an abnormal session.
created_timezoneStringTimezone of session creation (Timezone List)
sleep_stages[Sleep Stages]?Sleep Stages List
snoring_stages[Snoring Stages]?Snoring Stages List

Sleep Stages

sleep stage is-1,0,1,2,3 It is represented by an integer of one, and the number one represents the sleep stage of the 30-second interval. The meaning of each number is shown in the table below.

  • 0(wake), 1(sleep) if you use 2-stage analysis
numbersleep stage
-1error (invalid audio, analysis error, etc)
0wake
1light sleep
2deep sleep
3REM sleep

Snoring Stages

snoring stage is-1,0,1 It is represented by an integer of one, and the number one represents the snoring stage of the 30-second interval. The meaning of each number is shown in the table below.

numbersnoring stage
-1error (invalid audio, analysis error, etc)
0no snoring
1snoring

Stat Object

For each metric detail, please see Key Concepts

  • if state == COMPLETE
    • If you use 2-stage analysis: only presents wake and sleep information: time_in_rem, time_in_light, time_in_deep, rem_ratio, light_ratio, deep_ratio, light_latency, deep_latency, rem_latency is null
    • if peculiarities == NEVER_SLEPT: didn't sleep: sleep_latency, sleep_time, wakeup_latency, wake_time, wake_ratio, sleep_ratio, rem_ratio, light_ratio, deep_ratio, light_latency, deep_latency, rem_latency, sleep_cycle, longest_waso, sleep_index is null
  • Newly added metrics do not support data from previous sessions. You can check the time when metrics were added at https://docs.asleep.ai/changelog.
FieldTypeDescriptionExample
sleep_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)?The time it takes to fall asleep after the start of sleep staging2022-08-01T00:30:00+09:00
wake_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)?Wake time 2022-08-01T07:30:00+09:00
sleep_indexInt(50 <= sleep_index <= 100)?(Beta) Test Operation Sleep Data87
sleep_latencyInt (seconds)?Time to fall asleep1800
wakeup_latencyInt (seconds)?The time it takes to wake up and end your sleep measurement1800
light_latencyInt(seconds)?The time it takes to the first Light after the start of sleep.
deep_latencyInt(seconds)?The time it takes to the first Deep after the start of sleep.
rem_latencyInt(seconds)?The time it takes to the first REM after the start of sleep.
time_in_bedInt (seconds)The time from the start of the sleep measurement to the end of the sleep measurement28800
time_in_sleep_periodInt (seconds)During sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
(time_in_bed - sleep_latency - wakeup_latency)
27000
time_in_sleepInt (seconds)During sleep measurement time, the time you were actually sleeping
This time is divided into three stages: deep,light,and rem
24300
time_in_wakeInt (seconds)Wake time during sleep2700
time_in_lightInt (seconds)?Total time the sleep phase progressed to light5400
time_in_deepInt (seconds)?Total time the sleep phase progressed to deep5400
time_in_remInt (seconds)?Total time the sleep phase progressed to rem13500
time_in_snoringInt?Total time of snoring5400
time_in_no_snoringInt?Total time of no snoring23400
sleep_efficiencyfloat (0~1 range, decimal points)The percentage of time you actually slept during sleep measurement0.84
sleep_ratiofloat (0~1 range, decimal points)?During sleep stage, sleep ratio, not wake0.9
wake_ratiofloat (0~1 range, decimal points)?Rate of waking time in the middle during sleep phase0.1
light_ratiofloat (0~1 range, decimal points)?Rate of light sleep during sleep phase0.2
deep_ratiofloat (0~1 range, decimal points)?Rate of deep sleep during sleep phase0.2
rem_ratiofloat (0~1 range, decimal points)?rem sleep ratio0.5
snoring_ratiofloat (0~1 range, decimal points)?The percentage of time during the sleep phase that there was a snoring section0.3
no_snoring_ratiofloat (0~1 range, decimal points)?The percentage of time during the sleep phase that there was no snoring.0.7
waso_countInt?The number of times 'wake' occurred during the sleep period10
longest_wasoInt(seconds)?The duration of the longest 'wake' during the sleep period300
sleep_cycle_countInt?The number of sleep cycles.4
sleep_cycleInt(seconds)?The average duration of one sleep cycle.6600
sleep_cycle_timeList of String(YYYY-MM-DDThh:mm:ss+-hh:mm)Transition time for sleep cycles
[First sleep cycle onset time, first sleep cycle end time, second sleep cycle end time, ..., last sleep cycle end time]
["2023-09-05T16:15:00+00:00", "2023-09-05T18:03:00+00:00", "2023-09-05T20:32:30+00:00"]
snoring_countInt?The number of times snoring occurred.

400 Bad Request

  • timezone didn't come in correctly
{
	"detail": "The invalid timezone is provided"
}
  • x-user-id: invalid format
{
	"detail": "The format of x-user-id is invalid"
}
  • session_id: invalid format
{
	"detail": "The format of sleep session id 20230608020315_hz82 is not valid"
}

404 Not Found

  • session_idif the corresponding session is not found
{
	"detail": "Unable to find the sleep session of id {session_id}"
}

You can request a list of sleep sessions for a specific user.

Request

URL

GET https://api.asleep.ai/data/v1/sessions

Header

FieldTypeRequiredDefaultDescription
x-api-keyStringO-API Key
x-user-idStringO-Issued user id
timezoneStringXUTCReturn the analysis results in the timezone specified by the header. For example, UTC, Asia/Seoul

Query parameter

  • "date_gte, date_lte, order_by" are based on the session_start_time.
FieldTypeRequiredDefaultDescription
date_gteString (YYYY-MM-DD)X-Return sessions that are greater than or equal to date_gte based on the timezone in the header
date_lteString (YYYY-MM-DD)X-Return sessions that are less than or equal to date_lte based on the timezone in the header
order_byString (ASCor DESC)XDESCDESC: Sort in descending order
ASC: Sort in ascending order
offsetIntX0Number of sessions to skip
limitInt (Integer of 0~100)X20Number of sessions to receive
Max value is 100

Example

curl "https://api.asleep.ai/data/v1/sessions?date_gte=2022-01-01&offset=10&limit=10&order_by=ASC" -XGET \
  -H "x-api-key: <YOUR_API_KEY>" \
  -H "x-user-id: <USER_ID>"

Response

200 OK

  • Successful session list retrieval
{
    "detail": "OK",
    "result": {
        "timezone": "UTC",
        "sleep_session_list": [
            {
                "session_id": "20250114182518_eq85p",
                "state": "COMPLETE",
                "session_start_time": "2025-01-14T18:25:18+00:00",
                "session_end_time": "2025-01-14T22:55:55+00:00",
                "created_timezone": "Asia/Seoul",
                "unexpected_end_time": null,
                "last_received_seq_num": 540,
                "time_in_bed": 16237
            },
            {
                "session_id": "20250113172906_1zch9",
                "state": "COMPLETE",
                "session_start_time": "2025-01-13T17:29:06+00:00",
                "session_end_time": "2025-01-13T23:00:53+00:00",
                "created_timezone": "Asia/Seoul",
                "unexpected_end_time": null,
                "last_received_seq_num": 661,
                "time_in_bed": 19907
            },
            {
                "session_id": "20250112180001_8sqei",
                "state": "COMPLETE",
                "session_start_time": "2025-01-12T18:00:01+00:00",
                "session_end_time": "2025-01-12T23:03:11+00:00",
                "created_timezone": "Asia/Seoul",
                "unexpected_end_time": null,
                "last_received_seq_num": 605,
                "time_in_bed": 18190
            },
            {
                "session_id": "20250111180000_9sk5t",
                "state": "COMPLETE",
                "session_start_time": "2025-01-11T18:00:00+00:00",
                "session_end_time": "2025-01-11T23:05:08+00:00",
                "created_timezone": "Asia/Seoul",
                "unexpected_end_time": null,
                "last_received_seq_num": 609,
                "time_in_bed": 18308
            },
            {
                "session_id": "20250110180001_csktb",
                "state": "COMPLETE",
                "session_start_time": "2025-01-10T18:00:01+00:00",
                "session_end_time": "2025-01-10T23:05:08+00:00",
                "created_timezone": "Asia/Seoul",
                "unexpected_end_time": null,
                "last_received_seq_num": 609,
                "time_in_bed": 18307
            }
        ]
    }
}

Body (result field)

FieldTypeDescription
timezoneStringTimezone
sleep_session_listList of Sleep Session ObjectsList of session data

Sleep Session Object

if state == OPEN: session_end_time is null

FieldTypeDescription
session_idStringSession ID
stateString (OPEN,CLOSED,COMPLETE)Session state
OPEN: In-progress session, audio upload is possible
CLOSED: Session has been closed, audio file upload is not possible. Analysis of the uploaded sleep audio is ongoing
COMPLETE: Session has been closed and all sleep analysis is completed
session_start_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)Session start time
Example) 2022-08-01T01:31:17+09:00 (for Asia/Seoul timezone in the request)
session_end_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)?Session end time
Example) 2022-08-01T01:31:17+09:00 (for Asia/Seoul timezone in the request)
created_timezoneStringTimezone of session creation (Timezone List)
unexpected_end_timeString(YYYY-MM-DDThh:mm:ss+-hh:mm)?If a session fails to proceed and terminate properly due to app crashes or similar issues, and the client later ends the session with an unexpected parameter set to 1, the time at which this happens is recorded. In this case, the "end_time" is calculated based on the sequence number of the last uploaded audio file. Therefore, if "end_time" is not null, it indicates an abnormal session.
last_received_seq_numInt?Sequence number of the last uploaded audio file
time_in_bedInt (seconds)?Time spent in bed

400 Bad Request

  • Invalid timezone is provided
{
	"detail": "The invalid timezone is provided"
}

You can check the average sleep metrics for a specific period of time. Currently, you can retrieve data for up to 100 days.

Request

URL

GET https://api.asleep.ai/data/v1/users/{user_id}/average-stats

Header

FieldTypeRequiredDefaultDescription
x-api-keyStringO-API Key
timezoneStringXUTCChange the timezone of the analysis results to the corresponding timezone and return
UTC, Asia/Seoul

Path parameter

FieldTypeRequiredDescription
user_idStringOid of the session in which you want to request data

Query string

FieldTypeRequiredDefaultDescription
start_dateStringO-The starting time for the period you want to check the average
end_dateStringO-The ending time for the period you want to check the average

Example

curl "https://api.asleep.ai/data/v1/users/{user_id}/average-stats?start_date=2023-10-20&end_date=2023-10-30" -XGET \
  -H "x-api-key: <YOUR_API_KEY>"

Response

200 OK

  • Success
{
    "detail": "OK",
    "result": {
        "period": {
            "timezone": "UTC",
            "start_date": "2025-01-01",
            "end_date": "2025-01-05"
        },
        "peculiarities": ["NO_BREATHING_STABILITY"],
        "average_stats": {
            "start_time": "02:54:01",
            "end_time": "07:28:03",
            "sleep_time": "03:10:30",
            "wake_time": "07:17:44",
            "sleep_latency": 990,
            "wakeup_latency": 714,
            "time_in_bed": 16381,
            "time_in_sleep_period": 14658,
            "time_in_sleep": 14154,
            "time_in_wake": 504,
            "time_in_light": 6492,
            "time_in_deep": 3270,
            "time_in_rem": 4392,
            "time_in_stable_breath": null,
            "time_in_unstable_breath": null,
            "time_in_snoring": 53,
            "time_in_no_snoring": 18270,
            "sleep_efficiency": 0.864,
            "wake_ratio": 0.034,
            "sleep_ratio": 0.966,
            "light_ratio": 0.443,
            "deep_ratio": 0.223,
            "rem_ratio": 0.3,
            "stable_breath_ratio": null,
            "unstable_breath_ratio": null,
            "snoring_ratio": 0.004,
            "no_snoring_ratio": 0.996,
            "breathing_index": null,
            "waso_count": 7,
            "longest_waso": 228,
            "unstable_breath_count": null,
            "sleep_cycle_count": 3,
            "snoring_count": 2
        },
        "never_slept_sessions": [],
        "slept_sessions": [
            {
                "id": "20250101173000_biuw0",
                "created_timezone": "Asia/Seoul",
                "start_time": "2025-01-01T17:30:00+00:00",
                "end_time": "2025-01-01T22:37:23+00:00",
                "completed_time": "2025-01-01T22:37:25+00:00",
                "sleep_time": "2025-01-01T17:30:00+00:00",
                "wake_time": "2025-01-01T22:32:23+00:00",
                "sleep_latency": 0,
                "wakeup_latency": 300,
                "light_latency": 0,
                "deep_latency": 390,
                "rem_latency": 3840,
                "time_in_bed": 18443,
                "time_in_sleep_period": 18120,
                "time_in_sleep": 17910,
                "time_in_wake": 210,
                "time_in_light": 7020,
                "time_in_deep": 4410,
                "time_in_rem": 6480,
                "time_in_stable_breath": null,
                "time_in_unstable_breath": null,
                "time_in_snoring": 60,
                "time_in_no_snoring": 18060,
                "sleep_efficiency": 0.97,
                "sleep_ratio": 0.99,
                "wake_ratio": 0.01,
                "light_ratio": 0.39,
                "deep_ratio": 0.24,
                "rem_ratio": 0.36,
                "stable_breath_ratio": null,
                "unstable_breath_ratio": null,
                "snoring_ratio": 0.0,
                "no_snoring_ratio": 1.0,
                "breathing_pattern": null,
                "breathing_index": null,
                "waso_count": 7,
                "longest_waso": 30,
                "sleep_cycle_count": 4,
                "sleep_cycle": 4522,
                "unstable_breath_count": null,
                "snoring_count": 2
            },
            {
                "id": "20250102180002_1it7v",
                "created_timezone": "Asia/Seoul",
                "start_time": "2025-01-02T18:00:02+00:00",
                "end_time": "2025-01-02T23:05:06+00:00",
                "completed_time": "2025-01-02T23:05:07+00:00",
                "sleep_time": "2025-01-02T18:30:02+00:00",
                "wake_time": "2025-01-02T23:05:06+00:00",
                "sleep_latency": 1800,
                "wakeup_latency": 0,
                "light_latency": 0,
                "deep_latency": 510,
                "rem_latency": 3750,
                "time_in_bed": 18304,
                "time_in_sleep_period": 16500,
                "time_in_sleep": 15660,
                "time_in_wake": 840,
                "time_in_light": 8460,
                "time_in_deep": 3690,
                "time_in_rem": 3510,
                "time_in_stable_breath": null,
                "time_in_unstable_breath": null,
                "time_in_snoring": 30,
                "time_in_no_snoring": 16470,
                "sleep_efficiency": 0.86,
                "sleep_ratio": 0.95,
                "wake_ratio": 0.05,
                "light_ratio": 0.52,
                "deep_ratio": 0.22,
                "rem_ratio": 0.21,
                "stable_breath_ratio": null,
                "unstable_breath_ratio": null,
                "snoring_ratio": 0.0,
                "no_snoring_ratio": 1.0,
                "breathing_pattern": null,
                "breathing_index": null,
                "waso_count": 10,
                "longest_waso": 240,
                "sleep_cycle_count": 3,
                "sleep_cycle": 5490,
                "unstable_breath_count": null,
                "snoring_count": 1
            },
            {
                "id": "20250103180002_91khj",
                "created_timezone": "Asia/Seoul",
                "start_time": "2025-01-03T18:00:02+00:00",
                "end_time": "2025-01-03T23:05:14+00:00",
                "completed_time": "2025-01-03T23:05:15+00:00",
                "sleep_time": "2025-01-03T18:00:02+00:00",
                "wake_time": "2025-01-03T23:05:14+00:00",
                "sleep_latency": 0,
                "wakeup_latency": 0,
                "light_latency": 0,
                "deep_latency": 390,
                "rem_latency": 3360,
                "time_in_bed": 18312,
                "time_in_sleep_period": 18300,
                "time_in_sleep": 17220,
                "time_in_wake": 1080,
                "time_in_light": 8910,
                "time_in_deep": 3150,
                "time_in_rem": 5160,
                "time_in_stable_breath": null,
                "time_in_unstable_breath": null,
                "time_in_snoring": 0,
                "time_in_no_snoring": 18300,
                "sleep_efficiency": 0.94,
                "sleep_ratio": 0.94,
                "wake_ratio": 0.06,
                "light_ratio": 0.49,
                "deep_ratio": 0.17,
                "rem_ratio": 0.28,
                "stable_breath_ratio": null,
                "unstable_breath_ratio": null,
                "snoring_ratio": 0.0,
                "no_snoring_ratio": 1.0,
                "breathing_pattern": null,
                "breathing_index": null,
                "waso_count": 8,
                "longest_waso": 720,
                "sleep_cycle_count": 3,
                "sleep_cycle": 5940,
                "unstable_breath_count": null,
                "snoring_count": 0
            },
            {
                "id": "20250104180001_z8tn9",
                "created_timezone": "Asia/Seoul",
                "start_time": "2025-01-04T18:00:01+00:00",
                "end_time": "2025-01-04T20:27:03+00:00",
                "completed_time": "2025-01-04T20:27:05+00:00",
                "sleep_time": "2025-01-04T18:00:01+00:00",
                "wake_time": "2025-01-04T19:32:33+00:00",
                "sleep_latency": 0,
                "wakeup_latency": 3270,
                "light_latency": 0,
                "deep_latency": 690,
                "rem_latency": 3630,
                "time_in_bed": 8822,
                "time_in_sleep_period": 5520,
                "time_in_sleep": 5370,
                "time_in_wake": 150,
                "time_in_light": 2100,
                "time_in_deep": 1680,
                "time_in_rem": 1590,
                "time_in_stable_breath": null,
                "time_in_unstable_breath": null,
                "time_in_snoring": 30,
                "time_in_no_snoring": 5490,
                "sleep_efficiency": 0.61,
                "sleep_ratio": 0.97,
                "wake_ratio": 0.03,
                "light_ratio": 0.38,
                "deep_ratio": 0.3,
                "rem_ratio": 0.29,
                "stable_breath_ratio": null,
                "unstable_breath_ratio": null,
                "snoring_ratio": 0.01,
                "no_snoring_ratio": 0.99,
                "breathing_pattern": null,
                "breathing_index": null,
                "waso_count": 3,
                "longest_waso": 60,
                "sleep_cycle_count": 1,
                "sleep_cycle": 5190,
                "unstable_breath_count": null,
                "snoring_count": 1
            },
            {
                "id": "20250105180002_s3dh3",
                "created_timezone": "Asia/Seoul",
                "start_time": "2025-01-05T18:00:02+00:00",
                "end_time": "2025-01-05T23:00:26+00:00",
                "completed_time": "2025-01-05T23:00:27+00:00",
                "sleep_time": "2025-01-05T18:52:32+00:00",
                "wake_time": "2025-01-05T23:00:26+00:00",
                "sleep_latency": 3150,
                "wakeup_latency": 0,
                "light_latency": 0,
                "deep_latency": 450,
                "rem_latency": 3750,
                "time_in_bed": 18024,
                "time_in_sleep_period": 14850,
                "time_in_sleep": 14610,
                "time_in_wake": 240,
                "time_in_light": 5970,
                "time_in_deep": 3420,
                "time_in_rem": 5220,
                "time_in_stable_breath": null,
                "time_in_unstable_breath": null,
                "time_in_snoring": 90,
                "time_in_no_snoring": 14760,
                "sleep_efficiency": 0.81,
                "sleep_ratio": 0.98,
                "wake_ratio": 0.02,
                "light_ratio": 0.4,
                "deep_ratio": 0.23,
                "rem_ratio": 0.35,
                "stable_breath_ratio": null,
                "unstable_breath_ratio": null,
                "snoring_ratio": 0.01,
                "no_snoring_ratio": 0.99,
                "breathing_pattern": null,
                "breathing_index": null,
                "waso_count": 6,
                "longest_waso": 90,
                "sleep_cycle_count": 2,
                "sleep_cycle": 7155,
                "unstable_breath_count": null,
                "snoring_count": 3
            }
        ]
    }
}

Body (result field)

FieldTypeDescription
periodPeriod ObjectTimezone (Timezone List)
peculiaritiesListSpecial considerations when calculating the average of sleep sessions

NO_BREATHING_STABILITY: Analysis for breathing_stability is no longer provided in B2B services. As of V3, this peculiarities value exists in all sessions and is planned for removal in future updates.
average_statsAverage Stats Object?An object containing the averages of sleep metrics for "slept_sessions"
never_slept_sessionsList of Never Slept Session ObjectA list of sessions during which it is determined that no sleep occurred at all during the measurement time.
slept_sessionsList of Slept Session ObjectA list of sessions during which it is determined that sleep occurred during the measurement time.

Period Object

FieldTypeDescription
timezoneStringrequested timezone
예. UTC, Asia/Seoul
start_dateString(YYYY-MM-DD)requested start date
end_dateString (YYYY-MM-DD)requested end date

Average Stats Object

FieldTypeDescription
start_timeString(hh:mm:ss)Session start time
end_timeString(hh:mm:ss)Session end time
sleep_timeString (hh:mm:ss)The time it takes to fall asleep after the start of sleep staging
wake_timeString (hh:mm:ss)Wake time
sleep_latencyIntTime to fall asleep
wakeup_latencyIntThe time it takes to wake up and end your sleep measurement
time_in_bedIntThe time from the start of the sleep measurement to the end of the sleep measurement
time_in_sleep_periodIntDuring sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
(time_in_bed - sleep_latency - wakeup_latency)
time_in_sleepIntDuring sleep measurement time, the time you were actually sleeping
This time is divided into three stages: deep,light,and rem
time_in_wakeIntWake time during sleep
time_in_lightInt?Total time the sleep phase progressed to light
time_in_deepInt?Total time the sleep phase progressed to deep
time_in_remInt?Total time the sleep phase progressed to rem
time_in_snoringInt?Total time of snoring
time_in_no_snoringInt?Total time of no snoring
sleep_efficiencyfloat(0~1 range, decimal points)The percentage of time you actually slept during sleep measurement
wake_ratiofloat(0~1 range, decimal points)Rate of waking time in the middle during sleep phase
sleep_ratiofloat(0~1 range, decimal points)During sleep stage, sleep ratio, not wake
light_ratiofloat(0~1 range, decimal points)?Rate of light sleep during sleep phase
deep_ratiofloat(0~1 range, decimal points)?Rate of deep sleep during sleep phase
rem_ratiofloat(0~1 range, decimal points)?rem sleep ratio
snoring_ratiofloat(0~1 range, decimal points)?The percentage of time during the sleep phase that there was a snoring section
no_snoring_ratiofloat(0~1 range, decimal points)?The percentage of time during the sleep phase that there was no snoring.
waso_countInt?The number of times 'wake' occurred during the sleep period
longest_wasoInt?The duration of the longest 'wake' during the sleep period
sleep_cycle_countInt?The number of sleep cycles.
snoring_countInt?The number of times snoring occurred.

Never Slept Session Object

FieldTypeDescription
idStringsession id
start_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)Session start time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
end_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)Session end time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
completed_timeString(YYYY-MM-DDThh:mm:ss+-hh:mm)Time of session analysis completion
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)

Slept Session Object

FieldTypeDescription
idStringsession id
created_timezoneStringTimezone of session creation (Timezone List)
start_timeString(YYYY-MM-DDThh:mm:ss+-hh:mm)Session start time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
end_timeString(YYYY-MM-DDThh:mm:ss+-hh:mm)Session end time
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
completed_timeString(YYYY-MM-DDThh:mm:ss+-hh:mm)Time of session analysis completion
Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul)
sleep_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)?The time it takes to fall asleep after the start of sleep staging
wake_timeString (YYYY-MM-DDThh:mm:ss+-hh:mm)?Wake time
sleep_latencyint (seconds)?Time to fall asleep
wakeup_latencyint (seconds)?The time it takes to wake up and end your sleep measurement
sleep_efficiencyfloat (0~1 range, decimal points)The percentage of time you actually slept during sleep measurement
light_latencyint(seconds)?The time it takes to the first Light after the start of sleep
deep_latencyint(seconds)?The time it takes to the first Deep after the start of sleep
rem_latencyint(seconds)?The time it takes to the first REM after the start of sleep
time_in_bedint (seconds)The time from the start of the sleep measurement to the end of the sleep measurement
time_in_sleep_periodint (seconds)During sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
(time_in_bed - sleep_latency - wakeup_latency)
time_in_sleepint (seconds)During sleep measurement time, the time you were actually sleeping
This time is divided into three stages: deep,light,and rem
time_in_wakeint (seconds)Wake time during sleep
time_in_remint (seconds)?Total time the sleep phase progressed to rem
time_in_lightint (seconds)?Total time the sleep phase progressed to light
time_in_deepint (seconds)?Total time the sleep phase progressed to deep
time_in_snoringint (seconds)?Total time of snoring
time_in_no_snoringint (seconds)?Total time of no snoring
wake_ratiofloat (0~1 range, decimal points)Rate of waking time in the middle during sleep phase
sleep_ratiofloat (0~1 range, decimal points)During sleep stage, sleep ratio, not wake
light_ratiofloat (0~1 range, decimal points)?Rate of light sleep during sleep phase
deep_ratiofloat (0~1 range, decimal points)?Rate of deep sleep during sleep phase
rem_ratiofloat (0~1 range, decimal points)?rem sleep ratio
snoring_ratiofloat (0~1 range, decimal points)?The percentage of time during the sleep phase that there was a snoring section
no_snoring_ratiofloat (0~1 range, decimal points)?The percentage of time during the sleep phase that there was no snoring.
waso_countint?The number of times 'wake' occurred during the sleep period
longest_wasoint(seconds)?The duration of the longest 'wake' during the sleep period
sleep_cycle_countint?The number of sleep cycles
sleep_cycleint(seconds)?The average duration of one sleep cycle
snoring_countInt?The number of times snoring occurred.

400 Bad Request

  • If the requested period exceeds the available range or if the date format of the start_date or end_date is incorrect
{
	"detail": "The period should be less than or equal to 100 days"
}

404 Not Found

  • if the corresponding user_id is not found
{
	"detail": "Unable to find the user of id {user_id}"
}

Function that delivers the analyzed results by calling the desired HTTP callback URL, if the parameter is entered in the upload and session end API at Session API, the analysis results will be delivered in the following format

Request

Method

POST

Header

FieldTypeDescription
x-api-keyStringAPI key used to upload data or end session
x-user-idStringThe user id that created the sleep session

Body

FieldTypeDescription
callback_eventString (INFERENCE_COMPLETE,SESSION_COMPLETE)Callback event type
INFERENCE_COMPLETE: If the analysis is completed within 5 or 40 minute increments
SESSION_COMPLETE: The entire session analysis is complete
callback_versionString
(V1,V2,V3)
Callback version
V1: Follows the callback format of v1.0 documentation
V2: Follows the callback format of v2.0
V3: Follows the callback format of the current version
callback_dataWebhook Data ObjectWebhook data

Callback Data Object in case of INFERENCE_COMPLETE

FieldTypeDescription
user_idStringuser id
session_idStringsession id
seq_numIntOrder number of the audio data uploaded
inference_seq_numIntNumber that converted seq_num into 5 minutes increments
e.g.) when uploading MELSPECTROGRAM, if seq_num 39, inference_seq_num is 3
stage_list[Int]Sleep stage results in previous 5 minutes frame
e.g.) if inference_seq_num is 6, you get back 40 values from 3 to 6
snoring_stages[Int]Snoring stage results in previous 5 minutes frame
{
    "event": "INFERENCE_COMPLETE",
    "version": "V3",
    "data": {
        "user_id": "G-20250115025029-vLErWBfQNtnfvgDccFOQ",
        "session_id": "20250115025029_fvivn",
        "seq_num": 39,
        "inference_seq_num": 3,
        "sleep_stages": [0], // omitted
        "breath_stages": null,
        "snoring_stages": [0] // omitted
    }
}

Webhook Data Object in case of SESSION_COMPLETE

FieldTypeDescription
dataSleep Data ObjectThe response format is the same as Get Session in the Data API, with the only difference being the addition of user_id.
{
    "event": "SESSION_COMPLETE",
    "version": "V3",
    "data": {
        "timezone": "UTC",
        "peculiarities": ["NO_BREATHING_STABILITY"],
        "missing_data_ratio": 0.0,
        "user_id": "G-20250115025029-vLErWBfQNtnfvgDccFOQ",
        "session": {
            "id": "20250115025029_fvivn",
            "state": "COMPLETE",
            "start_time": "2025-01-15T02:50:29+00:00",
            "end_time": "2025-01-15T03:50:29+00:00",
            "unexpected_end_time": null,
            "created_timezone": "UTC",
            "sleep_stages": [0], // omitted
            "breath_stages": null, 
            "snoring_stages": [0] // omitted
        },
        "stat": {
            "sleep_time": "2025-01-15T03:05:29+00:00",
            "wake_time": "2025-01-15T03:26:29+00:00",
            "sleep_index": 50,
            "sleep_latency": 900,
            "wakeup_latency": 1440,
            "light_latency": 0,
            "deep_latency": null,
            "rem_latency": null,
            "time_in_bed": 3600,
            "time_in_sleep_period": 1260,
            "time_in_sleep": 1080,
            "time_in_wake": 180,
            "time_in_light": 1080,
            "time_in_deep": 0,
            "time_in_rem": 0,
            "time_in_stable_breath": null,
            "time_in_unstable_breath": null,
            "time_in_snoring": 0,
            "time_in_no_snoring": 1260,
            "sleep_efficiency": 0.3,
            "sleep_ratio": 0.86,
            "wake_ratio": 0.14,
            "light_ratio": 0.86,
            "deep_ratio": 0.0,
            "rem_ratio": 0.0,
            "stable_breath_ratio": null,
            "unstable_breath_ratio": null,
            "snoring_ratio": 0.0,
            "no_snoring_ratio": 1.0,
            "breathing_index": null,
            "breathing_pattern": null,
            "waso_count": 1,
            "longest_waso": 180,
            "sleep_cycle_count": 0,
            "sleep_cycle": null,
            "sleep_cycle_time": [],
            "unstable_breath_count": null,
            "snoring_count": 0
        }
    }
}