What AppLovin is, and where playables run

AppLovin isn't a single ad unit — it's a stack. MAX is AppLovin's in-app bidding mediation layer, and it's the most common place a playable actually gets served: as a rewarded, interstitial, or offerwall-adjacent unit competing in real-time auctions against demand from other networks plugged into the same waterfall. AppDiscovery is AppLovin's own demand-side platform, buying installs directly using its algorithmic bidding engine (AXON) across the apps in its own portfolio and its exchange partners. A creative built for one generally works for the other, because both render through the same MRAID-based ad surface — the spec that matters is AppLovin's rendering requirement, not which buying path served the impression.

That combination — huge auction volume plus a single, strict rendering contract — is why getting the packaging wrong is expensive: a rejected or misbehaving creative doesn't just fail once, it fails across every campaign routed through it.

Technical requirements

AppLovin's playable spec is stricter than most networks in one specific way: there's no ZIP option and no partial-embedding allowance. Everything has to live inside one HTML file, and that file has to behave correctly the instant it's dropped into AppLovin's renderer with no other files beside it.

RequirementSpec
File structureSingle self-contained .html file — no ZIP, no companion assets
Size cap5 MB maximum, including every embedded image, script, and audio clip
Ad interfaceMRAID 2.0
OrientationMust render correctly in both portrait and landscape
External requestsProhibited entirely — no external JS, CSS, images, fonts, or network calls of any kind
Click-throughmraid.open(url) — not window.open, not a bare clickTag
Auto-behaviorNo auto-click and no auto-play audio before the user has interacted
MRAID timingNo MRAID API call or viewport-dependent layout decision before MRAID signals ready

Two of these deserve extra attention because they look fine in a desktop browser test and only fail once submitted for real: "zero external requests" and "wait for MRAID ready." A browser doesn't enforce either — it happily fetches a relative-path asset or runs an MRAID call against a nonexistent object without complaint. AppLovin's rendering surface enforces both, which is why "worked when I opened it locally" is a different claim from "passed AppLovin's review."

Accepted formats and size limits

AppLovin accepts exactly one packaging shape for HTML5 playables: a single .html file with every resource — images, audio, fonts, and any library code — inlined directly into that file, typically as base64 or base122 data URIs decoded at runtime. There's no separate manifest, no sibling assets folder, and no video-file upload path for a playable; if audio or imagery needs to ship, it ships base64-encoded inside the same document.

The ceiling is 5 MB for the whole file, full stop — no larger allowance for "rich" creatives, no separate budget for audio versus imagery. Teams shipping heavier playables (long audio tracks, dense sprite sheets, several full-screen frames) often aim closer to 2–3 MB for headroom, since base64 encoding adds roughly 33% overhead on top of a raw asset's size — a 3.5 MB folder of raw PNGs and MP3s can land uncomfortably close to the cap once everything is inlined.

Common upload errors

Most AppLovin playable rejections trace back to one of a small handful of causes. All of them pass a casual local test and only surface once the creative hits AppLovin's actual rendering environment.

1. Calling MRAID before it's ready

Firing mraid.open(url) straight from a button's click handler, or reading mraid.getMaxSize() the moment a script loads, both work in a browser because there's no real MRAID container to be "not ready" yet. Inside AppLovin's SDK, the MRAID bridge takes a moment to initialize, and any call made before it signals ready is undefined behavior — sometimes silently dropped, sometimes thrown, and either way the creative misbehaves in an environment you can't easily debug from a desktop. The fix is a listener on the MRAID ready state (or mraidviewable, depending on SDK version) that gates every subsequent MRAID call and layout decision.

2. Referencing assets externally instead of embedding them

An <img src="assets/hero.png">, an @font-face pointing at a local .woff2, or a CSS background-image using a relative path are all normal in a standard web build — and all fail the instant AppLovin opens the HTML file in isolation with no sibling files present. There's no fallback: every one of those references returns nothing, and the creative either fails automated validation before it's served, or renders visibly broken if it slips through. The only fix is full inlining — every asset converted to a data URI inside the HTML itself.

3. Auto-playing audio (or auto-clicking) before interaction

Starting background music the instant the ad loads, or programmatically firing the CTA to "help" conversion, both violate AppLovin's interaction rule outright. Audio has to wait for an actual tap, and the CTA has to be a genuine user action, not code simulating one. AppLovin treats this as a hard rejection criterion, not a stylistic suggestion.

4. Assuming one orientation is enough

A playable built and tested only in portrait can render with broken layout or an unusable CTA the moment it's served landscape — and AppLovin's inventory serves both. If the design only makes sense one way, it still has to degrade gracefully in the other, not break.

Best practices

  • Gate everything behind MRAID ready. Wrap the entire ad's interactive logic — not just the CTA — behind the ready listener, not just the assumptions about a container that may not have finished initializing.
  • Inline first, optimize second. Get every asset embedded and working before tuning file size; the numbers change again once externally-referenced assets are properly inlined.
  • Test the actual output file, not the dev build. A dev-server build with live-reloading behaves differently than the single-file artifact you submit — always do a final pass against the real exported HTML.
  • Check both orientations before submitting, not after a rejection tells you to.
  • Keep the CTA obvious and singular. One clear mraid.open(url) call tied to one clear tap target reads better in review than several ambiguous click zones.
Worth knowing: most of the errors above are structural — missing embedded assets, MRAID calls firing too early, files sitting over the size cap — and all three are things PlayableKit's free Playable Ad Validator and free size checker can catch before you spend a review cycle finding out from AppLovin directly.

Exporting to AppLovin with PlayableKit

If your playable started life as a Unity Playworks/Luna export, PlayableKit takes that same ZIP, embeds every referenced asset as base64/base122 directly into a single file, wires the CTA to a properly ready-gated mraid.open(url) call, and checks the result against the 5 MB cap and both orientations automatically — producing the exact applovin.html AppLovin's spec expects, without hand-editing anything. The full workflow, including why raw Playworks/Luna exports fail this spec by default, is covered on the dedicated Export Unity Playworks/Luna to AppLovin page.

AppLovin is included on every paid PlayableKit plan: Starter at $400/mo covers 50 builds a month across Google Ads, Meta, AppLovin, and Unity Ads; Studio at $560/mo covers 100 builds across all supported networks; Scale at $800/mo covers 300 builds and 2 seats across all networks; Enterprise pricing is custom for volume beyond that. Full detail is on the pricing page.