Reports

Create report

Asleep.createReports()

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

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

Get a single report

Asleep.Reports.report()

var reports: Asleep.Reports?
let sessionId: String

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

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

Get multiple reports

Asleep.Reports.reports()

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

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

// Async
Task {
    do {
        let reportSessions = try await reports?.reports(fromDate: fromDate, toDate: toDate)
    } catch {
        print(error)
    }
}
Property NameTypeDescription
fromDateString (YYYY-MM-DD)View date start
toDateString (YYYY-MM-DD)View date end
orderByAsleep.Model.OrderByDefault value: .descending
Options: .ascending, .descending
DESC: Descending order
ASC: Ascending order
offsetIntDefault value: 0
Number of reports to skip
limitIntDefault value: 20
Maximum number of report (0~100)
completionBlockArray of SleepSessionIf nil, an error occurs
AsleepErrorError Codes

Get average stats

Asleep.Reports.getAverageReport()

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

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

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

Delete report

❗️

Caution: Data Deletion

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

Asleep.Reports.deleteReport()

var reports: Asleep.Reports?
let sessionId: String

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

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

Reanalyze

Reanalyzes a session that has already ended. If you specify an analysis period (start and end time), only that period is reanalyzed. For example, use it when the user corrects the "time they fell asleep ~ time they woke up" after the measurement has ended.

Asleep.Reports.reanalyze()

var reports: Asleep.Reports?
let sessionId: String
let analysisStartTime: Date
let analysisEndTime: Date

// Closure
reports?.reanalyze(sessionId: sessionId,
                   analysisStartTime: analysisStartTime,
                   analysisEndTime: analysisEndTime,
                   completionBlock: { (sessionId: String?, error: Asleep.AsleepError?) in
    if let error {
        print(error)
        return
    }
    if let sessionId {
        // Reanalysis request completed
    }
})

// Async
Task {
    do {
        try await reports?.reanalyze(sessionId: sessionId,
                                     analysisStartTime: analysisStartTime,
                                     analysisEndTime: analysisEndTime)
    } catch {
        print(error)
    }
}

To reanalyze the whole measurement without specifying a period, call it without the time parameters.

// Closure
reports?.reanalyze(sessionId: sessionId, completionBlock: { (sessionId: String?, error: Asleep.AsleepError?) in
    // ...
})

// Async
Task {
    try await reports?.reanalyze(sessionId: sessionId)
}
Property NameTypeDescription
sessionIdStringThe session ID to reanalyze
analysisStartTimeDateStart time of the analysis period
analysisEndTimeDateEnd time of the analysis period. It must be later than analysisStartTime
completionBlockString?The requested session ID on success
Asleep.AsleepError?Error on failure (Error Codes)

Notes

  • reanalyze returns as soon as the reanalysis request is accepted. Get the updated result with report(sessionId:), and check session.state to see whether the analysis has finished.
  • The analysis period is newly determined on every request. If you call reanalyze(sessionId:) without a period, the previously specified period is not kept and the whole measurement is reanalyzed. To keep a period, pass the same period again.
  • The config used to create Reports must have a userId. If it does not, the request is not sent and it fails with reanalyzeFailed.
  • completionBlock is not guaranteed to be called on the main thread. Switch to the main thread when you update the UI.
🚧

Changing the period with a reanalysis does not bring the recording files back.

Recording files are selected when the first analysis completes, against the period analysed at that time, and the files outside that period are deleted then. A reanalysis only sends a request to the server and never touches the files on the device, so recordings that were already deleted do not come back.

  • Widening the period: there are no recordings for the part that was added
  • Moving to a period that does not overlap the first one: there are no recordings at all
  • Narrowing to a part of the first period: only the files that were kept in the first place are available

audio_segments.json still lists a row for every segment of the whole recording; only the file path is empty for the segments that were not kept. An app cannot tell "no recording was ever made here" apart from "the recording was cleaned up".

If you need the recordings for a wider period, request that period when you stop the measurement.

Error codes

AsleepErrorHTTPSDK error code (Beta)Situation
invalidParameter--The start time is later than or equal to the end time (checked before the request)
reanalyzeFailed--The config used to create Reports has no userId
unknown--Network error (in async, the system error is thrown as is)
httpStatus40030400Invalid start or end time
httpStatus40130401Authentication failed
httpStatus40330403No permission to reanalyze
httpStatus40430404Session not found
httpStatus40930409Cannot reanalyze at the moment (reanalysis already in progress, etc.)
httpStatus41030410Data retention period expired
httpStatus42230422The session is still being tracked
httpStatus5xx30500Server error

The SDK error code is the 5-digit code delivered in the errorCode of httpStatus (Beta). For now we recommend branching on the HTTP status code.

🚧

Avoid retrying indefinitely when you receive httpStatus(code: 409).

It can be returned continuously not only while reanalysis is in progress, but also for sessions that cannot be reanalyzed at all. If you retry, fix the number of attempts and the interval.


Data Type

Asleep.Model.Report

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

enum Peculiarity {
    case inProgress
    case neverSlept
    case tooShortForAnalysis
    case tooLongForAnalysis
    case tooManyDefectsInSleepStages
    case noBreathingStability
    case noRealtimePolling
}
Property NameTypeDescription
timezoneStringThe adjusted time zone of the analysis result
e.g. UTC, Asia/Seoul (Timezone List)
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, CLOSED
NEVER_SLEPT: If it is determined that there was no sleep at all during the session measurement time
TOO_SHORT_FOR_ANALYSIS: When the measurement time is too short to conduct a valid analysis (currently less than 20 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
missing_data_ratioFloat (0~1 range, decimal points)The error rate in sleep analysis results due to reasons such as missing audio uploads
sessionAsleep.Model.SessionSession Report information
statAsleep.Model.StatAnalysis Report information
analysisAsleep.Model.Analysis?Information about the period the server analyzed. If the session is still being tracked, the period is not determined yet and this is nil

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 breathStages: [Int]?
    let snoringStages: [Int]?
    let sleepStageProbs: [[Float]]?
    let breathStageProbs: [[Float]]?
    let snoringStageProbs: [[Float]]?
    let measurementStartTime: Date?
    let measurementEndTime: Date?
}

enum State {
    case open
    case closed
    case complete
}
Property NameTypeDescription
idStringSession Id
stateAsleep.Model.StateSleep session state (OPEN, CLOSED, or COMPLETE)
startTimeDateStart time of the analysis period. If no period was specified, it is the same as the measurement start time
endTimeDate?End time of the analysis period. If no period was specified, it is the same as the measurement end time
unexpectedEndTimeDate?If a session fails to proceed and terminate properly due to app crashes or similar issues, and the client later executes initConfig to terminate the session, the time at which this happens is recorded. In this case, the "end_time" is calculated based on the sequence number of the last uploaded audio file. Therefore, if "end_time" is not null, it indicates an abnormal session.
createdTimezoneStringTimezone of session creation (Timezone List)
sleepStagesArray<Int>Sleep stages
-1: error
0 : wake
1 : light
2 : deep
3 : rem
breathStagesArray<Int>Breathing stability stages
snoringStagesArray<Int>Snoring stages
-1: error
0 : no snoring
1 : snoring
sleepStageProbs[[Float]]?Probability values of the sleep stages for each epoch
breathStageProbs[[Float]]?Probability values of the breathing stability stages for each epoch
snoringStageProbs[[Float]]?Probability values of the snoring stages for each epoch
measurementStartTimeDate?The time the measurement (recording) actually started, regardless of the analysis period
measurementEndTimeDate?The time the measurement (recording) actually ended, regardless of the analysis period

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 timeInStableBreath: Int?
    let timeInUnstableBreath: Int?
    let timeInSnoring: Int?
    let timeInNoSnoring: Int?
    let wakeRatio: Float?
    let sleepRatio: Float?
    let remRatio: Float?
    let lightRatio: Float?
    let deepRatio: Float?
    let stableBreathRatio: Float?
    let unstableBreathRatio: Float?
    let snoringRatio: Float?
    let noSnoringRatio: Float?
    let unstableBreathCount: Int?
    let breathingPattern: BreathingPattern?
    let breathingIndex: Float?
    let sleepCycle: Int?
    let sleepCycleCount: Int?
    let sleepCycleTime: [Date]?
    let wasoCount: Int?
    let longestWaso: Int?
    let sleepIndex: Int?
    let snoringCount: Int?
}
Property NameTypeDescription
sleepEfficiencyFloat?The percentage of time you actually slept during sleep measurement
sleepLatencyInt?time it took to fall asleep
sleepTimeDate?The time it takes to fall asleep after the start of sleep measurement
wakeupLatencyInt?The time it takes to wake up and end your sleep measurement
wakeTimeDate?wake up time
lightLatencyInt?The time it takes to the first Light after the start of sleep.
deepLatencyInt?The time it takes to the first Deep after the start of sleep.
remLatencyInt?The time it takes to the first REM after the start of sleep.
timeInWakeInt?wake during sleep
timeInSleepPeriodInt?During sleep measurement time, excluding the time it took from the start of the sleep measurement to fall asleep and the time it took from the wake to the end of the sleep measurement
timeInSleepInt?During sleep measurement time, the time you were actually sleeping
Classified into three stages: deep, light, rem
timeInBedInt?The time from the start of the sleep measurement to the end of the sleep measurement
timeInRemInt?Total time the sleep phase progressed to rem
timeInLightInt?Total time the sleep phase progressed to light
timeInDeepInt?Total time the sleep phase progressed to deep
timeInStableBreathInt?Total time of stable breathing
timeInUnstableBreathInt?Total time of unstable breathing
timeInSnoringInt?Total time of snoring
timeInNoSnoringInt?Total time of no snoring
wakeRatioFloat?Rate of waking time in the middle during sleep stage
sleepRatioFloat?The percentage of time you sleep without waking during the sleep phase
remRatioFloat?Rate of REM sleep during sleep stage
lightRatioFloat?Rate of light sleep during sleep stage
deepRatioFloat?Rate of deep sleep during sleep stage
stableBreathRatioFloat?The percentage of time during the sleep phase that breathing was stable
unstableBreathRatioFloat?The percentage of time during the sleep phase that breathing was unstable
snoringRatioFloat?The percentage of time during the sleep phase that there was a snoring section
noSnoringRatioFloat?The percentage of time during the sleep phase that there was no snoring.
unstableBreathCountInt?The number of times unstable breathing occurred
breathingPatternAsleep.Model.BreathingPattern?Breathing pattern (STABLE_BREATH, MILDLY_UNSTABLE_BREATH, MODERATELY_UNSTABLE_BREATH, SEVERELY_UNSTABLE_BREATH)
breathingIndexFloat?Breathing index
sleepCycleInt?The average duration of one sleep cycle.
sleepCycleCountInt?The number of sleep cycles.
sleepCycleTime[Date]?Transition time for sleep cycles
[First sleep cycle onset time, first sleep cycle end time, second sleep cycle end time, ..., last sleep cycle end time]
wasoCountInt?The number of times 'wake' occurred during the sleep period
longestWasoInt?The duration of the longest 'wake' during the sleep period
sleepIndexInt?The metric that comprehensively represents sleep quality, defined by learning from the distribution of sleep data
snoringCountInt?The number of times snoring occurred

Asleep.Model.Analysis

struct Analysis {
    let startEpochIndex: Int
    let endEpochIndex: Int
    let epochDurations: [Int]
    let totalEpochCount: Int

    var epochCount: Int { get }
    func contains(seq: Int) -> Bool
}
Property NameTypeDescription
startEpochIndexIntThe index of the first epoch of the analysis period (based on the whole measurement, inclusive)
endEpochIndexIntThe index after the last epoch of the analysis period (exclusive)
epochDurationsArray<Int>The duration (in seconds) of each epoch in the period. If the period boundaries do not match the epoch boundaries, the first and last values can be less than 30
totalEpochCountIntThe number of epochs of the whole measurement
epochCountIntThe number of epochs included in the period
contains(seq:)BoolWhether the epoch index seq, based on the whole measurement, is included in the analysis period
🚧

When an analysis period is specified, the index of the stage array is not based on the start of the measurement.

sleepStages[i] is the (startEpochIndex + i)-th epoch (30 seconds) of the whole measurement. Add startEpochIndex when you calculate a time from an array index or match it with a recording file.

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 NameTypeDescription
sessionIdStringSleep session ID
stateAsleep.Model.StateStatus of Session
'OPEN': An in-progress session, with audio uploads available
'CLOSED': The session terminated by sending an end session request. Unable to upload audio files. Analysis of uploaded sleep audio is still in progress
'COMPLETE': All sleep analysis completed after the end of the session
sessionStartTimeDateSession start time
sessionEndTimeDate?Session end time
createdTimezoneStringTimezone of session creation (Timezone List)
unexpectedEndTimeDate?If a session fails to proceed and terminate properly due to app crashes or similar issues, and the client later executes initConfig to terminate the session, the time at which this happens is recorded. In this case, the "end_time" is calculated based on the sequence number of the last uploaded audio file. Therefore, if "end_time" is not null, it indicates an abnormal session.
lastReceivedSeqNumInt?The sequence number of the last uploaded audio file
timeInBedInt?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 NameTypeDescription
periodAsleep.Model.PeriodTimezone (Timezone List)
peculiarities\[Asleep.Model.Peculiarity]Special considerations when calculating the average of sleep sessions
NO_BREATHING_STABILITY: When the customer's contract conditions do not support breathing stability analysis
averageStatsAsleep.Model.AverageStats?An object containing the averages of sleep metrics for "sleptSessions"
neverSleptSessions\[Asleep.Model.NeverSleptSession]A list of sessions during which it is determined that no sleep occurred at all during the measurement time.
sleptSessions\[Asleep.Model.SleptSession]A list of sessions during which it is determined that sleep occurred during the measurement time.

Asleep.Model.Period

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

Asleep.Model.AverageStats

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

Asleep.Model.NeverSleptSession

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

Asleep.Model.SleptSession

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

Did this page help you?