What App campaigns are, and why playables work there

Google Ads App campaigns are Google's automated format for driving app installs and in-app actions. You don't pick individual placements — you upload creative assets (text, images, video, and HTML5 playables) and set a goal, and Google's algorithm decides where and to whom to show each asset across Search, YouTube, Discover, Gmail, and the AdMob/Google Display Network. There's no manual placement targeting and, importantly, no manual creative review gate the way there is on some other channels. The system tests combinations of your assets automatically and shifts spend toward whatever performs.

Playables tend to perform well in this format for a simple reason: App campaigns are optimized for install intent, and a playable lets a user try the core mechanic before installing, which produces a more qualified click than a static image or a short video loop. But because the whole pipeline is algorithmic, a playable creative only gets the chance to prove itself if its package clears Google's automated ingestion checks first. There's no reviewer to notice "the ZIP is fine, just missing a meta tag" and wave it through — a failed mechanical check just means the creative doesn't run.

The real packaging requirements

This is the actual technical spec Google checks an HTML5 playable ZIP against — it's short, and every item is objectively checkable by a machine, which is exactly why it's enforced automatically rather than by manual review:

RequirementRule
Output typeZIP archive
Max size5 MB
Max files in ZIP512
Entry fileindex.html
Document structureValid <!DOCTYPE> declaration plus proper <html>/<body> tags
OrientationMust declare an orientation meta tag
Asset pathsLocal relative paths only, with a narrow allow-list of external libraries
Click-throughclickTag variable, exited via ExitApi.exit()
AudioMust stay muted until a user interaction

The narrow external-asset allow-list

Google is more permissive than most ad networks about external requests — it doesn't require every asset baked into a single self-contained HTML file the way Meta or AppLovin do. Local relative paths inside the ZIP are fine. But "more permissive" doesn't mean "anything goes": Google only permits a short, specific list of externally hosted resources on top of your local files:

  • Google's own exit API script, loaded from https://tpc.googlesyndication.com/pagead/gadgets/html5/api/exitapi.js
  • Google Fonts
  • Google-hosted jQuery, CreateJS, or GreenSock (GSAP)

A CDN font, a self-hosted analytics beacon, or any other third-party script outside that list isn't on the allow-list, and including one is a real path to rejection — it just isn't obvious unless you already know the exact list.

clickTag + ExitApi.exit()

The click-through convention has two halves: a clickTag variable holding the destination URL, and an actual exit call — ExitApi.exit() — provided by Google's exitapi.js. This is a carryover from Google's older display-ad tooling, and it's specific to Google; other networks use MRAID's mraid.open(), SDK-specific calls, or postMessage instead, so this exact pairing has to be wired in deliberately rather than assumed to already be there.

Step-by-step packaging checklist

  1. Name the entry file index.html and make sure it sits at the top level of the ZIP, not nested in a subfolder.
  2. Add a valid <!DOCTYPE> and confirm the document has real <html> and <body> tags, not just a loose fragment.
  3. Add an orientation meta tag declaring the intended orientation for the ad surface.
  4. Wire up clickTag and ExitApi.exit(), pointing at Google's exitapi.js — this is the part most non-Google exports are missing by default.
  5. Gate audio behind user interaction so nothing plays sound on load.
  6. Check every asset reference — anything not a local relative path must be on Google's allow-list (exitapi.js, Google Fonts, or Google-hosted jQuery/CreateJS/GSAP).
  7. Zip it up and check the numbers: 5 MB or under, 512 files or fewer.
  8. Test the ZIP end to end before uploading — open it in a browser, confirm the click-through fires, and confirm audio behaves correctly on first load.

None of these individually are hard. The friction is that they're easy to get partially right — a build that runs perfectly in a browser can still fail ingestion over a missing meta tag or one disallowed external font — and there's no reviewer on the other end to explain which check it failed.

Worth knowing: if you want to check a ZIP's size and file count against the 5 MB / 512-file ceiling before uploading anywhere, PlayableKit's free size checker does that in seconds, no signup. The Playable Ad Validator checks structural issues — missing entry file, broken inline script, missing assets — for free across all supported networks.

Coming from Unity Playworks/Luna? PlayableKit automates this

If your playable was built in Unity with Playworks (formerly Luna), the export ZIP that comes out of Unity is a generic HTML5 build — it runs fine in a browser but has none of the above by default, because Google's checklist isn't something Unity's exporter knows about. PlayableKit takes that same export and produces a Google-ready package automatically: entry file, DOCTYPE/html/body structure, orientation meta, clickTag/ExitApi wiring, muted-audio gating, and the size/file-count check, all handled in one pass. If you're working from a Playworks/Luna source specifically, the dedicated export walkthrough covers that path step by step, including where the export lives on disk and exactly what PlayableKit changes. For the fuller reference on Google's format, accepted asset types, and common upload errors beyond just packaging, see Google Playable Ads: Requirements, Formats & Common Errors.

The same applies regardless of source engine — Construct, Cocos, plain HTML5/JS, or anything else that outputs a browser-runnable build. The requirements above are Google's, not Unity's, so the packaging work is the same no matter what produced the original playable.