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 point | Guide |
|---|---|
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
| Aspect | Standard 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
| Phase | What you do | Affects 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
- Go to the App Dashboard and select your app.
- 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.
- Select Zero Permissions and confirm.

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.
- Navigate to Use Cases > Customize “Launch a game on Facebook” > Network Connection Settings > User Data Deletion.
- Delete the following from your systems, including backups, logs, and analytics warehouses:
- Player names
- Player profile pictures
- Friend names
- Friend profile pictures
- Keep player IDs and gameplay data. Scores, progress, inventory, and purchase history may all be retained.
- 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 level | What 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:
- Navigate to App Review > Permissions and Features.
- Direct link:
https://developers.facebook.com/apps/YOUR_APP_ID/app-review/permissions/
- Direct link:
- Find Instant Games Zero Permission Access.
- Select Request Advanced Access.

From Use Cases:
- 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
- Direct link:
- Find Instant Games Zero Permission Access.
- Select Actions > 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 deprecated | Replacement |
|---|---|
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.
- Go to the App Dashboard and select your app.
- Navigate to Instant Games > Content Security Policy.
- 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.
- Navigate to Use Cases > Customize “Launch a game on Facebook” > Web Hosting.
- Toggle Network Enabled Zero Permissions Settings at the top of the page.
- Upload your v8.0 bundle as a ZIP file, with
index.htmlandfbapp-config.jsonat the top level of the archive rather than inside a folder. - Wait for the platform to finish scanning the bundle.
- 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.

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()orgetPhoto()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.htmlis served fromshield-apps-{your-app-id}. Without theshieldprefix, 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.
- Go to Instant Games > Review > App Review for Instant Games.
- Add your game to the submission.
- Confirm that Instant Games Zero Permission Access with advanced access from Step 3 is included in the same submission.
- Submit.

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

- In the Zero Permissions Users Rollout card, select a small starting value from Rollout percentage and select Confirm.
- Monitor retention, session length, crash rate, purchase conversion, and ad revenue against your pre-migration baseline for long enough to see a real signal.
- 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(), andFBInstant.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
| Symptom | Likely 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
- Overlay View Components — Full XML component reference.
- Example Game Use Cases — Worked examples for friend lists, leaderboards, and profiles.
- API Reference — Complete SDK v8.0 reference for Zero Permissions.
- Testing — Facebook player and local testing.
- FAQ — Common questions about data deletion, permissions, and rollout.
- Get Support — Support channels if you get stuck.