Playable export reference·12 min read·

The MRAID 2.0 export checklist every ad network actually checks

MRAID 2.0 is the IAB's specification for rich-media mobile ads, and every major playable-accepting network claims to support it. In practice each network layers its own extra rules on top of the spec and rejects exports that miss any of them. The list below is the working checklist 7play.ai runs against every export, distilled from the public docs plus what the network rejections actually flag in the wild.

The MRAID 2.0 baseline

The spec itself is short. The ad must be a self-contained HTML file (or a ZIP with index.html at the root and all referenced assets inline), it must not include any network requests outside whitelisted DSP origins, it must call mraid.open(url) for clickthroughs (not window.location.href), and it must call mraid.getState() and respond to ready, viewableChange, and sizeChange events. That is the floor.

Per-network rules layered on top

AppLovin

AppLovin developer docs.

  • ZIP must be under 5 MB. Files inside count toward the cap including images and audio.
  • Click handler must call mraid.open(). AppLovin's ad-tag system appends the destination URL at serve time; hard-coded URLs in the ZIP will be replaced.
  • The end card must be inline in the same index.html, not loaded from an external URL. AppLovin rejects ZIPs that try to fetch the end card from a remote origin.
  • No video tags. Static + Canvas + WebGL only. Animated PNGs are fine.
  • The ad must finish rendering within 2 seconds of mraid.ready. Slow first frame is the most common silent rejection.

IronSource (Unity LevelPlay)

IronSource developer portal.

  • ZIP must be under 3 MB. This is the tightest of the major networks; if your asset pack is over 3 MB after gzip you will get rejected without explanation.
  • Clickthrough must call mraid.open('%%CLICK_URL_UNESC%%') (the IronSource click macro). The macro is replaced at serve time.
  • Touch events must use pointer events, not touch events. Old touch handlers fail.
  • The ad must implement mraid.useCustomClose(true) if you want to control the close button. Default close-button placement breaks several mechanic types.

Mintegral

  • ZIP under 5 MB. Same as AppLovin.
  • Clickthrough URL is appended via %%CTA%% macro. Pass it to mraid.open().
  • The end card must include an explicit close button calling mraid.close(). Mintegral does not render its own close overlay on playable end cards.
  • Audio is allowed but must be muted by default and unmuted only on user interaction. Auto-playing audio is an instant rejection.

Meta (Facebook Audience Network)

Meta Audience Network playable best practices.

  • ZIP under 5 MB.
  • Meta has its own playable spec layered on top of MRAID 2.0. The <meta name="ad.size" content="width=320,height=480"> tag is required in the index.html head.
  • The end card must include a clear call-to-action button. Meta's reviewers reject end cards without a visible CTA even if the playable itself has one mid-game.
  • Use FbPlayableAd.onCTAClick() in addition to mraid.open() when integrating directly. The dual handler is a Meta-specific requirement.

Unity Ads

  • ZIP under 5 MB.
  • Unity is the most permissive of the majors on MRAID 2.0 strictness but the strictest on performance: the ad must reach interactive in under 1 second on a mid-tier Android device or it gets deprioritised in the auction.
  • Pass clicks through mraid.open('{IFA}'). The macro is replaced with the iOS IDFA / Android AAID for attribution.

Liftoff Influence

  • ZIP under 5 MB.
  • Liftoff's creative studio uses MRAID 2.0 with the standard click macro %%CLICK_URL%%. No Liftoff-specific extras for the playable itself.
  • The CSV manifest Liftoff asks for in the upload UI is required even when the playable is self-contained. Missing manifest is the most common rejection.

A working click handler template

The shape that satisfies all six networks at once:

<script>
  // Wait for MRAID before firing any callbacks.
  if (mraid.getState() === 'loading') {
    mraid.addEventListener('ready', init);
  } else {
    init();
  }

  function init() {
    document.getElementById('cta').addEventListener('click', onClick);
  }

  function onClick() {
    // Network-supplied macro is appended by the ad server at serve time.
    // %%CLICK_URL%% (Liftoff) / %%CLICK_URL_UNESC%% (IronSource) /
    // %%CTA%% (Mintegral) all resolve into the same string at runtime.
    mraid.open('%%CLICK_URL%%');
  }
</script>

The cross-network rules that catch everyone

  • No external network requests. If your playable fetches a font, analytics script, or asset from a CDN at runtime, it will be rejected by every network listed above. Inline everything.
  • No localStorage or cookies. MRAID 2.0 ads are sandboxed; storage APIs are blocked. Persist nothing across renders.
  • One JS bundle, gzipped. Split bundles fail the ZIP-root rule. Inline all scripts.
  • No document.write(). Networks scan for it and reject. Use DOM APIs.
  • Audio must default to muted. Universal across the majors.

Caps at a glance

NetworkZIP capClick macroNotes
AppLovin5 MBNone (URL appended)End card inline
IronSource3 MB%%CLICK_URL_UNESC%%Pointer events only
Mintegral5 MB%%CTA%%Explicit close button required
Meta5 MBNone (use FbPlayableAd)ad.size meta tag required
Unity5 MB{IFA} macroInteractive in < 1s
Liftoff5 MB%%CLICK_URL%%CSV manifest required at upload

The honest summary

MRAID 2.0 is a thin spec, but the per-network overlays make "works on AppLovin" and "works on IronSource" two different problems. Any tool that claims universal MRAID 2.0 export is making promises about the overlay rules above, not just the spec. The right test is to take a real export, push it to each of your networks, and see how many pass validation in the first upload. Anything that does not is taking a shortcut on one of the rules above.


7play.ai turns your existing game assets into export-ready playable ad variants in minutes, not weeks. Closed beta in 2026.
Apply for design partner access