send_auth_url login API to reduce this friction. With send_auth_url, your app can send a partner-owned authentication URL (based on its existing device-code or token issuance flow) to the user’s Meta Horizon mobile app. Meta Horizon OS forwards the URL to the user’s phone with the short-lived code pre-populated, so the user can complete authentication and consent on mobile without manually retyping or remembering the code. Your app then finalizes login on the headset using its existing device-code or token issuance flow.send_auth_url when:send_auth_url(auth_url) API.com.meta.horizon.platform.sdk:core-kotlincom.meta.horizon.platform.sdk:users-kotlinsend_auth_url allows apps to initiate a login flow using the Meta Horizon mobile app. The provided auth_url is delivered to the user’s Horizon mobile app and opened when the user taps the notification. This is the verification_uri per the OAuth 2.0 Device Authorization Grant.| Parameter | Type | Description |
|---|---|---|
auth_url | string | Your verification_uri (HTTPS URL) that, when opened on mobile, lets the user authenticate and approve the headset login. In an OAuth 2.0 Device Authorization Grant (RFC 8628) flow, this typically corresponds to your verification_uri or verification_uri_complete and includes the short-lived user_code (for pre-population on mobile). Example pattern: https://amazon.com/code?user_code=...&client=QuestAPI |
Intent that must be launched (for example, through ActivityResultLauncher) to show the confirmation dialog and complete delivery of auth_url to mobile.import com.meta.horizon.platform.sdk.users.Users
import kotlinx.coroutines.launch
// Somewhere in your login UI handler
onLoginWithHorizon = {
coroutineScope.launch {
val users = Users()
// Example only (do NOT hardcode in production):
// https://partner.example.com/device?code=ABC123
//
// The user_code is effectively a nonce and must be generated server-side
// per login attempt (RFC 8628 S3.2).
val authUrl = getAuthUrlWithUserCode()
val intent = users.send_auth_url(authUrl)
activityLauncher?.launch(intent)
?: error("Activity launcher not initialized")
}
}
/**
* 3P-defined helper that fetches a freshly-generated device/user code from the 3P backend
* and returns the full verification URL to show to the user.
*
* RFC 8628 S3.2: https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
*/
suspend fun getAuthUrlWithUserCode(): String {
val response: DeviceCodeResponse = fetchDeviceCodeFrom3PBackend()
return "${response.verification_uri}?code=${response.user_code}"
}
// Example response shape (align to whatever your backend returns).
data class DeviceCodeResponse(
val verification_uri: String,
val user_code: String,
)
/**
* Replace this with your real network call to your 3P backend service.
* This is intentionally not implemented in the sample.
*/
suspend fun fetchDeviceCodeFrom3PBackend(): DeviceCodeResponse {
TODO("Call your 3P backend to generate user_code/device_code and return verification_uri + user_code")
}
| Error | Meaning | Recommended UX |
|---|---|---|
OK | Request sent successfully | Continue login flow; show “Check your phone” |
USER_CANCELLED | User declined in confirmation dialog | Keep user on login screen; allow retry |
NETWORK_ERROR | Transient network failure | Show a network error with a retry option |
FORBIDDEN | Server denied request | Show user-facing error and fallback options |
INVALID_URL (2005) | URL is malformed or invalid | Log error; regenerate URL; ensure HTTPS |
TOO_MANY_REQUESTS | Throttled | Back off and retry; avoid spamming the API |
user_code and device_code values.auth_url query parameters.uses-horizonos-sdk stanza and set horizonos:minSdkVersion (and typically horizonos:targetSdkVersion) to the minimum version that includes the login capability. For example:<manifest xmlns:horizonos="http://schemas.horizonos/sdk">
<horizonos:uses-horizonos-sdk
horizonos:minSdkVersion="83"
horizonos:targetSdkVersion="83" />
...
</manifest>