Quick disambiguation before anything else

Unity Playworks/Luna (formerly Luna) is the build tool inside the Unity Editor that exports your scene as a playable. Unity Ads is the unrelated ad network and mediation platform that serves that playable inside other apps. Sharing a company name is the only thing they have in common — Unity Ads enforces the same packaging spec on a Playworks/Luna export as it would on a playable built in any other engine. If you specifically need the Playworks/Luna-to-Unity-Ads export workflow, see Export Unity Playworks/Luna to Unity Ads. This page covers the Unity Ads spec itself, independent of what built the creative.

Technical requirements

Unity Ads validates playable creatives against a fixed set of rules. There's no partial credit — a creative that satisfies six of the seven items below still fails review on the seventh.

RequirementDetail
File structureOne self-contained HTML file. No ZIP, no folder, no separate CSS/JS/asset files.
Size limit5 MB hard cap. Unity Ads recommends staying near 2 MB for consistent load performance across devices.
Ad formatMRAID 2.0. Unity Ads' player expects the standard MRAID interface — not a proprietary SDK, not a plain iframe.
External requestsNone permitted. Every image, audio clip, font, and script has to be embedded directly in the HTML document itself.
Click-throughThe CTA element must call mraid.open(url). This is the only click API Unity Ads recognizes for playables.
Ready-state handlingThe creative must wait for MRAID's ready event before issuing any MRAID API calls or making layout decisions that depend on the ad container.
AudioNo audio may auto-play before the user has interacted with the ad.

Note what's not on this list: there's no forced-orientation requirement (unlike some other MRAID networks) and no separate game-end callback — Unity Ads' spec is comparatively lean, which is part of why it's a common first target when testing a new playable build.

Accepted formats

Unity Ads accepts exactly one packaging shape for playables: a single HTML file implementing MRAID 2.0. That's a narrower ask than several other networks in the same space:

  • Google Ads accepts a ZIP of up to 512 files (5 MB total) with an index.html entry point — multi-file packages are fine there.
  • Mintegral and TikTok also accept ZIP archives with specific folder/filename conventions and, in TikTok's case, a config.json.
  • Unity Ads, AppLovin, Meta, and Vungle all require the single-file HTML shape — but each expects a different click API inside that file (mraid.open() for Unity Ads and AppLovin, FbPlayableAd.onCTAClick() for Meta, a postMessage call for Vungle), so a single-file build made for one of them isn't automatically valid for another.

Practically: if your creative is already a ZIP or has assets referenced by relative path, it isn't in a submittable state for Unity Ads yet, regardless of how it behaves in a browser.

Size limits, in practice

5 MB is the number that determines whether Unity Ads' upload form accepts the file at all — go over it and the upload is rejected outright, no review needed. 2 MB is a softer, performance-driven recommendation: playables load inside a mediation SDK on a real user's device, often on a cellular connection, and a file that clears the technical cap but sits at 4.5 MB will show up in performance data as slow-loading, high-abandon inventory even though it passed submission.

The gap between the two numbers matters more once every asset gets embedded rather than loaded on demand — base64-encoding images, audio, and fonts inflates their footprint by roughly a third over the raw file size, so a build that looked lean as separate files can land well past 2 MB once it's a single self-contained document.

Common upload errors

  • Submitting a ZIP or multi-file folder. Unity Ads' upload form expects exactly one HTML file — a ZIP that would be fine for Google Ads or Mintegral will be rejected here.
  • Leftover external references. A Google Font @import, a CDN-hosted script tag, or an analytics pixel left in from development will violate the no-external-requests rule even if it never actually fires during review — the reference itself is enough to fail validation.
  • Missing MRAID ready-state gating. Interaction logic that fires on page load instead of waiting for the MRAID ready event can throw errors or render incorrectly inside Unity Ads' player, which initializes the container asynchronously.
  • Wrong click API. A CTA wired for FbPlayableAd.onCTAClick(), a bare window.open(), or a Vungle-style postMessage call will compile and preview fine locally but do nothing when tapped inside Unity Ads — because Unity Ads only listens for mraid.open(url).
  • Autoplay audio. Any audio element with autoplay set, or a script that calls .play() before a user tap, gets flagged during review.
  • Oversized after embedding. A file that was under 2 MB as separate assets frequently crosses 5 MB once every image and sound is base64-encoded inline — this is the single most common "it worked yesterday" surprise.

Best practices

  • Compress images and audio before embedding them, not after — encoding adds size, it never removes it.
  • Gate all interaction and rendering logic behind the MRAID ready listener, even logic that "shouldn't" need the ad container to be initialized.
  • Keep the CTA to a single, unambiguous mraid.open(url) call — don't layer a fallback click handler on top that could fire under different conditions.
  • Run the finished file through a size checker and a structural validator before uploading — catching a 5.2 MB file or a stray external <script src> locally is faster than waiting on network review to find it.
  • Test the actual click-through target URL, not just that the CTA is wired — a working mraid.open() call pointed at a broken or missing URL still fails in the wild even though it passes review.
Worth knowing: Playable Kit's free Playable Ad Validator and size checker catch most of the errors above — oversized files, missing MRAID ready gating, external references, autoplay audio — before you ever touch Unity Ads' upload form.

Exporting a Unity Playworks/Luna build for Unity Ads with PlayableKit

If your playable started life as a Unity Playworks/Luna export, none of the requirements above are things that export does automatically — it's a multi-file build with relative asset paths, no MRAID wiring, and no ready-state gating, because Playworks/Luna stays agnostic about which network the export eventually targets. PlayableKit picks up at that point: upload the Playworks/Luna ZIP, select Unity Ads as a target, and it outputs a single embedded HTML file with MRAID 2.0 and mraid.open() already wired in, sized against the 2 MB/5 MB thresholds above. The full step-by-step is on the dedicated Export Unity Playworks/Luna to Unity Ads page.

The same source export can be packaged for other single-file MRAID-style networks in the same pass — see the TikTok playable ads and Vungle playable ads references for how their requirements differ from Unity Ads'.