Instant Games

Migrating to Network Enabled Zero Permissions

Updated: Sep 9, 2026
Copy for LLM
This guide walks you through migrating an existing, live Instant Game from the standard permissions environment to Network Enabled Zero Permissions (NEZP). It assumes your current production bundle is built on Instant Games SDK v7.1 or earlier and that your game reads player names, photos, and friend data directly from the SDK.
The migration touches six areas: your app’s network connection settings, your access level for Zero Permissions, your SDK version, the player-identifying UI in your game, app review, and the production rollout. You can work through them in order, and nothing you do reaches production players until the final rollout step.
Migration deadline: September 30, 2026
Your game must complete its migration to Network Enabled Zero Permissions by September 30, 2026. If it has not migrated by that date, your game will no longer be accessible to players on Facebook.
App review takes several days and the rollout to 100% is incremental, so plan backwards from this date rather than starting the migration close to it.

Who this guide is for

Use this guide if you have already shipped an Instant Game and want to move it to Zero Permissions. If you are coming from somewhere else, use the guide that matches your starting point instead:
Your starting pointGuide
A live Instant Game on SDK v7.1 or earlier, in the standard environment
This guide
A brand-new Instant Game that has never launched
A Canvas Game, also known as a Legacy Web Game
A native, web, or console game using Facebook Login for Gaming

What changes when you move to NEZP

AspectStandard environment (SDK v7.1 and earlier)Network Enabled Zero Permissions
SDK
fbinstant.7.1.js or earlier
fbinstant.8.0.js
Player name and photo
Returned to your game code by FBInstant.player.getName() and getPhoto()
Not returned to your game. Rendered by Meta inside overlay views
Friend name and photo
Returned by getConnectedPlayersAsync() on each player object
getConnectedPlayersAsync() returns IDs only. Names and photos render in overlay views
Permissions
Advanced permissions such as gaming_profile, gaming_user_picture, and user_friends
No player-facing permissions. One app-level permission, Instant Games Zero Permission Access
Player ID
Game-scoped ID from FBInstant.player.getID()
Unchanged. The same ID for the same player, so progress keyed by it is preserved
External network calls
Allowed from the game iframe
Allowed, but every domain must be declared in your Content Security Policy configuration
Global leaderboards
FBInstant.globalLeaderboards.*
Deprecated. Rejects with DEPRECATED_GLOBAL_LEADERBOARD_ERROR. Use your own backend plus overlay views
Hosting origin
apps-{app-id}.fbsbx.com
shield-apps-{app-id}.fbsbx.com
Your existing player IDs, cloud-storage data, in-app purchase catalog, and product configuration all carry over unchanged. The work is concentrated in the SDK upgrade and in replacing every piece of UI that displays a name or a photo.

Migration at a glance

PhaseWhat you doAffects production players
1. Switch app settings
Select Zero Permissions, confirm data deletion
No
2. Request for Advanced NEZP Access
Request for access via App Review
No
3. Upgrade the build
Move to SDK v8.0 and remove unsupported API calls
No
4. Rebuild the UI
Replace name and photo rendering with overlay views
No
5. Upload and test
Upload a NEZP bundle, mark it, and test it
No
6. App review
Request advanced access to Zero Permissions and pass review
No
7. Roll out
Raise the rollout percentage from 0% to 100%
Yes
Start with the dashboard settings and the access request, because both take time to process and neither depends on your code. The engineering work in phases 3 and 4 can proceed while your access request is pending.

Phase 1: Switch your app to Zero Permissions

Step 1: Select Zero Permissions in Network Connection Settings

  1. Go to the App Dashboard and select your app.
  2. Navigate to Use Cases > Customize “Launch a game on Facebook” > Network Connection Settings > Connection Experience Settings.
    • If Use Cases is not in the sidebar, look for Network Connection Settings under Instant Games.
  3. Select Zero Permissions and confirm.
Connection Experience Settings
This setting does not move any production traffic. It starts the migration and unlocks the NEZP tooling on the Web Hosting page that you need in phase 5.
Note: After you select Zero Permissions, all Platform Test Users default to the Zero Permissions model. If you use test users to validate your current production build, do that before you change this setting.

Step 2: Confirm user data deletion

Under the Facebook Platform Terms, a Zero Permissions game may not attempt to re-identify or de-anonymize players. Before you can roll out, you must attest that you have deleted the identifying data your game previously received from Facebook.
  1. Navigate to Use Cases > Customize “Launch a game on Facebook” > Network Connection Settings > User Data Deletion.
  2. Delete the following from your systems, including backups, logs, and analytics warehouses:
    • Player names
    • Player profile pictures
    • Friend names
    • Friend profile pictures
  3. Keep player IDs and gameplay data. Scores, progress, inventory, and purchase history may all be retained.
  4. Select the confirmation checkbox and save.
You have a 14-day window after the migration begins to complete the deletion. Confirming deletion is also a prerequisite for the rollout control in Phase 7, so do not leave it until the end.

Phase 2: Request advanced access for Zero Permissions

Step 3: Request advanced access to Instant Games Zero Permission Access

Zero Permissions is granted at two levels, and a live game needs both in sequence:
Access levelWhat it covers
Standard access
The Zero Permissions environment is available only to people with a role on the app — admins, developers, and testers. This is what you get by default, and it is enough for all of the development and testing in phases 3 through 5.
Advanced access
The Zero Permissions environment is available to the public. Required before you can raise the rollout above 0%. It also lets your app serve the standard and Zero Permissions environments at the same time while the rollout is partial.
There are two entry points for the request, and the control is labeled differently in each.
From App Review:
  1. Navigate to App Review > Permissions and Features.
    • Direct link: https://developers.facebook.com/apps/YOUR_APP_ID/app-review/permissions/
  2. Find Instant Games Zero Permission Access.
  3. Select Request Advanced Access.
Permissions and Features page showing Zero Permission Access
From Use Cases:
  1. Navigate to Use Cases > Customize “Launch a game on Facebook” > Permissions and features.
    • Direct link: https://developers.facebook.com/apps/YOUR_APP_ID/use_cases/customize/?use_case_enum=INSTANT_GAMES&business_id=YOUR_BUSINESS_ID&selected_tab=permissions&product_route=use_cases
  2. Find Instant Games Zero Permission Access.
  3. Select Actions > Increase access.
Permissions and features list with the Actions menu open on Increase access
Either route adds the request to your App Review submission. It is not reviewed until you submit your game in Phase 6, so raise the request now and continue building while it is pending.

Phase 3: Upgrade your build to SDK v8.0

Step 4: Load the v8.0 SDK

Zero Permissions requires SDK v8.0. Replace the SDK script tag in your index.html:
<!-- Before -->
<script src="https://connect.facebook.net/en_US/fbinstant.7.1.js"></script>

<!-- After -->
<script src="https://connect.facebook.net/en_US/fbinstant.8.0.js"></script>
Load the SDK with a <script> tag rather than injecting it dynamically. The in-game debugging tool only attaches when the SDK is present in the initial HTML.
If you are on a version earlier than v7.1, review the changelogs for each intervening version before you upgrade, because breaking changes accumulate: v6.3, v7.0, v7.1, and v8.0.
Unity developers should upgrade to the current Unity Plugin, which wraps the v8.0 API and includes the Overlay View Builder editor tool.
Your loading lifecycle is unchanged. initializeAsync(), setLoadingProgress(), and startGameAsync() behave the same way they did in v7.1.

Step 5: Remove calls to APIs that NEZP does not support

Search your codebase for the following and replace each one before you upload a bundle.
Removed or deprecatedReplacement
FBInstant.player.getName()
An overlay view that renders {{FBInstant.player.name}}
FBInstant.player.getPhoto()
An overlay view that renders {{FBInstant.player.photo}}
player.getName() and player.getPhoto() on objects from getConnectedPlayersAsync()
Keep getID(), and render the name and photo in an overlay view
FBInstant.globalLeaderboards.setScoreAsync(), getScoreAsync(), getTopEntriesAsync(), and getTopFriendEntriesAsync()
Your own backend leaderboard, rendered with arbitrary player rendering
Any logic that checks whether gaming_profile, gaming_user_picture, user_friends, or email was granted
Delete it. There are no player-facing permissions under Zero Permissions, and no denied-permission states to handle
Any cached copy of a name or photo in your own storage
Delete it as part of Step 2
The removed methods do not throw a catchable error that names the cause — they return undefined or fail silently, which typically surfaces later as a blank label or a broken image. Removing them explicitly is safer than relying on runtime testing to find them.

Step 6: Declare the external domains your game uses

NEZP games run in a sandboxed iframe with a Content Security Policy applied. Any domain your game contacts, or loads assets from, must be added to your app’s CSP configuration first. This includes backend and multiplayer servers, analytics endpoints, ad and attribution SDKs, CDNs, and font hosts.
  1. Go to the App Dashboard and select your app.
  2. Navigate to Instant Games > Content Security Policy.
  3. Add each domain without the https:// prefix or a trailing slash, and select only the directives that domain needs.
All external requests must use HTTPS with a valid certificate. See Content Security Policy for the full list of supported directives and domain requirements.
Note: Overlay views cannot load images from an external CDN, even one on your CSP allowlist. Overlay images must come from your game bundle, a player photo template expression, or a base64 data URL passed in as initial data.

Phase 4: Rebuild player-identifying UI with overlay views

This is the largest engineering task in the migration. Under Zero Permissions your game never receives a player’s name or photo. Instead, you describe the layout in XML, and Meta renders it inside an iframe that your game positions and sizes but cannot read.

Step 7: Inventory every surface that shows player data

Before writing any XML, list every screen in your game that renders a name or a photo. Typical surfaces include:
  • The player’s own avatar and display name in the HUD or profile panel
  • Friend lists and friend pickers
  • Leaderboards, both friend and global
  • Match, lobby, and turn-order UI
  • Gift, challenge, and invite flows
  • Chat and activity feeds
  • Any name or photo baked into a share image
For each surface, note what it displays, whether it needs to react to taps, and how often it updates. Overlays that update every frame are expensive, so plan to separate small dynamic overlays from large static ones.

Step 8: Create your first overlay view

Add the XML and CSS to your game bundle, then create the overlay at runtime and show it.
overlays/profile_card.xml:
<View className="card">
  <Image src="{{FBInstant.player.photo}}" className="avatar" width="48" />
  <View>
    <Text content="{{FBInstant.player.name}}" className="name" />
    <Text content="Score: {{score}}" className="score" />
  </View>
</View>
overlays/styles.css:
.card {
  display: flex;
  align-items: center;
  gap: 12px;
}

.avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
}
In your game code:
var container = document.getElementById('playerCard');

var overlay = await FBInstant.overlayViews.createOverlayViewAsync(
  'overlays/profile_card.xml',
  container,
  'width: 100%; height: 64px; border: none;',
  'overlays/styles.css',
  { score: 1500 }
);

await overlay.showAsync();
The overlay is not visible until you call showAsync().
For the two most common cases — the current player’s photo and the current player’s name — you can skip the XML entirely and use createProfilePictureOverlayViewAsync() and createProfileNameOverlayViewAsync().
Use the overlay preview tool to iterate on XML and CSS in the browser without rebuilding and re-uploading your bundle.

Step 9: Handle taps and updates

Overlay content is inside a Meta-controlled iframe, so your game does not receive DOM events from it. Interactive elements declare an onTapEvent name, and your game listens for it:
<View className="friendRow" onTapEvent="challenge_{{friend.id}}">
  <Image src="{{friend.photo}}" className="avatar" />
  <Text content="{{friend.name}}" className="name" />
</View>
FBInstant.overlayViews.setCustomEventHandler(function(eventStr, overlayID) {
  if (eventStr.startsWith('challenge_')) {
    startChallenge(eventStr.split('_')[1]);
  }
});
To change the data an overlay displays, call updateAsync() and then showAsync() again:
await overlay.updateAsync({ score: 2000 });
await overlay.showAsync();
Keep these performance characteristics in mind, because they differ from ordinary DOM updates:
  • updateAsync() re-renders the whole overlay. There is no incremental patching, and every image is re-fetched. Throttle updates to meaningful state changes rather than calling them each frame.
  • dismissAsync() only hides the overlay. The iframe stays in the DOM with its state intact, which makes it cheap to show again.
  • destroyAsync() frees the overlay. Use it to remove the iframe and release resources for overlays you will not show again. Long sessions that create overlays without destroying them will accumulate memory.
  • Reuse beats recreate. For variable-length lists such as per-player name tags, pre-create a pool at startup and recycle it.

Step 10: Render players who are not the current player

Friend lists and leaderboards use the same mechanism. Fetch the IDs from the SDK or your backend, then pass them to an overlay that renders each one.
var players = await FBInstant.player.getConnectedPlayersAsync();
var ids = players.map(function(p) { return { playerID: p.getID() }; });

var overlay = await FBInstant.overlayViews.createOverlayViewAsync(
  'overlays/friend_list.xml', container, null, 'overlays/styles.css', { players: ids }
);
await overlay.showAsync();
<View>
  <For source="{{players}}" itemName="i">
    <View className="friendRow" onTapEvent="select_{{i.playerID}}">
      <Image src="{{FBInstant.players[{{i.playerID}}].photo}}" className="avatar" />
      <Text content="{{FBInstant.players[{{i.playerID}}].name}}" className="name" />
    </View>
  </For>
</View>
Any player ID works here. The player does not have to be a friend of the current player or share a context with them, which is what makes backend-driven leaderboards and matchmaking UI possible.
For the full component reference, including For, If, Condition, and ConditionGroup, see Overlay View Components. For complete worked examples of each surface listed in Step 7, see Example Game Use Cases and Social Features.

Phase 5: Upload and test the NEZP bundle

Step 11: Upload and mark your NEZP bundle

NEZP is a separate environment with its own active bundle. Uploading a bundle does not change what your production players receive.
  1. Navigate to Use Cases > Customize “Launch a game on Facebook” > Web Hosting.
  2. Toggle Network Enabled Zero Permissions Settings at the top of the page.
  3. Upload your v8.0 bundle as a ZIP file, with index.html and fbapp-config.json at the top level of the archive rather than inside a folder.
  4. Wait for the platform to finish scanning the bundle.
  5. Mark the bundle you want to serve in NEZP with the shield icon.
Your existing production bundle stays exactly where it is and continues to serve every player until you roll out.

Step 12: Test in NEZP

Select Play in NEZP on the Web Hosting page to launch the shield bundle.
Testing your existing app
Concentrate on what NEZP changes:
  • Overlay views. Check every surface from your Step 7 inventory, on more than one account, with both real profile pictures and gaming avatars.
  • Removed APIs. Confirm nothing renders a blank name or a broken image, which is how a leftover getName() or getPhoto() call usually shows up.
  • Network requests. Watch the browser console for CSP violations, and confirm your backend, analytics, and ad calls all succeed.
  • Player identity. Verify that getID() returns the same ID it did before migration and that saved progress loads.
  • Cross-platform. Test on Facebook web, iOS, and Android. Overlay sizing and tap targets are the most common source of platform-specific issues.
A few practical notes when testing:
  • Confirm you are actually in NEZP. In Chrome DevTools, check that index.html is served from shield-apps-{your-app-id}. Without the shield prefix, you are running the standard environment.
  • Give internal testers the Developer role. The NEZP toggle is honored for people with the Admin or Developer role on the app. Someone assigned only the Tester role may still be served the standard environment.
  • Disable the cache while iterating. Bundle JavaScript is cached aggressively. Turn on Disable cache in the DevTools Network panel, or hard-refresh, so you are testing the bundle you just uploaded.
  • Turn on debug mode. The in-game debugging tool includes an overlay view inspector that shows each overlay’s state and resolved data.
For local iteration with the embedded player, see Testing.

Phase 6: Submit for app review

Step 13: Submit your game and your access request

When your NEZP bundle is stable, submit it for review.
Note: This step is optional if your game has already passed EQR.
  1. Go to Instant Games > Review > App Review for Instant Games.
  2. Add your game to the submission.
  3. Confirm that Instant Games Zero Permission Access with advanced access from Step 3 is included in the same submission.
  4. Submit.
Policy Review, Quality Review and In App Purchases Review card with the Create submission button
Review typically takes a few days, and you can keep testing while it is pending. Before submitting, check Instant Games > Launch Status and resolve any outstanding health-check items, such as a missing IARC certificate under Audience Details or incomplete game details.

Phase 7: Roll out to production

Step 14: Unlock the rollout control

Navigate to Network Connection Settings > Zero Permissions Rollout. If the percentage selector is disabled, one of the prerequisites is still outstanding. Select the information icon next to the control to see which one. The full set is:
  • Zero Permissions selected in Connection Experience Settings (Step 1)
  • User data deletion confirmed (Step 2)
  • Instant Games Zero Permission Access approved with advanced access (Step 3)
  • A NEZP bundle uploaded and marked with the shield icon (Step 11)
  • App review complete (Step 13)

Step 15: Increase the rollout percentage

Zero Permissions Users Rollout card with the rollout percentage selector and the permanence warning
  1. In the Zero Permissions Users Rollout card, select a small starting value from Rollout percentage and select Confirm.
  2. Monitor retention, session length, crash rate, purchase conversion, and ad revenue against your pre-migration baseline for long enough to see a real signal.
  3. Increase the percentage in stages until you reach 100%.
Important: Rollout is incremental only. You cannot lower the percentage or roll a migration back, so validate thoroughly at each stage before increasing it.

After you reach 100%

Once the migration completes, the bundle marked with the shield icon becomes your production bundle, and every player is served the Zero Permissions experience. No further action is required.
Your publishing workflow changes slightly from this point on. On the Web Hosting page, use the star icon to load a bundle into the Zero Permissions environment, and Play under Manage Hosted Assets to test it.
The advanced access grant for Zero Permissions also reverts to standard access once the migration is complete, because the app no longer needs to serve both environments at the same time.

Migration checklist

Configure
  • Select Zero Permissions in Connection Experience Settings
  • Delete stored names and photos, and confirm user data deletion
  • Request advanced access to Instant Games Zero Permission Access
Prepare
  • Audit every call to getName(), getPhoto(), and FBInstant.globalLeaderboards.*
  • Inventory every screen that displays a player name or photo
  • List every external domain your game contacts
  • Record a pre-migration baseline for retention, session length, and revenue
Build
  • Upgrade the SDK script tag to fbinstant.8.0.js
  • Remove unsupported API calls and permission-checking logic
  • Add your domains to the Content Security Policy configuration
  • Implement an overlay view for each surface in your inventory
  • Reuse or destroy overlays rather than leaking them
Verify
  • Upload the v8.0 bundle and mark it with the shield icon
  • Confirm the game is served from shield-apps-{app-id}
  • Test every overlay surface on web, iOS, and Android
  • Confirm no CSP violations in the console
  • Confirm player IDs and saved progress are unchanged
  • Confirm purchases and ads still work
Launch
  • Submit for app review with the access request included
  • Resolve all Launch Status health-check items
  • Roll out incrementally, monitoring metrics at each stage
  • Reach 100% and verify the shield bundle is serving production

Troubleshooting

SymptomLikely cause
Names or photos render blank
A leftover getName() or getPhoto() call, or an overlay that was created but never shown with showAsync()
An overlay image never loads
The src points at an external CDN. Overlay images must come from the bundle, a player photo expression, or a base64 data URL
Network requests fail only in NEZP
The domain is missing from your Content Security Policy configuration, or it is not served over HTTPS with a valid certificate
Your changes do not appear after re-uploading
The previous bundle is cached. Disable the cache in DevTools and reload
A tester is served the old experience
They hold only the Tester role, or the game is loading from apps-{app-id} rather than shield-apps-{app-id}
The rollout percentage selector is disabled
One of the prerequisites in Step 14 is incomplete. Select the information icon to see which
Memory grows over a long session
Overlays are being created and dismissed rather than reused or destroyed

Next steps