llms.txt
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
- 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
- Enter the issued API Key in the YOUR_API_KEY field of Debug.xcconfig and Release.xcconfig.
API_KEY=YOUR_API_KEY
- 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"
- Build and install the sample app on your iPhone.
- If a Signing error occurs, change the Bundle Identifier.
Android Sample App
- 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
- Enter the API Key in local.properties.
asleep_api_key="ApiKey"
- 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
}
}
- 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 Name | Type | Definition | Example [Units] (= Actual Value) |
---|---|---|---|---|
1 | start_time | Time | Exact 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) |
2 | end_time | Time | Exact 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) |
3 | time_in_bed | Duration | The time duration between the start and the end of tracking. | 23428 [s] (=6h 30m 28s) |
4 | sleep_time | Time | Exact 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) |
5 | wake_time | Time | Exact 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) |
6 | time_in_sleep_period | Duration | The time duration between the onset of ‘Sleep’ and the start of the last ‘Wake’ during tracking. | 20190 [s] (= 5h 36m 30s) |
7 | sleep_latency | Duration | The time duration between the start of tracking and the detection of first 'Sleep'. | 3180 [s] (=53m 0s) |
8 | wakeup_latency | Duration | The time duration between the start of the last 'Wake' and the end of tracking. | 30 [s] (= 0m 30s) |
9 | sleep_index | Score | The 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 Name | Type | Definition | Example [Units] (= Actual Value) |
---|---|---|---|---|
1 | time_in_sleep | Duration | The actual time spent sleeping. It is the time duration calculated after subtracting all ‘Wake’ time from time_in_bed. | 19380 [s] (= 5h 23m 0s) |
2 | sleep_efficiency | Ratio | The ratio of time_in_sleep to time_in_bed | 0.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 Name | Type | Definition | Example [Units] (= Actual Value) |
---|---|---|---|---|
1 | sleep_stages | Number List | A 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, .....) |
2 | waso_count | Count | The number of ‘Wake’ detected during time_in_sleep_period | 19 [#] (= 19 times) |
3 | longest_waso | Duration | The longest time duration of ‘Wake’ during time_in_sleep_period | 90 [s] (=1m 30s) |
4 | time_in_wake | Duration | The sum of all ‘Wake’ seconds detected during time_in_sleep_period | 810 [s] (=13m 30s) |
5 | time_in_light | Duration | The sum of all ‘Light’ seconds detected during time_in_sleep_period | 8610 [s] (=2h 23m 30s) |
6 | time_in_deep | Duration | The sum of all ‘Deep’ seconds detected during time_in_sleep_period | 5700 [s] (=1h 35m 0s) |
7 | time_in_rem | Duration | The sum of all ‘REM’ seconds detected during time_in_sleep_period | 5070 [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 Name | Type | Definition | Example [Units] (= Actual Value) |
---|---|---|---|---|
1 | sleep_ratio | Ratio | Ratio of time_in_sleep to time_in_sleep_period | 0.96 [x.xx] (=96%) |
2 | wake_ratio | Ratio | Ratio of time_in_wake to time_in_sleep_period | 0.04 [x.xx] (=4%) |
3 | light_ratio | Ratio | Ratio of time_in_light to time_in_sleep_period | 0.43 [x.xx] (=43%) |
4 | deep_ratio | Ratio | Ratio of time_in_deep to time_in_sleep_period | 0.28 [x.xx] (=28%) |
5 | rem_ratio | Ratio | Ratio of time_in_rem to time_in_sleep_period | 0.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 Name | Type | Definition | Example [Units] (= Actual Value) |
---|---|---|---|---|
1 | light_latency | Duration | The 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) |
2 | deep_latency | Duration | The time duration between sleep_time to the first detection of ‘Deep’ | 540 [s] (=9m 0s) |
3 | rem_latency | Duration | The 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 Name | Type | Definition | Example [Units] (= Actual Value) |
---|---|---|---|---|
1 | sleep_cycle | Duration | The average time duration of sleep cycles. Each sleep cycle is consisted of both 'REM' and 'Non-REM' sleep. | 6520 [s] (=1h 38m 40s) |
2 | sleep_cycle_count | Count | The number of sleep cycles detected during the time_in_sleep_period | 3 [#] (=3 times) |
3 | sleep_cycle_time | Time List | A 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 Name | Type | Definition | Example [Units] (= Actual Value) |
---|---|---|---|---|
1 | snoring_stages | Number List | A 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 .......) |
2 | time_in_snoring | Duration | The time duration, of which snoring is detected during time_in_sleep_period | 23400 [s] (=6h 30m 00s) |
3 | time_in_no_snoring | Duration | The time duration, of which no snoring is detected during time_in_sleep_period | 5400 [s] (=90m 0s) |
4 | snoring_ratio | Ratio | The ratio of time_in_snoring to time_in_sleep_period | 0.72 [x.xx] (=72%) |
5 | no_snoring_ratio | Ratio | The ratio of time_in_no_snoring to time_in_sleep_period | 0.28 [x.xx] (=28%) |
6 | snoring_count | Count | The number of times snoring is detected during the time_in_sleep_period | 20 [#] (=20 times) |
Basic Sleep Analysis
The Basic Sleep Analysis feature allows you to review the following sleep data:
Data Name | Definition |
---|---|
sleep_stages | A list of numbers, indicating sleep stages during time_in_bed (0: Wake / 1: Sleep) |
start_time | Exact time at which the tracking started |
end_time | Exact time at which the tracking ended. |
time_in_bed | The time duration between the start and the end of tracking |
sleep_time | Exact time at which ‘Sleep’ was first detected since the tracking started |
wake_time | Exact time at which the last 'Wake' period was detected during tracking. No sleep will be detected after wake_time |
time_in_sleep_period | The time duration between the onset of ‘Sleep’ and the start of the last ‘Wake’ during tracking |
sleep_latency | The time duration between the start of tracking and the detection of first 'Sleep' |
wakeup_latency | The time duration between the start of the last 'Wake' and the end of tracking |
time_in_sleep | The actual time spent sleeping. It is the time duration calculated after subtracting all ‘Wake’ time from time_in_bed |
sleep_efficiency | The ratio of time_in_sleep to time_in_bed |
waso_count | The number of ‘Wake’ detected during time_in_sleep_period |
longest_waso | The longest time duration of ‘Wake’ during time_in_sleep_period |
time_in_wake | The sum of all ‘Wake’ seconds detected during time_in_sleep_period |
sleep_ratio | Ratio of time_in_sleep to time_in_sleep_period |
wake_ratio | Ratio of time_in_wake to time_in_sleep_period |
sleep_index | The 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 Name | Definition |
---|---|
sleep_stages | A list of numbers, indicating sleep stages during time_in_bed (0: Wake / 1: Light / 2: Deep / 3: REM) |
time_in_light | The sum of all ‘Light’ seconds detected during time_in_sleep_period |
time_in_deep | The sum of all ‘Deep’ seconds detected during time_in_sleep_period |
time_in_rem | The sum of all ‘REM’ seconds detected during time_in_sleep_period |
light_ratio | Ratio of time_in_light to time_in_sleep_period |
deep_ratio | Ratio of time_in_deep to time_in_sleep_period |
rem_ratio | Ratio of time_in_rem to time_in_sleep_period |
light_latency | The 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_latency | The time duration between sleep_time to the first detection of ‘Deep’ |
rem_latency | The time duration between sleep_time to the first detection of ‘REM’ |
sleep_cycle | The average time duration of sleep cycles. Each sleep cycle is consisted of both 'REM' and 'Non-REM' sleep. |
sleep_cycle_count | The number of sleep cycles detected during the time_in_sleep_period |
sleep_cycle_time | A 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 Name | Definition |
---|---|
snoring_stages | A list of snoring stages during the time_in_bed (0: no snoring / 1: snoring) |
time_in_snoring | The time duration, of which snoring is detected during time_in_sleep_period |
time_in_no_snoring | The time duration, of which no snoring is detected during time_in_sleep_period |
snoring_ratio | The ratio of time_in_snoring to time_in_sleep_period |
no_snoring_ratio | The ratio of time_in_no_snoring to time_in_sleep_period |
snoring_count | The 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 Name | Definition |
---|---|
sleep_stages | A list of numbers, indicating sleep stages during time_in_bed |
snoring_stages | A 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.
- Initialization: This step initializes the SDK. It involves creating a new User ID or closing any previously open sleep tracking sessions.
- 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.
- 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.
- 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.
- Since the first analysis starts after 5 minutes, the user must track sleep for at least 5 minutes to receive sleep analysis results.
- 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
-
In Xcode, click File > Add Packages.
-
In the dialog that appears, enter the repository URL https://github.com/asleep-ai/asleep-sdk-ios.
-
In Version, select Up to Next Major Version and the default option.
-
Click
Add Package
button.
-
Click
Add Package
button one more time.
-
In Xcode, click
Signing & Capabilities
on your application target.
-
Click
+ Capability
button and double clickBackground Modes
.
-
Select
Audio, AirPlay, and Picture in Picture
.
-
In Xcode, click
Info
on your app target.
-
Click
+
and addPrivacy - Microphone Usage Description
.
-
Write a microphone permission request message.
Import the Asleep SDK
import AsleepSDK
Sleep Tracking with AsleepTrack SDK
Initialize the AsleepTrack SDK
-
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)
-
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()
- 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~~
Version | History |
---|---|
v3.1.2 | Fixed a crash that occurred when the app was forcefully terminated. |
v3.1.1 | Added library to enable simulator builds |
v3.1.0 | The AI model has been upgraded to Highball, enabling two-person sleep tracking. |
v2.4.7 | Fixed an issue where 'cannotActivateInBackground' error was being delegated when the microphone could not be reactivated after an interrupt. |
v2.4.6 | Added signing in Asleep SDK. |
v2.4.5 | 1. 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.4 | Added retry logic for when the app resumes after being interrupted by the system. |
v2.4.3 | Fixed Mic Recording abnormal behavior after sleeping calls. |
v2.4.2 | Fix sdk version debug message. |
v2.4.1 | Remove Personally Identifiable APIs (Does not need to be applied "PrivacyInfo.xcprivacy"). |
v2.4.0 | Add snoring data in Report and Average Stats. Audio Interrupt Bug fix (Timing changes between audio-related interrupts and processing audio settings). |
v2.3.0 | Average-stats, sleep_index are added. |
v2.2.0 | 1. 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.2 | 1. Add related to TrackingStatus. 2. Add defensive logic to close the session when initAsleepConfig is called during SleepTracking. |
v2.1.1 | 1. Modified Error handling. Audio process stop during session Open / Close error case. 2. Modified Debug SDK Log. |
v2.1.0 | 1. The noise reduction processing has been modified. |
v2.0.0 | 1. 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 Name | Type | Description |
---|---|---|
apiKey | String | Enter the value obtained from the Generate API key |
userId | String? | When there is no initial userId, enter nil, and later input the received userId. |
baseUrl | URL? | Enter the proxy server address. If nil, default base url is used. |
callbackUrl | URL? | Enter the URL of the server to receive sleep session analysis results. |
service | Service? | Enter the app name |
delegate | AsleepConfigDelegate | Delegate to receive results and errors |
AsleepConfigDelegate
protocol AsleepConfigDelegate {
func userDidJoin(userId: String, config: Asleep.Config)
func didFailUserJoin(error: Asleep.AsleepError)
func userDidDelete(userId: String)
}
-
If success, userDidJoin() is called.
Property Name Type Description userId String generated userId config Asleep.Config genearated config -
If failure, didFailUserJoin() is called.
Property Name Type Description error Asleep.AsleepError Error Codes -
userDidDelete()
If success, all user data including the userId will be deleted.Property Name Type Description userId String Deleted userId
Delete User
Asleep.deleteUser()
var config: Asleep.Config?
if let config {
Asleep.deleteUser(config: config)
}
Property Name | Type | Description |
---|---|---|
config | Asleep.Config | Enter 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 Name | Type | Description |
---|---|---|
config | Asleep.Config | Enter the Asleep.Config instance |
delegate | AsleepConfigDelegate | Delegate 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)
}
-
didCreate()
Tracking is generated. -
didUpload()
Data is uploaded.Property Name Type Description sequence Int A value that starts from 0 and increases by 1 every 30 seconds -
didClose()
Tracking is terminated.Property Name Type Description sessionId String Report result id value -
didFail()
Due to error, tracking is endedProperty Name Type Description error Asleep.AsleepError Error Codes -
didInterrupt()
Tracking is interrupted due to events such as calls. -
didResume()
Tracking resumes once the interrupting factor is resolved. -
micPermissionWasDenied()
Tracking cannot be started without microphone permission. -
analysing()
Latest session dataProperty Name Type Description session Asleep.Model.Session during 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 name | Type | Description |
---|---|---|
sessionId | String? | 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 name | Type | Description | Version |
---|---|---|---|
id | String | Sleep session id | |
state | Asleep.Model.State | Sleep session state (OPEN , CLOSED , or COMPLETE ) | |
startTime | Date | Session start time | |
endTime | Date? | Session end date | |
unexpectedEndTime | Date? | 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. | |
createdTimezone | String | Timezone of session creation (Timezone List) | |
sleepStages | Array<Int> | Sleep stages-1 : error0 : wake1 : light2 : deep3 : rem | |
snoringStages | Array<Int> | Snoring stages-1 : error0 : no snoring1 : snoring |
Create report
Asleep.createReports()
var config: Asleep.Config?
var reports: Asleep.Reports?
if let config {
reports = Asleep.createReports(config: config)
}
Property Name | Type | Description |
---|---|---|
config | Asleep.Config | Enter 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 Name | Type | Description |
---|---|---|
sessionId | String | sessionId that can be received when stopping tracking |
completionBlock | Asleep.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 Name | Type | Description |
---|---|---|
fromDate | String (YYYY-MM-DD ) | View date start |
toDate | String (YYYY-MM-DD ) | View date end |
orderBy - default value: .descending | Asleep.Model.OrderBy [.ascending, .descending] | DESC : Descending prderASC : Ascending order |
offset - default value: 0 | Int | Number of reports to skip |
limit - default value: 20 | Int | Maximum number of report (0~100) |
completionBlock | Array<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 Name | Type | Description |
---|---|---|
fromDate | String (YYYY-MM-DD ) | The starting time for the period you want to check the average |
toDate | String (YYYY-MM-DD ) | The ending time for the period you want to check the average |
completionBlock | Asleep.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 Name | Type | Description |
---|---|---|
sessionId | String | sessionId to be deleted |
completionBlock | Asleep.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 name | Type | Description |
---|---|---|
timezone | String | The adjusted time zone of the analysis result e.g. UTC , Asia/Seoul (Timezone List) |
peculiarities | Asleep.Model.Peculiarity | A 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, CLOSEDNEVER_SLEPT : If it is determined that there was no sleep at all during the session measurement timeTOO_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_ratio | Floatt(0~1 range, decimal points ) | The error rate in sleep analysis results due to reasons such as missing audio uploads |
session | Asleep.Model.Session | Session Report information |
stat | Asleep.Model.Stat | Analysis 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 name | Type | Description | Version |
---|---|---|---|
id | String | Session Id | |
state | Asleep.Model.State | Sleep session state (OPEN , CLOSED , or COMPLETE ) | |
startTime | Date | Session start time | |
endTime | Date? | Session end time | |
unexpectedEndTime | Date? | 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. | |
createdTimezone | String | Timezone of session creation (Timezone List) | |
sleepStages | Array<Int> | Sleep stages-1 : error0 : wake1 : light2 : deep3 : rem | |
snoringStages | Array<Int> | Snoring stages-1 : error0 : no snoring1 : 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 name | Type | Description | Version |
---|---|---|---|
sleepEfficiency | Float? | The percentage of time you actually slept during sleep measurement | |
sleepLatency | Int? | time it took to fall asleep | |
sleepTime | Date? | The time it takes to fall asleep after the start of sleep measurement | |
wakeupLatency | Int? | The time it takes to wake up and end your sleep measurement | |
wakeTime | Date? | wake up time | |
lightLatency | Int? | The time it takes to the first Light after the start of sleep. | |
deepLatency | Int? | The time it takes to the first Deep after the start of sleep. | |
remLatency | Int? | The time it takes to the first REM after the start of sleep. | |
timeInWake | Int? | wake during sleep | |
timeInSleepPeriod | Int? | 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 | |
timeInSleep | Int? | During sleep measurement time, the time you were actually sleeping Classified into three stages: deep, light, rem | |
timeInBed | Int? | The time from the start of the sleep measurement to the end of the sleep measurement | |
timeInRem | Int? | Total time the sleep phase progressed to rem | |
timeInLight | Int? | Total time the sleep phase progressed to light | |
timeInDeep | Int? | Total time the sleep phase progressed to deep | |
timeInSnoring | Int? | Total time of snoring | |
timeInNoSnoring | Int? | Total time of no snoring | |
wakeRatio | Float? | Rate of waking time in the middle during sleep stage | |
sleepRatio | Float? | The percentage of time you sleep without waking during the sleep phase | |
remRatio | Float? | Rate of REM sleep during sleep stage | |
lightRatio | Float? | Rate of light sleep during sleep stage | |
deepRatio | Float? | Rate of deep sleep during sleep stage | |
snoringRatio | Float? | The percentage of time during the sleep phase that there was a snoring section | |
noSnoringRatio | Float? | The percentage of time during the sleep phase that there was no snoring. | |
sleepCycle | Int? | The average duration of one sleep cycle. | |
sleepCycleCount | Int? | 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] | |
wasoCount | Int? | The number of times 'wake' occurred during the sleep period | |
longestWaso | Int? | The duration of the longest 'wake' during the sleep period | |
sleepIndex | Int? | The metric that comprehensively represents sleep quality, defined by learning from the distribution of sleep data | |
snoringCount | Int? | 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 name | Type | Description | Version |
---|---|---|---|
sessionId | String | Sleep session ID | |
state | Asleep.Model.State | 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 | |
sessionStartTime | Date | Session start time | |
sessionEndTime | Date? | Session end time | |
createdTimezone | String | Timezone of session creation (Timezone List) | |
unexpectedEndTime | Date? | 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. | |
lastReceivedSeqNum | Int | The sequence number of the last uploaded audio file | |
timeInBed | Int | The 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 name | Type | Description |
---|---|---|
period | Asleep.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 |
averageStats | Asleep.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 name | Type | Description |
---|---|---|
timezone | String | requested timezone 예. UTC, Asia/Seoul |
startDate | Date | requested start date |
endDate | Date | requested 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 name | Type | Description |
---|---|---|
startTime | String(hh:mm:ss ) | Session start time |
endTime | String(hh:mm:ss ) | Session end time |
sleepTime | String(hh:mm:ss ) | The time it takes to fall asleep after the start of sleep staging |
wakeTime | String(hh:mm:ss ) | Wake time |
sleepLatency | Int | Time to fall asleep |
wakeupLatency | Int | The time it takes to wake up and end your sleep measurement |
timeInBed | Int | The time from the start of the sleep measurement to the end of the sleep measurement |
timeInSleepPeriod | Int | 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) |
timeInSleep | Int | During sleep measurement time, the time you were actually sleeping This time is divided into three stages: deep,light,and rem |
timeInWake | Int | Wake time during sleep |
timeInLight | Int? | Total time the sleep phase progressed to light |
timeInDeep | Int? | Total time the sleep phase progressed to deep |
timeInRem | Int? | Total time the sleep phase progressed to rem |
timeInSnoring | Int? | Total time of snoring |
timeInNoSnoring | Int? | Total time of no snoring |
sleepEfficiency | Double | The percentage of time you actually slept during sleep measurement |
wakeRatio | Double | Rate of waking time in the middle during sleep phase |
sleepRatio | Double | During sleep stage, sleep ratio, not wake |
lightRatio | Double? | Rate of light sleep during sleep phase |
deepRatio | Double? | Rate of deep sleep during sleep phase |
remRatio | Double? | rem sleep ratio |
snoringRatio | Double? | The percentage of time during the sleep phase that there was a snoring section |
noSnoringRatio | Double? | The percentage of time during the sleep phase that there was no snoring. |
wasoCount | Int | The number of times 'wake' occurred during the sleep period |
longestWaso | Int | The duration of the longest 'wake' during the sleep period |
sleepCycleCount | Int? | The number of sleep cycles. |
snoringCount | Int? | The number of times snoring occurred. |
Asleep.Model.NeverSleptSession
struct NeverSleptSession {
let id: String
let startTime: Date
let endTime: Date
let completedTime: Date
}
Property name | Type | Description |
---|---|---|
id | String | session id |
startTime | Date | Session start time |
endTime | Date | Session end time |
completedTime | Date | Time 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 name | Type | Description |
---|---|---|
id | String | session id |
createdTimezone | String | Timezone of session creation (Timezone List) |
startTime | Date | Session start time |
endTime | Date | Session end time |
completedTime | Date | Time of session analysis completion |
sleepEfficiency | Double | The percentage of time you actually slept during sleep measurement |
sleepLatency | Int? | Time to fall asleep |
wakeupLatency | Int? | The time it takes to wake up and end your sleep measurement |
lightLatency | Int? | The time it takes to the first Light after the start of sleep |
deepLatency | Int? | The time it takes to the first Deep after the start of sleep |
remLatency | Int? | The time it takes to the first REM after the start of sleep |
sleepTime | Date? | The time it takes to fall asleep after the start of sleep staging |
wakeTime | Date? | Wake time |
timeInWake | Int | Wake time during sleep |
timeInSleepPeriod | Int | 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) |
timeInSleep | Int | During sleep measurement time, the time you were actually sleeping This time is divided into three stages: deep,light,and rem |
timeInBed | Int | The time from the start of the sleep measurement to the end of the sleep measurement |
timeInRem | Int? | Total time the sleep phase progressed to rem |
timeInLight | Int? | Total time the sleep phase progressed to light |
timeInDeep | Int? | Total time the sleep phase progressed to deep |
timeInSnoring | Int? | Total time of snoring |
timeInNoSnoring | Int? | Total time of no snoring |
wakeRatio | Double | Rate of waking time in the middle during sleep phase |
sleepRatio | Double | During sleep stage, sleep ratio, not wake |
remRatio | Double? | rem sleep ratio |
lightRatio | Double? | Rate of light sleep during sleep phase |
deepRatio | Double? | Rate of deep sleep during sleep phase |
snoringRatio | Double? | The percentage of time during the sleep phase that there was a snoring section |
noSnoringRatio | Double? | The percentage of time during the sleep phase that there was no snoring. |
sleepCycle | Int? | The average duration of one sleep cycle |
sleepCycleCount | Int? | The number of sleep cycles |
wasoCount | Int? | The number of times 'wake' occurred during the sleep period |
longestWaso | Int? | The duration of the longest 'wake' during the sleep period |
snoringCount | Int? | The number of times snoring occurred. |
Asleep.setDebugLoggerDelegate()
let delegate: AsleepDebugLoggerDelegate = self
Asleep.setDebugLoggerDelegate(self)
protocol AsleepDebugLoggerDelegate {
func didPrint(message: String)
}
Property Name | Type | Description |
---|---|---|
message | String | Log 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
Code | Type | Description | State | Handling |
---|---|---|---|---|
401 | Unauthorized | Unauthorized | COMMON | Client Handling |
401 | Unauthorized | invalid user id | COMMON | Client Handling |
403 | Plan is expired | Plan is expired | COMMON | SDK Stop |
403 | Rate limit exceeded | Rate limit exceeded | COMMON | SDK Stop |
403 | Quota exceeded | Quota exceeded | COMMON | SDK Stop |
400 | Bad Request | Invalid callback url | TRACKING | Client Handling |
400 | Bad Request | [WARNING] Invalid session end time. format(YYYY-MM-DDTHH:mm:ssz), 'session_end_time' must always be greater than 'session_start_time’ | TRACKING | SDK Handling |
403 | Forbidden | the sleep session is already closed | TRACKING | SDK Stop |
404 | Not Found | session does not exist. | TRACKING | Client Handling |
409 | Conflict | previous sleep session is not closed yet | TRACKING | SDK Stop |
422 | Validation Error | Invalid parameter | TRACKING | SDK Handling |
422 | Unprocessable Entity | Invalid parameter. | TRACKING | SDK Handling |
400 | Bad Request | invalid timezone | REPORT | Client Handling |
400 | Unprocessable Entity | The format of sleep session id {session_id} is not valid | REPORT | Client Handling |
401 | Unauthorized | The api key is not provided | REPORT | Client Handling |
404 | Not Found | Unable to find the sleep session of id {session_id} | REPORT | Client 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
- Create a project using Android Studio.
- 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>
- 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.
- Pass the
asleepConfig
generated frominitAsleepConfig
and theasleepTrackingListener
to monitor the sleep tracking status. - When tracking begins, the
onStart()
callback is triggered. - The
onPerform()
callback is called every 30 seconds to provide progress updates. - When tracking ends, the
onFinish()
callback is triggered.
- Pass the
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.
- Create a
Reports
object by passing theasleepConfig
generated frominitAsleepConfig
. - Provide the
sessionId
that was created during sleep tracking.
- Create a
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 thatuserId
,sessionId
, andreport
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:
- 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()
andendSleepTracking()
to implement sleep tracking easily.- Refer to the Begin-End Sample App.
- 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
.
Version | History |
---|---|
v3.1.2 | Fixed an issue where changes to the apiKey were not recognized. Added missing libraries for 32-bit devices. |
v3.1.1 | Exception handling for errors occurring only on Android 13. |
v3.1.0 | The 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.2 | 1. 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.1 | Added an optional ‘isPrivacySensitive’ parameter to ‘startSleepTracking()’ to optionally select the privacy sensitive feature of the AudioRecord. The default is true. |
v.2.4.0 | Add snoring data to Report and Average Stats. Add setPrivacySensitive during Recording. |
v2.3.0 | Average-stats, sleep_index are added. Added functionality to continue the session. Changed some functions to asynchronous processing. |
v2.2.2 | Android 14 compatibility has been addressed in the hotfix. |
v2.2.1 | Fixed obfuscation bug for sessionId in getTrackingStatus. |
v2.2.0 | 1. 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.2 | 1. Redefine errorCode. 2. Add related to TrackingStatus. 3. Add defensive logic to close the session when initAsleepConfig is called during SleepTracking. |
v2.1.1 | 1. 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.0 | 1. The noise reduction processing has been modified. 2. User-Agent has been added to HTTP. |
v2.0.0 | 1. 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 Name | Type | Description |
---|---|---|
context | Context | Enter ApplicationContext |
apiKey | String | Enter the value issued by Generate API key |
userId | String? | Enter null if there is no initial userId, and enter the userId that has been issued since |
baseUrl | String? | If null, use the default value, enter the proxy server address |
callbackUrl | String? | Enter the url of the server to receive sleep session analysis results |
service | String? | your app name |
asleepConfigListener | AsleepConfigListener | listener to receive callback for userId |
asleepLogger | AsleepLogger? | 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 Name | Type | Description |
---|---|---|
userId | String? | Newly issued or entered userId |
asleepConfig | AsleepConfig? | Required set value to use the SDK |
- If failure, onFail() is called.
Parameter Name | Type | Description |
---|---|---|
errorCode | Int | AsleepErrorCode |
detail | String | errorCode 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 Name | Type | Description |
---|---|---|
tag | String | "[Asleep SDK]" |
msg | String | log message |
throwable | Throwable? | 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 Name | Type | Description |
---|---|---|
deleteUserIdListener | DeleteUserIdListener? | 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 Name | Type | Description |
---|---|---|
userId | String? | deleted userId |
- If failure, onFail() is called.
Parameter Name | Type | Description |
---|---|---|
errorCode | Int | See AsleepErrorCode |
detail | String | errorCode 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 Name | Type | Description |
---|---|---|
context | Context? | 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 Name | Type | Description |
---|---|---|
context | Context? | Enter ApplicationContext |
apiKey | String | Enter 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:
- Foreground Service Execution: The Foreground Service starts automatically, ensuring background tasks remain stable.
- 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.
- 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
)
Parameter | Type | Description |
---|---|---|
asleepConfig | AsleepConfig | Value received from initAsleepConfig . |
notificationClass | Class<*>? | Activity to open when tapping the foreground service notification. |
notificationTitle | String? | Title of the foreground service notification. |
notificationText | String? | Body text of the foreground service notification. |
notificationIcon | Int? | Icon resource for the foreground service notification. |
asleepTrackingListener | Asleep.AsleepTrackingListener | Listener 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)
}
Function | Parameter | Type | Description |
---|---|---|---|
onStart | sessionId | String | Called when sleep tracking starts, providing the session ID. |
onPerform | sequence | Int | Called every 30 seconds during analysis, providing a sequence value starting from 0. |
onFinish | sessionId | String | Called when sleep tracking ends, providing the session ID of the completed session. |
onFail | errorCode | Int | Called if an error occurs during the sleep tracking process, returning an errorCode. |
detail | String | Additional 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 theonFail()
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.
- If
Asleep.isSleepTrackingProcessAlive(context: Context)
Asleep.connectSleepTracking()
- If
isSleepTrackingProcessAlive()
returnstrue
, 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 Name | Type | Description |
---|---|---|
asleepConfig | AsleepConfig? | Enter the set value received by the callback in the initAsleepConfig call |
trackingListener | TrackingListener | Listener 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 Name | Type | Description |
---|---|---|
sequence | Int | A value that starts from 0 and increases by 1 every 30 seconds |
- When Sleep Tracking is ended, onClose()is called.
Parameter Name | Type | Description |
---|---|---|
sessionId | String | Report Result id value |
- If failure, onFail() is called.
Parameter Name | Type | Description |
---|---|---|
errorCode | Int | See AsleepErrorCode |
detail | String | errorCode 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 Name | Type | Description |
---|---|---|
isPrivacySensitive | Boolean | If 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 Name | Type | Description |
---|---|---|
analysisListener | AnalysisListener | sleep 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 Name | Type | Description |
---|---|---|
id | String? | Sleep session id |
state | String? | Sleep session state (OPEN, CLOSED or COMPLETE) |
startTime | String? | Session start time |
endTime | String? | Session end date |
sleepStages | List<Int?>? | Sleep stages |
snoringStages | List<Int?>? | Snoring |
- If failure, onFail() is called.
Parameter Name | Type | Description |
---|---|---|
errorCode | Int | See AsleepErrorCode |
detail | String | errorCode 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 name | Type | Description |
---|---|---|
sessionId | String? | 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 Name | Type | Description |
---|---|---|
asleepConfig | AsleepConfig? | 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 Name | Type | Description |
---|---|---|
sessionId | String | When Sleep Tracking stops, sessionId value |
reportListener | ReportListener | Report 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 Name | Type | Description | Version |
---|---|---|---|
timezone | String | Timezone (Timezone List) | |
peculiarities | List | A 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, CLOSEDNEVER_SLEPT : If it is determined that there was no sleep at all during the session measurement timeTOO_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. | |
missingDataRatio | Float | The error rate in sleep analysis results due to reasons such as missing audio uploads | |
session | Session? | Session analysis information | |
stat | Stat? | Analysis statistical information | |
id | String | Session Id | |
state | String | Status of SessionOPEN : An in-progress session, with audio uploads availableCLOSED : 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 | |
startTime | String | Session start time Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul) | |
endTime | String? | Session end time Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul) | |
sleepStages | List<Int>? | Sleep Stages List | |
createdTimezone | String | Timezone of session creation (Timezone List) | |
unexpectedEndTime | String? | Abnormal session termination time. This assign the next initAsleepConfig time. | |
sleepEfficiency | Float? | The percentage of time you actually slept during sleep measurement | |
sleepLatency | Int? | time it took to fall asleep | |
sleepTime | String? | The time it takes to fall asleep after the start of sleep staging | |
wakeupLatency | Int? | The time it takes to wake up and end your sleep measurement | |
wakeTime | String? | wake up time | |
timeInWake | Int? | wake during sleep | |
timeInSleepPeriod | Int? | 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) | |
timeInSleep | Int? | During sleep measurement time, the time you were actually sleeping This time is divided into three stages: deep, light, and rem | |
timeInBed | Int? | The time from the start of the sleep measurement to the end of the sleep measurement | |
timeInRem | Int? | Total time the sleep phase progressed to rem | |
timeInLight | Int? | Total time the sleep phase progressed to light | |
timeInDeep | Int? | Total time the sleep phase progressed to deep | |
wakeRatio | Float? | Rate of waking time in the middle during sleep stage | |
sleepRatio | Float? | During sleep stage, sleep ratio, not wake | |
remRatio | Float? | Rate of rem sleep during sleep stage | |
lightRatio | Float? | Rate of light sleep during sleep stage | |
deepRatio | Float? | Rate of deep sleep during sleep stage | |
sleepCycle | Int? | The average duration of one sleep cycle. | |
sleepCycleCount | Int? | The number of sleep cycles. | |
wasoCount | Int? | The number of times 'wake' occurred during the sleep period | |
longestWaso | Int? | The duration of the longest 'wake' during the sleep period | |
lightLatency | Int? | The time it takes to the first Light after the start of sleep. | |
remLatency | Int? | The time it takes to the first REM after the start of sleep. | |
deepLatency | Int? | The time it takes to the first Deep after the start of sleep. | |
sleepIndex | Int? | The metric that comprehensively represents sleep quality, defined by learning from the distribution of sleep data | |
timeInSnoring | Int? | Total time in the snoring | |
timeInNoSnoring | Int? | Total time in the no snoring | |
snoringRatio | Float? | Percentage of time spent snoring during sleep stages | |
noSnoringRatio | Float? | Percentage of time spent not snoring during sleep stages | |
snoringCount | Int? | Number of occurrences of snoring episodes | |
sleepCycleTime | List? | 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 Name | Type | Description |
---|---|---|
errorCode | Int | See AsleepErrorCode |
detail | String | errorCode 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 Name | Type | Description |
---|---|---|
fromDate | String (YYYY-MM-DD ) | View start date |
toDate | String (YYYY-MM-DD ) | View last date |
orderBy = "DESC" | String | DESC: descending order, ASC: ascending order |
offset = 0 | Int | number of skipped Report |
limit = 20 | Int | max number of Report (0~100) |
reportsListener | ReportsListener? | 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 Name | Type | Description | Version |
---|---|---|---|
sessionId | String? | Sleep session ID | |
lastReceivedSeqNum | Int? | The sequence number of the last uploaded audio file | |
sessionEndTime | String? | Session end time | |
sessionStartTime | String? | Session start time | |
state | String? | Sleep session state (OPEN, CLOSED or COMPLETE) | |
timeInBed | Int? | The time from the start of the sleep measurement to the end of the sleep measurement | |
createdTimezone | String | Timezone of session creation (Timezone List) | |
unexpectedEndTime | String? | 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 Name | Type | Description |
---|---|---|
errorCode | Int | See AsleepErrorCode |
detail | String | errorCode 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 Name | Type | Description |
---|---|---|
fromDate | String | The starting time for the period you want to check the average |
toDate | String | The ending time for the period you want to check the average |
averageReportListener | AverageReportListener | Average 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 Name | Type | Description |
---|---|---|
period | Period | Timezone |
peculiarities | List | Special considerations when calculating the average of sleep sessions |
averageStats | AverageStats? | An object containing the averages of sleep metrics for "sleptSessions" |
neverSleptSessions | List | A list of sessions during which it is determined that no sleep occurred at all during the measurement time. |
sleptSessions | List | A 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 Name | Type | Description |
---|---|---|
timezone | String | requested timezone Ex. UTC, Asia/Seoul |
startDate | String | requested start date |
endDate | String | requested 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 Name | Type | Description | Version |
---|---|---|---|
startTime | String | Session start time | |
endTime | String | Session end time | |
sleepTime | String | The time it takes to fall asleep after the start of sleep staging | |
wakeTime | String | Wake time | |
sleepLatency | Int | Time to fall asleep | |
wakeupLatency | Int | The time it takes to wake up and end your sleep measurement | |
timeInBed | Int | The time from the start of the sleep measurement to the end of the sleep measurement | |
timeInSleepPeriod | Int | 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) | |
timeInSleep | Int | During sleep measurement time, the time you were actually sleeping This time is divided into three stages: deep,light,and rem | |
timeInWake | Int | Wake time during sleep | |
timeInLight | Int? | Total time the sleep phase progressed to light | |
timeInDeep | Int? | Total time the sleep phase progressed to deep | |
timeInRem | Int? | Total time the sleep phase progressed to rem | |
sleepEfficiency | Float? | The percentage of time you actually slept during sleep measurement | |
wakeRatio | Float? | Rate of waking time in the middle during sleep phase | |
sleepRatio | Float? | During sleep stage, sleep ratio, not wake | |
lightRatio | Float? | Rate of light sleep during sleep phase | |
deepRatio | Float? | Rate of deep sleep during sleep phase | |
remRatio | Float? | rem sleep ratio | |
wasoCount | Int? | The number of times 'wake' occurred during the sleep period | |
longestWaso | Int? | The duration of the longest 'wake' during the sleep period | |
sleepCycleCount | Int? | The number of sleep cycles. | |
timeInSnoring | Int? | Total time in the snoring | |
timeInNoSnoring | Int? | Total time in the no snoring | |
snoringRatio | Float? | Percentage of time spent snoring during sleep stages | |
noSnoringRatio | Float? | Percentage of time spent not snoring during sleep stages | |
snoringCount | Int? | Number of occurrences of snoring episodes |
NeverSleptSessions
data class NeverSleptSessions (
val id: String,
val startTime: String,
val endTime: String,
val completedTime: String
)
Parameter Name | Type | Description |
---|---|---|
id | String | session id |
startTime | String | Session start time Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul) |
endTime | String | Session end time Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul) |
completedTime | String | Time 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 name | Type | Description | Version |
---|---|---|---|
id | String | session id | |
createdTimezone | String | Timezone of session creation (Timezone List) | |
startTime | String | Session start time Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul) | |
endTime | String | Session end time Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul) | |
completedTime | String | Time of session analysis completion Example) 2022-08-01T01:31: 17+09: 00 (If the request timezone is Asia/Seoul) | |
sleepEfficiency | Float | The percentage of time you actually slept during sleep measurement | |
sleepLatency | Int? | Time to fall asleep | |
sleepTime | String? | The time it takes to fall asleep after the start of sleep staging | |
wakeupLatency | Int? | The time it takes to wake up and end your sleep measurement | |
wakeTime | String? | Wake time | |
lightLatency | Int? | The time it takes to the first Light after the start of sleep | |
deepLatency | Int? | The time it takes to the first Deep after the start of sleep | |
remLatency | Int? | The time it takes to the first REM after the start of sleep | |
timeInWake | Int | Wake time during sleep | |
timeInSleepPeriod | Int | 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) | |
timeInSleep | Int | During sleep measurement time, the time you were actually sleeping This time is divided into three stages: deep,light,and rem | |
timeInBed | Int | The time from the start of the sleep measurement to the end of the sleep measurement | |
timeInRem | Int? | Total time the sleep phase progressed to rem | |
timeInLight | Int? | Total time the sleep phase progressed to light | |
timeInDeep | Int? | Total time the sleep phase progressed to deep | |
wakeRatio | Float | Rate of waking time in the middle during sleep phase | |
sleepRatio | Float | During sleep stage, sleep ratio, not wake | |
remRatio | Float? | rem sleep ratio | |
lightRatio | Float? | Rate of light sleep during sleep phase | |
deepRatio | Float? | Rate of deep sleep during sleep phase | |
sleepCycle | Int? | The average duration of one sleep cycle | |
sleepCycleCount | Int? | The number of sleep cycles | |
wasoCount | Int? | The number of times 'wake' occurred during the sleep period | |
longestWaso | Int? | The duration of the longest 'wake' during the sleep period | |
timeInSnoring | Int? | Total time in the snoring | |
timeInNoSnoring | Int? | Total time in the no snoring | |
snoringRatio | Float? | Percentage of time spent snoring during sleep stages | |
noSnoringRatio | Float? | Percentage of time spent not snoring during sleep stages | |
snoringCount | Int? | Number of occurrences of snoring episodes |
- If failure, onFail() is called.
Parameter Name | Type | Description |
---|---|---|
errorCode | Int | See AsleepErrorCode |
detail | String | errorCode 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 Name | Type | Description |
---|---|---|
sessionId | String | Delete sessionId value |
deleteReportListener | DeleteReportListener | Report delete callback listener |
- Asleep.Reports.DeleteReportListener
interface DeleteReportListener {
fun onSuccess(sessionId: String?)
fun onFail(errorCode: Int, detail: String)
}
- If success, onSuccess() is called.
Parameter Name | Type | Description |
---|---|---|
sessionId | String? | delete sessionId value |
- If failure, onFail() is called.
Parameter Name | Type | Description |
---|---|---|
errorCode | Int | See AsleepErrorCode |
detail | String | errorCode 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.
Error | Code | Description | Handling | Version |
---|---|---|---|---|
ERR_SETUP_INCOMPLETE | 10000 | Setup process is not completed. | SDK Stop | 3.1.0 |
ERR_UNABLE_ODA | 10001 | ODA is unavailable. | SDK Stop | 3.1.0 |
ERR_UNKNOWN | 11000 | Unknown | SDK Stop | |
ERR_UNINITIALIZED | 11001 | Uninitialized SDK | SDK Stop | |
ERR_MIC_PERMISSION | 11002 | No mic permission | Client Handling | |
ERR_AUDIO | 11003 | Android Audio Error | SDK Stop | |
ERR_INVALID_URL | 11004 | Invalid URL Format | SDK Stop | |
ERR_AUDIO_SILENCED | 11005 | Recording Audio Silenced | SDK Handling | |
ERR_AUDIO_UNSILENCED | 11006 | Recording Audio Unsilenced | SDK Handling | |
ERR_COMMON_UNAUTHORIZED | 11401 | Unauthorized | SDK Stop | |
ERR_COMMON_EXPIRED | 11403 | Plan is expired | Rate limit exceeded | Quota exceeded | SDK Stop | |
ERR_COMMON_NOT_FOUND | 11404 | user not exist | SDK Stop | |
ERR_NETWORK | 11500 | HTTP 500 error | Network error | SDK Stop | |
ERR_INIT_FAILED | 21000 | Failed to initAsleepConfig | Network error occurred. | Client Handling | |
ERR_INIT_SERVER_ERROR | 21500 | internal server error | Client Handling | |
ERR_CREATE_FAILED | 22000 | Failed to create a session | Network error occurred. | Client Handling | |
ERR_CREATE_CONFLICT | 22409 | The previous sleep session is not closed yet. | SDK Stop | |
ERR_CREATE_SERVER_ERROR | 22500 | internal server error | SDK Stop | |
ERR_UPLOAD_FAILED | 23000 | Failed to upload | Network error occurred. | SDK Handling | |
ERR_UPLOAD_UNAUTHORIZED | 23401 | invalid customer uuid | user_agent is empty | SDK Handling | |
ERR_UPLOAD_FORBIDDEN | 23403 | The session is already closed. | SDK Stop | |
ERR_UPLOAD_NOT_FOUND | 23404 | The session does not exist. | SDK Stop | |
ERR_UPLOAD_BAD_REQUEST | 23400 | Invalid 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_LARGE | 23413 | HTTP content length exceeded {size} bytes. | SDK Handling | |
ERR_UPLOAD_UNPROCESSABLE | 23422 | Invalid parameter | Invalid seq_num (seq_num starts from 0) | SDK Handling | |
ERR_UPLOAD_SERVER_ERROR | 23500 | internal server error | SDK Handling | |
ERR_CLOSE_FAILED | 24000 | Failed to close a session | Network error occurred. | Client Handling | |
ERR_CLOSE_UNAUTHORIZED | 24401 | Unauthorized | invalid customer uuid | SDK Stop | |
ERR_CLOSE_FORBIDDEN | 24403 | The session is already closed. | SDK Stop | |
ERR_CLOSE_BAD_REQUEST | 24400 | [WARNING] Invalid session end time. format(YYYY-MM-DDTHH:mm:ssz), must be less than session_start_time | SDK Stop | |
ERR_CLOSE_NOT_FOUND | 24404 | The session does not exist. | SDK Stop | |
ERR_CLOSE_SERVER_ERROR | 24500 | internal server error | Client Handling | |
ERR_DELETE_FAILED | 25000 | Failed to delete a session | Network error occurred. | Client Handling | |
ERR_DELETE_UNAUTHORIZED | 25401 | Invalid customer uuid | Client Handling | |
ERR_DELETE_SERVER_ERROR | 25500 | internal server error | Client Handling | |
ERR_DELETE_USER_FAILED | 26000 | Failed to delete a customer uuid | Network error occurred. | Client Handling | |
ERR_DELETE_USER_UNAUTHORIZED | 26401 | Invalid customer uuid | Client Handling | |
ERR_DELETE_USER_SERVER_ERROR | 26500 | internal server error | Client Handling | |
ERR_ANALYSE_FAILED | 31000 | Failed to analyse | Network error occurred. | Client Handling | |
ERR_ANALYSE_UNAUTHORIZED | 31401 | Unauthorized | Client Handling | |
ERR_ANALYSE_NOT_FOUND | 31404 | Unable to find the sleep session of id {session_id} | Client Handling | |
ERR_ANALYSE_SERVER_ERROR | 31500 | internal server error | Client Handling | |
ERR_REPORT_FAILED | 32000 | Failed to report | Network error occurred. | Client Handling | |
ERR_REPORT_UNAUTHORIZED | 32401 | Unauthorized | Client Handling | |
ERR_REPORT_NOT_FOUND | 32404 | Unable to find the sleep session of id {session_id} | Client Handling | |
ERR_REPORT_SERVER_ERROR | 32500 | internal server error | Client Handling | |
ERR_REPORTS_FAILED | 33000 | Failed to reports | Network error occurred. | Client Handling | |
ERR_REPORTS_UNAUTHORIZED | 33401 | The API key is not provided. | Client Handling | |
ERR_REPORTS_SERVER_ERROR | 33500 | internal server error | Client Handling | |
ERR_AVERAGE_REPORT_FAILED | 34000 | Failed to average report | Network error occurred. | Client Handling | |
ERR_AVERAGE_REPORT_BAD_REQUEST | 34400 | The period should be less than or equal to 100 days | Client Handling | |
ERR_AVERAGE_REPORT_NOT_FOUND | 34404 | Unable to find the user of id {user_id} | Client Handling | |
ERR_AVERAGE_REPORT_SERVER_ERROR | 34500 | internal server error | Client 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.
Field | Type | Description |
---|---|---|
x-api-key | String | API Key |
Response Structure
All API responses follow the structure of the response object below.
Field | Type | Description |
---|---|---|
detail | String | Message value according to the API call result. |
result | Object | Result 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.
- 401 Unauthorized
- API Key is missing or invalid
{ "detail": "Unauthorized" }
- 403 Plan is expired
- Plan usage period has expired
{ "detail": "Plan is expired" }
- 403 Rate limit exceeded
- API call count has exceeded the defined Rate limit
{ "detail": "Rate limit exceeded" }
- 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
Parameter | Type | Required | Description |
---|---|---|---|
x-api-key | String | O | API 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)
Field | Type | Description |
---|---|---|
user_id | String | user 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
Field | Type | Required | Description |
---|---|---|---|
x-api-key | String | O | API Key |
Path Parameter
Field | Type | Required | Description |
---|---|---|---|
user_id | String | O | user 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)
Field | Type | Description |
---|---|---|
user_id | String | user id |
to_be_deleted | Boolean | whether the user is marked for deletion |
last_session_info | Session Object or null | information about the last session |
Session Object
if state == OPEN
: session_end_time is null
if state != COMPLETE
: complete_end_time is null
Field | Type | Description |
---|---|---|
session_id | String | session id |
inference_type | String | format of the audio data uploaded in the session |
service | String | name of the service specified when creating the session |
start_time | String (YYYY-MM-DDThh:mm:ssZ ) | start time of the session |
end_time | String (YYYY-MM-DDThh:mm:ssZ )? | end time of the session |
state | String (OPEN ,CLOSED ,COMPLETE ) | state of the session |
complete_time | String (YYYY-MM-DDThh:mm:ssZ )? | completion time of the final session analysisif 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
Field | Type | Required | Description |
---|---|---|---|
x-api-key | String | O | API Key |
Path Parameter
Field | Type | Required | Description |
---|---|---|---|
user_id | String | O | user 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_id
is 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
Field | Type | Required | Description |
---|---|---|---|
x-api-key | String | O | API Key |
x-user-id | String | O | Issued user id |
Path parameter
Field | Type | Required | Description |
---|---|---|---|
session_id | String | O | Created 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
Field | Type | Required | Description |
---|---|---|---|
x-api-key | String | O | API Key |
x-user-id | String | O | Issued 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
Field | Type | Required | Default | Description |
---|---|---|---|---|
x-api-key | String | O | - | API Key |
x-user-id | String | O | - | Issued user id |
timezone | String | X | UTC | Change the timezone of the analysis results to the corresponding timezone and return UTC, Asia/Seoul |
Path parameter
Field | Type | Required | Description |
---|---|---|---|
session_id | String | O | id 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 isnull
if:peculiarities == IN_PROGRESS or NO_REALTIME_POLLING or TOO_SHORT_FOR_ANALYSIS or TOO_MANY_DEFECTS_IN_SLEEP_STAGES
Field | Type | Description |
---|---|---|
timezone | String | Timezone (Timezone List) |
peculiarities | List | A 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, CLOSEDNEVER_SLEPT : If it is determined that there was no sleep at all during the session measurement timeTOO_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_ratio | float(0~1 range, decimal points ) | The error rate in sleep analysis results due to reasons such as missing audio uploads |
session | Session Object | Session Report Information |
stat | Stat Object? | Session Report Information |
Session Object
if state == OPEN
: session_end_time is null
Field | Type | Description |
---|---|---|
id | String | session id |
state | String (OPEN ,CLOSED ,COMPLETE ) | Status of SessionOPEN : An in-progress session, with audio uploads availableCLOSED : The session terminated by sending an end session request. Unable to upload audio files. Analysis of uploaded sleep audio is still in progressCOMPLETE : All sleep analysis completed after the end of the session |
start_time | String (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_time | String (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_time | String (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_timezone | String | Timezone 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
number | sleep stage |
---|---|
-1 | error (invalid audio, analysis error, etc) |
0 | wake |
1 | light sleep |
2 | deep sleep |
3 | REM 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.
number | snoring stage |
---|---|
-1 | error (invalid audio, analysis error, etc) |
0 | no snoring |
1 | snoring |
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 nullif 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.
Field | Type | Description | Example |
---|---|---|---|
sleep_time | String (YYYY-MM-DDThh:mm:ss+-hh:mm )? | The time it takes to fall asleep after the start of sleep staging | 2022-08-01T00:30:00+09:00 |
wake_time | String (YYYY-MM-DDThh:mm:ss+-hh:mm )? | Wake time | 2022-08-01T07:30:00+09:00 |
sleep_index | Int(50 <= sleep_index <= 100 )? | (Beta) Test Operation Sleep Data | 87 |
sleep_latency | Int (seconds )? | Time to fall asleep | 1800 |
wakeup_latency | Int (seconds )? | The time it takes to wake up and end your sleep measurement | 1800 |
light_latency | Int(seconds )? | The time it takes to the first Light after the start of sleep. | |
deep_latency | Int(seconds )? | The time it takes to the first Deep after the start of sleep. | |
rem_latency | Int(seconds )? | The time it takes to the first REM after the start of sleep. | |
time_in_bed | Int (seconds ) | The time from the start of the sleep measurement to the end of the sleep measurement | 28800 |
time_in_sleep_period | Int (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_sleep | Int (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_wake | Int (seconds ) | Wake time during sleep | 2700 |
time_in_light | Int (seconds )? | Total time the sleep phase progressed to light | 5400 |
time_in_deep | Int (seconds )? | Total time the sleep phase progressed to deep | 5400 |
time_in_rem | Int (seconds )? | Total time the sleep phase progressed to rem | 13500 |
time_in_snoring | Int? | Total time of snoring | 5400 |
time_in_no_snoring | Int? | Total time of no snoring | 23400 |
sleep_efficiency | float (0~1 range, decimal points ) | The percentage of time you actually slept during sleep measurement | 0.84 |
sleep_ratio | float (0~1 range, decimal points )? | During sleep stage, sleep ratio, not wake | 0.9 |
wake_ratio | float (0~1 range, decimal points )? | Rate of waking time in the middle during sleep phase | 0.1 |
light_ratio | float (0~1 range, decimal points )? | Rate of light sleep during sleep phase | 0.2 |
deep_ratio | float (0~1 range, decimal points )? | Rate of deep sleep during sleep phase | 0.2 |
rem_ratio | float (0~1 range, decimal points )? | rem sleep ratio | 0.5 |
snoring_ratio | float (0~1 range, decimal points )? | The percentage of time during the sleep phase that there was a snoring section | 0.3 |
no_snoring_ratio | float (0~1 range, decimal points )? | The percentage of time during the sleep phase that there was no snoring. | 0.7 |
waso_count | Int? | The number of times 'wake' occurred during the sleep period | 10 |
longest_waso | Int(seconds )? | The duration of the longest 'wake' during the sleep period | 300 |
sleep_cycle_count | Int? | The number of sleep cycles. | 4 |
sleep_cycle | Int(seconds )? | The average duration of one sleep cycle. | 6600 |
sleep_cycle_time | List 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_count | Int? | 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_id
if 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
Field | Type | Required | Default | Description |
---|---|---|---|---|
x-api-key | String | O | - | API Key |
x-user-id | String | O | - | Issued user id |
timezone | String | X | UTC | Return 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.
Field | Type | Required | Default | Description |
---|---|---|---|---|
date_gte | String (YYYY-MM-DD ) | X | - | Return sessions that are greater than or equal to date_gte based on the timezone in the header |
date_lte | String (YYYY-MM-DD ) | X | - | Return sessions that are less than or equal to date_lte based on the timezone in the header |
order_by | String (ASC or DESC ) | X | DESC | DESC : Sort in descending orderASC : Sort in ascending order |
offset | Int | X | 0 | Number of sessions to skip |
limit | Int (Integer of 0~100 ) | X | 20 | Number 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)
Field | Type | Description |
---|---|---|
timezone | String | Timezone |
sleep_session_list | List of Sleep Session Objects | List of session data |
Sleep Session Object
if state == OPEN
: session_end_time is null
Field | Type | Description |
---|---|---|
session_id | String | Session ID |
state | String (OPEN ,CLOSED ,COMPLETE ) | Session stateOPEN : In-progress session, audio upload is possibleCLOSED : Session has been closed, audio file upload is not possible. Analysis of the uploaded sleep audio is ongoingCOMPLETE : Session has been closed and all sleep analysis is completed |
session_start_time | String (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_time | String (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_timezone | String | Timezone of session creation (Timezone List) |
unexpected_end_time | String(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_num | Int? | Sequence number of the last uploaded audio file |
time_in_bed | Int (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
Field | Type | Required | Default | Description |
---|---|---|---|---|
x-api-key | String | O | - | API Key |
timezone | String | X | UTC | Change the timezone of the analysis results to the corresponding timezone and return UTC, Asia/Seoul |
Path parameter
Field | Type | Required | Description |
---|---|---|---|
user_id | String | O | id of the session in which you want to request data |
Query string
Field | Type | Required | Default | Description |
---|---|---|---|---|
start_date | String | O | - | The starting time for the period you want to check the average |
end_date | String | O | - | 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)
Field | Type | Description |
---|---|---|
period | Period Object | Timezone (Timezone List) |
peculiarities | List | Special considerations when calculating the average of sleep sessionsNO_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_stats | Average Stats Object? | An object containing the averages of sleep metrics for "slept_sessions" |
never_slept_sessions | List of Never Slept Session Object | A list of sessions during which it is determined that no sleep occurred at all during the measurement time. |
slept_sessions | List of Slept Session Object | A list of sessions during which it is determined that sleep occurred during the measurement time. |
Period Object
Field | Type | Description |
---|---|---|
timezone | String | requested timezone 예. UTC, Asia/Seoul |
start_date | String(YYYY-MM-DD ) | requested start date |
end_date | String (YYYY-MM-DD ) | requested end date |
Average Stats Object
Field | Type | Description |
---|---|---|
start_time | String(hh:mm:ss ) | Session start time |
end_time | String(hh:mm:ss ) | Session end time |
sleep_time | String (hh:mm:ss ) | The time it takes to fall asleep after the start of sleep staging |
wake_time | String (hh:mm:ss ) | Wake time |
sleep_latency | Int | Time to fall asleep |
wakeup_latency | Int | The time it takes to wake up and end your sleep measurement |
time_in_bed | Int | The time from the start of the sleep measurement to the end of the sleep measurement |
time_in_sleep_period | Int | 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_sleep | Int | During sleep measurement time, the time you were actually sleeping This time is divided into three stages: deep,light,and rem |
time_in_wake | Int | Wake time during sleep |
time_in_light | Int? | Total time the sleep phase progressed to light |
time_in_deep | Int? | Total time the sleep phase progressed to deep |
time_in_rem | Int? | Total time the sleep phase progressed to rem |
time_in_snoring | Int? | Total time of snoring |
time_in_no_snoring | Int? | Total time of no snoring |
sleep_efficiency | float(0~1 range, decimal points ) | The percentage of time you actually slept during sleep measurement |
wake_ratio | float(0~1 range, decimal points ) | Rate of waking time in the middle during sleep phase |
sleep_ratio | float(0~1 range, decimal points ) | During sleep stage, sleep ratio, not wake |
light_ratio | float(0~1 range, decimal points )? | Rate of light sleep during sleep phase |
deep_ratio | float(0~1 range, decimal points )? | Rate of deep sleep during sleep phase |
rem_ratio | float(0~1 range, decimal points )? | rem sleep ratio |
snoring_ratio | float(0~1 range, decimal points )? | The percentage of time during the sleep phase that there was a snoring section |
no_snoring_ratio | float(0~1 range, decimal points )? | The percentage of time during the sleep phase that there was no snoring. |
waso_count | Int? | The number of times 'wake' occurred during the sleep period |
longest_waso | Int? | The duration of the longest 'wake' during the sleep period |
sleep_cycle_count | Int? | The number of sleep cycles. |
snoring_count | Int? | The number of times snoring occurred. |
Never Slept Session Object
Field | Type | Description |
---|---|---|
id | String | session id |
start_time | String (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_time | String (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_time | String(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
Field | Type | Description |
---|---|---|
id | String | session id |
created_timezone | String | Timezone of session creation (Timezone List) |
start_time | String(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_time | String(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_time | String(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_time | String (YYYY-MM-DDThh:mm:ss+-hh:mm )? | The time it takes to fall asleep after the start of sleep staging |
wake_time | String (YYYY-MM-DDThh:mm:ss+-hh:mm )? | Wake time |
sleep_latency | int (seconds )? | Time to fall asleep |
wakeup_latency | int (seconds )? | The time it takes to wake up and end your sleep measurement |
sleep_efficiency | float (0~1 range, decimal points ) | The percentage of time you actually slept during sleep measurement |
light_latency | int(seconds )? | The time it takes to the first Light after the start of sleep |
deep_latency | int(seconds )? | The time it takes to the first Deep after the start of sleep |
rem_latency | int(seconds )? | The time it takes to the first REM after the start of sleep |
time_in_bed | int (seconds ) | The time from the start of the sleep measurement to the end of the sleep measurement |
time_in_sleep_period | int (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_sleep | int (seconds ) | During sleep measurement time, the time you were actually sleeping This time is divided into three stages: deep,light,and rem |
time_in_wake | int (seconds ) | Wake time during sleep |
time_in_rem | int (seconds )? | Total time the sleep phase progressed to rem |
time_in_light | int (seconds )? | Total time the sleep phase progressed to light |
time_in_deep | int (seconds )? | Total time the sleep phase progressed to deep |
time_in_snoring | int (seconds )? | Total time of snoring |
time_in_no_snoring | int (seconds )? | Total time of no snoring |
wake_ratio | float (0~1 range, decimal points ) | Rate of waking time in the middle during sleep phase |
sleep_ratio | float (0~1 range, decimal points ) | During sleep stage, sleep ratio, not wake |
light_ratio | float (0~1 range, decimal points )? | Rate of light sleep during sleep phase |
deep_ratio | float (0~1 range, decimal points )? | Rate of deep sleep during sleep phase |
rem_ratio | float (0~1 range, decimal points )? | rem sleep ratio |
snoring_ratio | float (0~1 range, decimal points )? | The percentage of time during the sleep phase that there was a snoring section |
no_snoring_ratio | float (0~1 range, decimal points )? | The percentage of time during the sleep phase that there was no snoring. |
waso_count | int? | The number of times 'wake' occurred during the sleep period |
longest_waso | int(seconds )? | The duration of the longest 'wake' during the sleep period |
sleep_cycle_count | int? | The number of sleep cycles |
sleep_cycle | int(seconds )? | The average duration of one sleep cycle |
snoring_count | Int? | 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
orend_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
Field | Type | Description |
---|---|---|
x-api-key | String | API key used to upload data or end session |
x-user-id | String | The user id that created the sleep session |
Body
Field | Type | Description |
---|---|---|
callback_event | String (INFERENCE_COMPLETE ,SESSION_COMPLETE ) | Callback event typeINFERENCE_COMPLETE : If the analysis is completed within 5 or 40 minute incrementsSESSION_COMPLETE : The entire session analysis is complete |
callback_version | String ( V1 ,V2 ,V3 ) | Callback versionV1 : Follows the callback format of v1.0 documentationV2 : Follows the callback format of v2.0V3 : Follows the callback format of the current version |
callback_data | Webhook Data Object | Webhook data |
Callback Data Object in case of INFERENCE_COMPLETE
Field | Type | Description |
---|---|---|
user_id | String | user id |
session_id | String | session id |
seq_num | Int | Order number of the audio data uploaded |
inference_seq_num | Int | Number 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
Field | Type | Description |
---|---|---|
data | Sleep Data Object | The 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
}
}
}
Updated 5 days ago