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.
- Add
productInfo(the device info) to theAsleep.setup()call. - After you confirm that
setuphas finished (onComplete), proceed in the orderinitAsleepConfig→ start tracking.
The rest of the code is the same as 3.2.0 — starting and stopping tracking, getting reports, and so on.
Callsetuponly once per app launch.If you call
setupagain on every init result, tracking callback or screen refresh, setup ↔ init can repeat. Do not call it again right inside the failure callback: retry13000after a while, and do not retry13400.
[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 code1. 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.
| Item | Description | Constraint |
|---|---|---|
model | Product model name (e.g. "model-123") | 1~100 characters |
identifierType | The kind of value that identifies the device | SERIAL or MAC_ADDRESS |
identifierValue | The actual serial number or MAC address | 1~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
identifierValuehas 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:FFandaa-bb-cc-dd-ee-ff.- Enter the correct
modelwhen you register for the first time. Even if you register again with the same identifier value and only a differentmodel, the model name stored on the server does not change.- An empty value or a value that exceeds the length fails with a
13400error 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 onlyinitAsleepConfigwithoutsetupin 3.2.0, addsetupas shown above and change the order so that your existinginitAsleepConfigis called after you confirm that setup has finished. That is the only change.
setup results
| Result | Meaning | What the app should do |
|---|---|---|
Complete (onComplete) | Device registration finished (or passed through with the stored registration information) | Connect the user (initAsleepConfig) |
13000 | Temporary failure — network error, server error. This is the result after the SDK has already retried 3 times | Check the network and call setup again after a while |
13400 | Rejected — invalid input, API Key error, no permission to register | Do not retry. Check productInfo and the API Key. If it is not resolved, contact Asleep |
11000 | The API Key is an empty string | Check the API Key |
- If it fails, the completion callback is not called.
- Do not call
setupagain right inside the failure callback. If the cause remains, failure → call again repeats endlessly. - The
detailthat 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
setuponly 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
setupagain while setup is in progress is ignored. In this case no callback is called. - Calling
setupduring tracking is ignored as well. No callback is called in this case either, so call setup before you start tracking. - If you call
setupinApplication.onCreate, it also runs in the service process used for tracking (:AsleepService). It is normal thatonCompleteis 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
setupagain. The device registration is already finished, so you only need to tryinitAsleepConfigagain.
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
setupagain with the newproductInfo. 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.
Updated about 2 hours ago
