Setup

Call it after the app launches and before you start sleep tracking, and call Asleep.initAsleepConfig() after you receive onComplete().

Asleep.setup(context, apiKey, asleepSetupListener, productInfo)   ← passes the authentication info and the device info
   └ onComplete()
        └ Asleep.initAsleepConfig(context, apiKey, userId, asleepConfigListener)
             └ onSuccess(userId, asleepConfig)
                  └ createSleepTrackingManager → startSleepTracking
                     or beginSleepTracking

If you do not pass productInfo, it works exactly the same as before (3.2.0).

To use Product registration, you have to pass productInfo to setup.


Setup

Asleep.setup()

val productInfo = ProductInfo(
    model = "MODEL_NAME",
    identifierType = Asleep.ProductIdentifierType.SERIAL,
    identifierValue = "SERIAL_NUMBER"
)

Asleep.setup(
    context = applicationContext,
    apiKey = "YOUR_API_KEY",
    baseUrl = null,
    callbackUrl = null,
    service = null,
    asleepSetupListener = object : Asleep.AsleepSetupListener {
        override fun onComplete() { }
        override fun onProgress(progress: Int) { }
        override fun onFail(errorCode: Int, detail: String) { }
    },
    productInfo = productInfo
)
Parameter NameTypeDescription
contextContextEnter ApplicationContext
apiKeyStringEnter the value issued by Generate API key
baseUrlString?If null, use the default server, enter the proxy server address
callbackUrlString?Enter the url of the server to receive sleep session analysis results
serviceString?your app name
asleepSetupListenerAsleepSetupListener?listener to receive the setup result
productInfoProductInfo?Device (Product) information. If you pass it, the device is registered during setup. See Product Registration below

Token authentication

Instead of an API Key you can authenticate with app credentials (appId and appSecret). Every API after setup works the same way regardless of which method you use.

Asleep.setup(
    context = applicationContext,
    appId = "YOUR_APP_ID",
    appSecret = "YOUR_APP_SECRET",
    asleepSetupListener = asleepSetupListener,
    productInfo = productInfo
)
ParameterTypeDescription
contextContextApplication context
appIdStringApp ID issued from the dashboard
appSecretStringApp Secret issued from the dashboard
isTestEnvironmentBoolean?Set to true only when using the test environment. Default null
baseUrlString?Uses the default server when null
callbackUrlString?Server URL to receive the sleep session analysis result
serviceString?Application name
asleepSetupListenerAsleepSetupListener?Listener that receives the setup result
productInfoProductInfo?Device (Product) information. See Product Registration below

Differences from the API Key method

ItemAPI KeyToken
Authentication headerx-api-keyAuthorization: Bearer
Token refreshNoneRefreshed automatically by the SDK (5 minutes before expiry)
Authentication failure (401)Error callbackReissued automatically and retried
Credential storage-EncryptedSharedPreferences (AES256)
  • onFail(11000) is called immediately when appId or appSecret is an empty string.
  • Both methods share the same re-entrancy guard. A Token setup is ignored while an API Key setup is in progress.
  • Token failures are reported as 1200012003. See the error codes below.
CodeNameDescription
12000ERR_TOKEN_ISSUE_FAILEDFailed to issue the token
12001ERR_TOKEN_REFRESH_FAILEDFailed to refresh the token
12002ERR_TOKEN_INVALID_CREDENTIALSInvalid appId or appSecret
12003ERR_TOKEN_NETWORK_ERRORNetwork error during a token request

Asleep.AsleepSetupListener

interface AsleepSetupListener {
    fun onComplete()
    fun onProgress(progress: Int)
    fun onFail(errorCode: Int, detail: String)
}
  • onComplete() : It is called when setup is finished. If you passed productInfo, it is called only after the device registration is finished.
  • onFail(errorCode, detail) : It is called when setup fails. In this case onComplete() is not called.
    • detail is a string for checking the cause (logging). Your app logic must branch on errorCode.
  • onProgress(progress) : It is not called during Product registration. You can leave it empty.

Call rules

CaseBehavior
Calling setup again while setup is in progressIt is ignored (e.g. W setup is already in progress; this call is ignored, no callback). Call it after you receive onComplete / onFail. Calling it inside the callback is fine
Calling setup during sleep trackingIt is ignored (no callback). Call it after the tracking has ended
apiKey is an empty stringonFail(11000) immediately
baseUrl has an invalid formatonFail(11004) immediately

Product Registration

Product registration is a feature that registers the device the SDK runs on with the Asleep server. Once registered, the server records which session was measured on which device.

  • There is no separate API. The device is registered when you pass productInfo to setup.
  • If the registration succeeds, the SDK stores the registration information on the device and automatically includes it in requests such as session creation and data upload from then on. There is no value for the app to handle.
  • If you call setup without productInfo, no registration request is sent.

ProductInfo

data class ProductInfo(
    val model: String,
    val identifierType: Asleep.ProductIdentifierType,
    val identifierValue: String
)

enum class ProductIdentifierType { SERIAL, MAC_ADDRESS }
Parameter NameTypeDescription
modelStringProduct model name (1~100 characters)
identifierTypeProductIdentifierTypeThe kind of value that identifies the device. SERIAL (serial number) or MAC_ADDRESS (MAC address)
identifierValueStringSerial number or MAC address (1~255 characters)
🚧

Please make sure of the following

  • Use a value for identifierValue that is unique per device and does not change.
  • Always pass it in the same format. The SDK does not convert letter case, separators (: / -) or leading and trailing spaces, and if the string differs even slightly it treats it as a different device and sends a new registration request.
  • An empty value, a value with only spaces, or a value that exceeds the length fails with onFail(13400) without a server request.

How it works

If you pass productInfo, the device registration becomes a step of setup, and the remaining steps proceed only after the registration is finished.

Asleep.setup(context, apiKey, asleepSetupListener, productInfo)
 │
 ├ ① Check the stored registration information
 │    Already registered with the same API Key and the same productInfo → pass through without a registration request
 │
 ├ ② Check the input values
 │    model / identifierValue conditions violated → onFail(13400)
 │
 ├ ③ Send a registration request to the server
 │    Network error or server error → retry up to 3 times after 2, 4 and 8 seconds
 │
 └ ④ Success → (the remaining setup steps) → onComplete()
      Failure → onFail(13000 or 13400)
CaseBehavior
First runIt registers with the server and stores the registration information
From the next run (same API Key, same productInfo)It passes through without a registration request
productInfo changed (e.g. the connected device changed)It registers again with the new productInfo. If it succeeds, the sessions created after that are recorded with the new device
API Key changedIt deletes the existing registration information and registers again with the new API Key
Reinstalled after deleting the appThe stored registration information is deleted as well, so it registers again on the next setup

Call setup with the same productInfo every time the app launches. From the second run it passes through without a registration request.

Time taken

Registration is a step that pauses and resumes setup, so the final callback is delayed when the network is in a bad state.

  • A device that is already registered: it passes through without a registration request.
  • First registration: it usually finishes with a single request.
  • When the server does not respond and every retry is spent: onFail(13000) is called after about 90 seconds with the API Key method, or after about 3 minutes with the Token method, which sends two requests per attempt (HTTP timeout 10 seconds, up to 4 attempts, backoff total 14 seconds).
  • A 4xx rejection is not retried, so it finishes within one round trip.

We recommend showing a loading screen right after the setup call.

When to start tracking

Which device a session was measured on is determined when the session is created.

  • Always start tracking after you receive onComplete().
  • If you receive onFail(13xxx), setup is not complete. Do not start the tracking. Solve the cause and call setup again.
  • setup is ignored during sleep tracking. If the connected device has changed, call setup with the new productInfo after the tracking has ended.

Stored information

  • The registration information is stored in EncryptedSharedPreferences dedicated to the SDK.
  • The registration information (credential) is not exposed to the app, and the SDK attaches it to requests automatically.

Error codes

A registration failure is delivered through AsleepSetupListener.onFail(), and it is divided into two codes that the app has to handle differently.

CodeNameMeaningWhat the app should do
13000ERR_PRODUCT_REGISTER_FAILEDA temporary failure. Network error, server error (5xx), or too many requests (429). This is the result after the SDK has already retriedGuide the user about the network status and call setup again later
13400ERR_PRODUCT_REGISTER_REJECTEDRejected. Invalid input (400), authentication failure (401), no permission to register (403), or a client-side pre-validation failure. Retrying gives the same resultCheck productInfo and the API Key
⚠️

detail is for checking the cause (logging) and its wording can change without notice.

Branch your app logic on the code (13000 / 13400).


Example

class SleepSdkController(private val context: Context) {

    private val productInfo = ProductInfo(
        model = "MODEL_NAME",
        identifierType = Asleep.ProductIdentifierType.SERIAL,
        identifierValue = deviceSerial
    )

    private val setupListener = object : Asleep.AsleepSetupListener {
        override fun onComplete() {
            // It is called only after the device registration is finished.
            Asleep.initAsleepConfig(
                context = context,
                apiKey = "YOUR_API_KEY",
                userId = userId,
                asleepConfigListener = configListener
            )
        }

        override fun onProgress(progress: Int) { }

        override fun onFail(errorCode: Int, detail: String) {
            when (errorCode) {
                13000 -> {
                    // Temporary failure - check the network and call setup again after a while
                }
                13400 -> {
                    // Rejected - check productInfo / API Key (the result is the same if you try again)
                }
            }
        }
    }

    private val configListener = object : Asleep.AsleepConfigListener {
        override fun onSuccess(userId: String?, asleepConfig: AsleepConfig?) {
            // Now you can start the tracking.
        }

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

    fun start() {
        Asleep.setup(
            context = context.applicationContext,
            apiKey = "YOUR_API_KEY",
            asleepSetupListener = setupListener,
            productInfo = productInfo
        )
    }
}

Did this page help you?