mraid.open(url) on a real tap. See our export walkthrough for the step-by-step version of what's below.
What ironSource is, and how it runs playables
ironSource operates two distinct paths for creative delivery, and it matters which one a given campaign runs through. The first is ironSource's owned-and-operated in-app network — the mediation-driven inventory most people mean when they say "ironSource," reached through the ironSource SDK inside publisher apps. The second is the ironSource programmatic exchange, which sells the same general inventory into DSPs under its own, separately documented rules. Both render creatives inside an MRAID-compliant WebView container and are now documented under Unity's Grow product line rather than a legacy ironSource-branded site — but the two specs disagree on some specifics, which is exactly the kind of thing that trips up a manual build.
Technical requirements
Unity publishes two separate specs that cover ironSource inventory: the general creative-specifications page for its Grow/acquire products, and a dedicated MRAID specifications guide for the ironSource exchange. They don't fully agree with each other on file size or MRAID version — worth stating plainly rather than picking one number and hoping it's right for your inventory.
| Requirement | Spec |
|---|---|
| File size | Unity's general Grow spec: under 5 MB. The ironSource exchange's MRAID spec: downloaded assets + code capped at 4 MB. Two different documented numbers — build to the lower one if you don't know which inventory you're in. |
| MRAID version | Unity's general Grow spec cites MRAID 3.0. The ironSource exchange's MRAID spec cites MRAID 2.0. Same discrepancy pattern as file size — check which doc governs your placement before relying on MRAID 3.0-only APIs. |
| Package format | Single self-contained index.html — no linked files or folders, assets inlined |
| Click-through / CTA | mraid.open(url), fired only on explicit user interaction — never an automatic redirect on load |
| Close button | ironSource's container renders its own close control and timer; a custom one inside the creative is redundant and can conflict with it |
| Orientation | Support both portrait and landscape |
| Network requests | Avoid XHR/network calls; any unavoidable external reference must use an absolute HTTPS URL — no relative paths, no HTTP |
| Playback start | Gate the start of interactive content on the MRAID viewableChange event (or a loading screen, per the exchange doc) — don't assume visibility on page load |
| Platform floor | Android 4.4+, iOS 9.0+ |
Both Unity documents agree on the core shape of a compliant creative — MRAID-driven, single-file, click-gated — they just diverge on the numbers that decide whether a specific build passes review. That divergence is documented on Unity's own docs sites (docs.unity.com/en-us/grow/acquire/creatives/playable/specifications and docs.unity.com/en-us/grow/programmatic/ironsource-exchange/mraid-specifications-guidelines) — a real ambiguity to plan around, not a typo to ignore.
Accepted formats
ironSource's playable ad unit accepts a single HTML5 file built to the MRAID container model described above — no separate video-plus-endcard playable format, and no multi-file package or ZIP with loose assets referenced by relative path. Everything the ad needs to render — markup, script, styles, images, audio, fonts — has to live inside that one index.html, encoded inline (typically as base64 data URIs), within whichever size ceiling applies to the inventory you're targeting. Static image or video-only creatives are separate ad formats on ironSource, distinct from the interactive playable unit this page covers.
Common upload errors
Most rejected ironSource playable submissions trace back to a small set of recurring mistakes:
- Building to the wrong size ceiling. A creative under 5 MB but over 4 MB clears one Unity-documented ironSource spec and fails the other. If you don't know which inventory (owned-and-operated vs. exchange) a campaign runs through, build under 4 MB and avoid the question entirely.
- Relative asset paths left in from a browser-tested build. A playable that renders fine locally or on a dev server can still reference images or scripts by relative path — those break the moment the HTML runs inside ironSource's sandboxed WebView, since nothing outside the single file is guaranteed to exist.
- A custom close button fighting the network's own. A visible close/X control inside the creative, on top of the one ironSource's container already renders, can create an overlapping tap target or a control that never registers.
- Interactive content starting before viewability. Firing animations or timers on
window.onloadinstead of the MRAIDviewableChangeevent means part of the playable's runtime can play out before the user ever sees the ad rendered. - An auto-redirect instead of a gated click-through. Any code path that calls
mraid.open()without a user tap is a rejection on both the owned-and-operated and exchange paths — the store link has to follow a real tap. - Mixed HTTP/HTTPS references. Even one external reference over plain HTTP, left from a CDN link or analytics snippet, is enough to fail review in a WebView that enforces HTTPS-only access.
Best practices for adapting a build by hand today
If ironSource is a network you need now and you're working from a Unity Playworks/Luna export (or any other engine's export), the practical sequence is: inline every image, audio clip, and font as base64 so the file is genuinely self-contained; replace whatever click handler your export generated with an explicit mraid.open(url) tied to a real tap event; delete any custom close/X element the build includes; gate gameplay behind the MRAID viewableChange event instead of starting on load; and target a hard ceiling of 4 MB rather than 5 MB so the build clears both Unity-documented specs regardless of which ironSource inventory it runs through. Test the packaged file in an actual MRAID test harness before submission — a build that only runs in a plain browser tab hasn't proven anything about how it behaves inside ironSource's container.
This is exactly the per-network work PlayableKit automates today — asset inlining, click-through wiring, and size compliance, per network's actual rules, from one source export, ironSource included.