Product Registration (v3.3.0)

When you upgrade from 3.2.0 to 3.3.0, there are only two things you have to change.

  1. Add productInfo (the device info) to the Asleep.setup() call.
  2. After you confirm that setup has finished (onComplete), proceed in the order initAsleepConfig → start tracking.

The rest of the code is the same as 3.2.0 — starting and stopping tracking, getting reports, and so on.

🚧

Call setup only once per app launch.

If you call setup again on every init result, tracking callback or screen refresh, setup ↔ init can repeat. Do not call it again right inside the failure callback: retry 13000 after a while, and do not retry 13400.

[App launch]
   │
   ① Asleep.setup(context, apiKey, productInfo)  ← only once per app launch. Registers the device
   │     ├ Failure → 13000 (retry after a while) / 13400 (check the input values and the key, do not retry)
   │     └ onComplete()
   │
   ② Asleep.initAsleepConfig(context, apiKey, userId)  ← existing code
   │     └ onSuccess(userId, asleepConfig)
   │
   ③ Start tracking   ← existing code. The session created here is linked to the device
   │
   ④ Stop tracking    ← existing code

1. Upgrade the SDK version

Upgrade the dependency version in build.gradle.

implementation 'ai.asleep:asleepsdk:3.3.0'

2. Prepare the ProductInfo

Prepare the three values that describe the device.

ItemDescriptionConstraint
modelProduct model name (e.g. "model-123")1~100 characters
identifierTypeThe kind of value that identifies the deviceSERIAL or MAC_ADDRESS
identifierValueThe actual serial number or MAC address1~255 characters
import ai.asleep.asleepsdk.Asleep
import ai.asleep.asleepsdk.data.ProductInfo

val productInfo = ProductInfo(
    model = "model-123",                                    // Product model name (≤100 characters)
    identifierType = Asleep.ProductIdentifierType.SERIAL,   // SERIAL or MAC_ADDRESS
    identifierValue = deviceSerial                          // The unique value of the device (≤255 characters)
)
🚧

Please make sure of the following

  • identifierValue has to be unique per device and must not change. The server distinguishes devices by this value.
  • Always pass it in the same format. The SDK does not convert the value; it compares and sends it as it is. If the letter case, the separator (: / -) or a leading or trailing space differs even slightly, it treats it as a different device and sends a new registration request. For example, AA:BB:CC:DD:EE:FF and aa-bb-cc-dd-ee-ff.
  • Enter the correct model when you register for the first time. Even if you register again with the same identifier value and only a different model, the model name stored on the server does not change.
  • An empty value or a value that exceeds the length fails with a 13400 error right away, without a server request.

3. Add productInfo to setup

Call setup once per app launch (before you start tracking), with the same productInfo every time.

  • First run: it registers the device with the server.
  • From the second run: it uses the registration information stored on the device, so it completes immediately without a registration request.

Once the registration is finished, the SDK automatically attaches the device information to requests such as session creation and data upload. There is nothing for the app to do.

3.2.0

Asleep.setup(context = applicationContext, apiKey = apiKey, asleepSetupListener = setupListener)

3.3.0 — only productInfo is added.

val setupListener = object : Asleep.AsleepSetupListener {
    override fun onComplete() {
        // Device registration finished — record the completed state and connect the user (initAsleepConfig)
    }

    override fun onFail(errorCode: Int, detail: String) {
        when (errorCode) {
            13000 -> { }   // Temporary failure — call setup again after a while, for example with a retry button
            13400 -> { }   // Rejected — check productInfo / API Key (do not retry)
            else  -> { }   // Others (e.g. 11000 empty API Key, 11004 invalid baseUrl)
        }
    }

    override fun onProgress(progress: Int) { }
}

Asleep.setup(
    context = applicationContext,
    apiKey = apiKey,
    asleepSetupListener = setupListener,
    productInfo = productInfo
)
📘

If you were calling only initAsleepConfig without setup in 3.2.0, add setup as shown above and change the order so that your existing initAsleepConfig is called after you confirm that setup has finished. That is the only change.

setup results

ResultMeaningWhat the app should do
Complete (onComplete)Device registration finished (or passed through with the stored registration information)Connect the user (initAsleepConfig)
13000Temporary failure — network error, server error. This is the result after the SDK has already retried 3 timesCheck the network and call setup again after a while
13400Rejected — invalid input, API Key error, no permission to registerDo not retry. Check productInfo and the API Key. If it is not resolved, contact Asleep
11000The API Key is an empty stringCheck the API Key
  • If it fails, the completion callback is not called.
  • Do not call setup again right inside the failure callback. If the cause remains, failure → call again repeats endlessly.
  • The detail that comes with an error is for checking the cause and its wording can change. Branch on the error code.

Good to know

  • The first registration can take time. It usually finishes quickly, but if the server does not respond and all retries are used, the failure callback comes after about 1 minute 30 seconds at most. We recommend showing a loading indicator on the screen that waits for setup.
  • Call setup only once per app launch. If you call it on every init result, tracking callback or screen refresh (onResume, redrawing the screen, and so on), it completes immediately from the second call, so setup ↔ init can repeat rapidly. The only exception is when the connected device has changed.
  • Calling setup again while setup is in progress is ignored. In this case no callback is called.
  • Calling setup during tracking is ignored as well. No callback is called in this case either, so call setup before you start tracking.
  • If you call setup in Application.onCreate, it also runs in the service process used for tracking (:AsleepService). It is normal that onComplete is not called in that process, so decide whether it is finished from the callback in the main process.

4. Connect the user — initAsleepConfig after setup is confirmed

Call your existing initAsleepConfig after you confirm that setup has finished. The parameters are the same as in 3.2.0.

  • Even if init fails, do not call setup again. The device registration is already finished, so you only need to try initAsleepConfig again.
private var isSetupCompleted = false
private var config: AsleepConfig? = null

private val setupListener = object : Asleep.AsleepSetupListener {
    override fun onComplete() {
        isSetupCompleted = true
        connectUser()
    }
    override fun onFail(errorCode: Int, detail: String) { /* See section 3 */ }
    override fun onProgress(progress: Int) { }
}

private val configListener = object : Asleep.AsleepConfigListener {
    override fun onSuccess(userId: String?, asleepConfig: AsleepConfig?) {
        config = asleepConfig   // Used for tracking and reports
    }
    override fun onFail(errorCode: Int, detail: String) {
        // Do not call setup again. If needed, retry connectUser() only
    }
}

private fun connectUser() {
    if (!isSetupCompleted) return
    Asleep.initAsleepConfig(
        context = applicationContext,
        apiKey = apiKey,
        userId = userId,
        asleepConfigListener = configListener
    )
}

5. Start and stop tracking — the existing code as it is

The code for starting and stopping tracking is the same as in 3.2.0. Just make sure of the following two things.

  • Start tracking after setup is complete and the user is connected successfully. The session is linked to the device the moment it is created.
  • If the connected device has changed (a different serial number), stop tracking and then call setup again with the new productInfo. The sessions created after that are linked to the new device.

📘

3.3.0 also adds a Token method that authenticates with the app credentials (appId · appSecret) instead of the API Key. It is a separate feature from Product registration. For details, see the Setup page.


Did this page help you?