The problem
This rejection is confusing precisely because nothing looks wrong on your end. You test the build, audio fires right on cue, visuals and click-through all check out, and you submit expecting a pass. The rejection reason that comes back — audio playing automatically, before any user interaction — reads like Meta is flagging a feature, not a defect. It is a real requirement, and it's spelled out directly in Meta's playable spec: "Do not auto-play audio before a user interaction." Playback quality is irrelevant here. The build can be pixel-perfect and still fail review on this one line alone.
Why Meta enforces this
This isn't a browser limitation Meta is passing along — it's a deliberate product decision. A playable renders inline in a feed or story that a user is scrolling through with sound off by default, often in public, often without headphones. Sound firing the instant the ad loads, before the user has asked for anything, is a jarring interruption in a context built around silent, self-paced browsing. Meta's review pipeline checks for this directly in the code path, not just in observed behavior, because "it happened to be muted on my test device" isn't the same guarantee as "the code physically cannot fire audio until a tap occurs." That's why a creative can autoplay audio at a volume nobody would even notice and still get flagged — the rule is about the trigger, not the loudness.
Why a Unity Playworks/Luna export often autoplays by default
This is also why the issue shows up so consistently in builds that started life as a Unity Playworks (Luna) export. Inside the original app or game, sound-on is the reasonable default — a player has already opened the game expecting audio, so a scene's music or SFX firing on load is normal, expected behavior, and Playworks/Luna carries that assumption straight through into the exported build. Nothing in the export step questions whether that's still the right call once the same file is repurposed as a feed ad. The context changed — game session to silent-scrolling ad placement — but the trigger logic that decides when a sound cue fires usually didn't, because there was no reason to touch it for the original use case.
The fix: gate audio behind the first tap, not scene start
The fix isn't in file packaging, asset encoding, or anything a conversion pipeline does — it's in the trigger. Every place your Unity scene fires audio needs to check for a prior user-interaction event (the first tap, click, or touch on the creative) before it's allowed to play, instead of firing directly off scene load, a timer, or an animation callback. In practice that means:
- Set a flag the first time a tap/click/touch event lands anywhere on the playable, and gate every
AudioSource.Play()call (or equivalent) behind that flag. - Remove any audio calls tied directly to
Start(), scene-load callbacks, or a fixed delay timer — those all fire before Meta considers the user to have "interacted." - Apply this to every sound in the build, not just background music — a single SFX that fires on load (a whoosh, a chime, a voice line) is enough to trigger the same rejection.
- Don't rely on the browser's own autoplay-blocking behavior to cover this for you. Some in-app webviews are more permissive than a desktop browser, and Meta's review checks the code path itself — not just whether a given test device happened to suppress the sound.
This is a source-level change in the Unity project, then a re-export through Playworks/Luna — not something a packaging tool can patch after the fact, since the trigger logic lives in your scene's own scripts, not in the HTML shell around it.
How to verify before resubmitting
Before you upload again, open the converted file cold — no interaction at all — and confirm you hear nothing for several seconds. Then tap once, anywhere on the CTA path a real user would use, and confirm audio starts only after that tap, not before it. Test this in the same kind of container the ad will actually run in (an MRAID/webview test placement or Meta's own preview), since a bare local file can behave differently around autoplay than a real in-feed placement. Running the export through PlayableKit's Playable Ad Validator is a fast first pass — it flags Meta's other packaging rules (single-file embedding, CTA wiring) for free before you spend a review cycle finding out the hard way. If you're also seeing dead silence rather than a rejection notice — audio that simply never plays, even after a tap — that's a different, more technical issue with the Luna export's cache pipeline, covered separately in Luna playable audio not playing: common causes.