Migrate to Meta XR Platform SDK v203 or later
Updated: Nov 2, 2026
Meta XR Platform SDK v203 and later run on a new platform runtime, and v201 is the last version on the previous runtime. The package name (com.meta.xr.sdk.platform), the Oculus.Platform namespace, and the OculusPlatformSettings asset stay the same, and the APIs this page does not list compile unchanged, including Core.AsyncInitialize(), Core.IsInitialized(), Request.OnComplete(), Message.IsError, and Message.GetError(). In v203 and v205, awaiting Core.AsyncInitialize() never completes. See Troubleshooting. This page walks you through the changes to make when you move a Unity app from v201 to v203 or later. Steps 2 to 6 apply only if your code uses the affected APIs.
- A Unity project that uses Meta XR Platform SDK v201.
- App IDs set in your platform settings. See Set up for platform development with Unity.
- A Meta Horizon OS device for testing.
- A user account that is entitled to your app, for the entitlement check in step 8.
- Meta Horizon Link installed if you test on PC or in the Editor. See Use Link for app development.
Update
com.meta.xr.sdk.platform to v203 or later in Package Manager. Use the latest version, because v207 and later avoid the
await Core.AsyncInitialize() issue described in Troubleshooting. See
Meta XR UPM packages. The new package depends on
com.unity.nuget.newtonsoft-json, and Package Manager installs it for you. The Editor adds the required Horizon OS entry to your Android manifest when you build, so you do not need to edit the manifest.
After the update, Package Manager lists the new version and the com.unity.nuget.newtonsoft-json package.
2. Replace direct CAPI calls
The Oculus.Platform.CAPI class and its ovr_* functions are removed. Replace each direct CAPI call with the matching public API.
For example, replace new LaunchDetails(CAPI.ovr_ApplicationLifecycle_GetLaunchDetails()) with ApplicationLifecycle.GetLaunchDetailsRequest(), which returns Request<LaunchDetails>. The synchronous ApplicationLifecycle.GetLaunchDetails() is deprecated: it logs a warning, blocks for up to 2 seconds, and returns null if the request fails or times out. If your code already calls ApplicationLifecycle.GetLaunchDetails(), move it to GetLaunchDetailsRequest() too.
When you finish, your project compiles with no references to CAPI.
3. Remove Message.Type checks
Message.Type is marked obsolete as an error, so any code that reads it fails to compile. Remove these checks. The OnComplete callback guarantees the correct message type. If you need the type, read Message<T>.DataType instead.
When you finish, your project compiles with no references to Message.Type.
4. Update Core.Initialize error handling
In v201, Core.Initialize() returned void and threw UnityException on failure. In v203 and later, it returns a HorizonStatus and throws HorizonException or one of its subclasses, such as HorizonRequestNotSupportedException, when initialization fails. It still throws UnityException when no App ID is set. Because it throws on failure, you do not need to check the returned HorizonStatus, and existing calls written as a statement still compile.
Update these parts of your code:
- Add
catch blocks for HorizonException around Core.Initialize(). Keep any catch block for UnityException, which still reports a missing App ID. - On PC and in Play mode in the Editor, also catch
NotSupportedException. See Troubleshooting. - If your code uses
await Core.AsyncInitialize(), see Troubleshooting.
5. Replace removed or renamed APIs
Update each of the following APIs from v201:
AndroidPlatform and WindowsPlatform: removed. Call Core.Initialize(appId) or Core.AsyncInitialize(appId) instead.StandalonePlatform: obsolete. Code that uses it produces a compiler warning but still compiles. Call Core.Initialize() or Core.AsyncInitialize() instead, and enable Use Standalone Platform in your platform settings for Play mode in the Editor.Users.GetLoggedInUserLocale(): always returns an empty string and has no replacement. Code that uses it produces a compiler warning but still compiles. Remove the call and any code that depends on its result.- Synchronous
Voip methods with a ...Request() twin: supported, but discouraged. These include Voip.Start(), Voip.Accept(), Voip.Stop(), and Voip.SetMicrophoneMuted(). They compile with no warning, but each call logs a warning and blocks the calling thread for up to 2 seconds. A method that returns a value returns the default value if the request fails or times out. Call the matching ...Request() method instead, such as Voip.StartRequest(), Voip.AcceptRequest(), or Voip.StopRequest(), and await it or handle it with OnComplete(). Notifications.MarkAsRead, Voip.SetMicrophoneFilterCallback, Voip.SetSystemVoipStateNotificationCallback, Voip.SetSystemVoipSuppressed, and the Vrcamera class: removed with no replacement. Remove these calls.Livestreaming.SetStatusUpdateNotificationCallback: renamed. Call Livestreaming.SetStatusChangeNotificationCallback instead.- Model members deprecated in favor of an
Optional twin: removed. Use the twin. For example, replace LeaderboardEntry.SupplementaryMetric with LeaderboardEntry.SupplementaryMetricOptional.
When you finish, your project compiles with no errors or warnings from these APIs, and a project search finds no calls to the synchronous Voip methods.
6. Move Rich Presence code to Group Presence
The
RichPresence class is deprecated in favor of Group Presence, as it was in v201. It has no
[Obsolete] attribute, so the compiler shows no warning. Search your project for
RichPresence and move each call to
GroupPresence. For example, replace
RichPresence.GetDestinations() with
GroupPresence.GetDestinations(). See
Group Presence overview.
When you finish, a project search for RichPresence returns no matches.
7. Check which App ID the Editor uses
Open the platform settings from the menu for your version:
- v203 to v205: Meta > Platform > Edit Settings
- v207 and later: Window > Meta > Platform > Edit Settings
Confirm that Use Standalone Platform matches the App ID you want to test with in the Editor. In the Editor and on PC, this setting selects the App ID:
- Checked: the SDK uses the Meta Quest App ID.
- Unchecked: the SDK uses the Rift App ID. If the Rift App ID is empty, initialization throws
UnityException.
Checking Use Standalone Platform also switches Play mode in the Editor to the standalone platform, which signs in with the Test User Email and Test User Password fields in the same panel and supports fewer features. If your app has only a Meta Quest App ID, check Use Standalone Platform and sign in with a test user to test in Play mode, or test on a Horizon OS device. Unlike in v201, the setting also applies to PC builds, but the test user credentials are stored only in the Editor, so initialization fails in a PC build. Uncheck Use Standalone Platform before you build for PC. An App ID that you pass to Core.Initialize(appId) or Core.AsyncInitialize(appId) overrides the App ID from your settings.
The Use Meta Quest App ID over Rift App ID in Editor setting no longer controls the App ID. On a Horizon OS device, the SDK always uses the Meta Quest App ID.
8. Verify with an entitlement check
Entitlements.IsUserEntitledToApplication() keeps the same signature. Build and run your app if it already calls this method. Otherwise, import the Entitlement Check sample from the Samples tab of the package in Package Manager and run the sample. The sample is included in the Meta XR Platform SDK package, and the following excerpt is from it:
if (!Oculus.Platform.Core.IsInitialized())
{
Oculus.Platform.Core.Initialize();
}
Entitlements.IsUserEntitledToApplication().OnComplete(EntitlementCheckCallback);
EntitlementCheckCallback is the sample’s own handler, which receives the
Message. In the sample, this code runs inside a
try block whose
catch treats any initialization exception as a failed entitlement check. Run the check on a Horizon OS device. The check passes when the callback runs and
Message.IsError is
false. See
Entitlement check for Meta Store apps. Also run each feature whose code you changed in Steps 2 to 6 on a Horizon OS device.
Awaited Core.AsyncInitialize() call never completes
Symptom: In v203 and v205, await Core.AsyncInitialize() never returns.
Solution: Call Core.AsyncInitialize().OnComplete(...) with a Message<PlatformInitialize> callback instead of await, or update to v207 or later.
NotSupportedException on PC or in Play mode in the Editor
Symptom:Core.Initialize() throws NotSupportedException with a message about the Meta Horizon Link runtime. If you call Core.AsyncInitialize(), the request never completes and the same message appears in the Console.
Solution: If
Use Standalone Platform is checked, sign in with test user credentials in the platform settings first. Otherwise, your installed Meta Horizon Link is older than v201: update it to the latest version, or keep testing PC features on Meta XR Platform SDK v201 until you can. The message’s advice to switch to the v201 Public Test Channel or wait for v205 dates from before those versions reached the live channel; updating replaces it. In the Editor and on PC, the SDK calls the platform runtime installed with Meta Horizon Link, so the installed version controls which requests work. See
Use Link for app development.
Error code 12 or “Provider not found” on PC
Symptom: A request on PC or in Play mode in the Editor fails with error code 12 and a message that starts with Provider not found.
Solution: The following features have no PC implementation. Test them on a Horizon OS device.
- Device Application Integrity
- Consent
- Media (sharing to Facebook)
- User Data Store (v203 to v209)
With Use Standalone Platform checked, Application Lifecycle, Asset Files, Avatars, Language Packs, and VoIP also return this error.
Notification callbacks are not called on PC
Symptom: Callbacks you register with a Set...NotificationCallback method never fire on PC or in Play mode in the Editor.
Solution: In v203 through v210, the SDK does not deliver notifications on PC or in Play mode in the Editor. Test notifications on a Horizon OS device.