The structure Mintegral requires

Mintegral's package shape has three layers, and all three names have to agree with each other:

  • A ZIP archive — Mintegral wants a zipped package, not a single self-contained HTML file the way AppLovin or Meta expect.
  • One top-level folder inside that ZIP — everything in the package lives under a single folder, not loose at the archive root.
  • An HTML entry file inside that folder — the actual playable HTML, at the exact relative path <name>/<name>.html.

The part that catches teams out: the ZIP's own filename, the top-level folder's name, and the HTML file's name all have to be the same base name. Mintegral isn't just checking that an entry file exists somewhere in the archive — it's checking that the container and its contents were named as one deliberate unit.

A correct structure, concretely

Using a placeholder name like mygame for a specific creative, the archive should unzip to exactly this:

mygame.zip └── mygame/ # top-level folder, same name as the ZIP ├── mygame.html # entry file, same name again ├── img/ │ ├── bg.png │ └── button.png ├── audio/ │ └── sfx.mp3 └── js/ └── engine.js

Every name in that first three lines — mygame.zip, mygame/, mygame.html — is the same string. Swap in your own creative's name and the pattern holds; what matters is that all three match each other, not what the name itself is.

Compare that to a structure that runs fine in a browser but still fails Mintegral's review: a ZIP named build.zip containing a folder named creative containing a file named index.html. Nothing about the playable itself is broken — the naming just doesn't agree at any of the three levels, and that alone is enough to be rejected.

What's allowed inside beyond the entry file

Unlike networks that demand one flattened, fully inlined HTML file, Mintegral allows ordinary loose asset files inside the package. Images, audio clips, JavaScript bundles, and any engine runtime files your build depends on can sit alongside the entry HTML as separate files, referenced by normal relative paths — nothing needs to be base64-encoded or inlined. A Unity-exported playable with several sprite sheets and an audio clip can generally keep those assets as-is rather than flattening everything into a single file. The only real constraints: the whole package (entry file plus every asset) must stay at or under 5 MB, and everything referenced by the HTML needs to live inside that same top-level folder so relative paths resolve correctly once unzipped.

Step-by-step packaging checklist

  1. Pick one name for the creative up front — this becomes the ZIP filename, the folder name, and the HTML filename, decided once rather than named piece by piece.
  2. Create the top-level folder using that name and put every file the playable needs inside it — nothing loose at the ZIP root.
  3. Name the entry HTML file to match, placed directly inside that folder, not nested in a subfolder of its own.
  4. Add asset folders as neededimg/, audio/, js/, or whatever your build already uses — nested inside the same top-level folder, referenced by relative path.
  5. Wire the callbacks — CTA calls window.install() with an mraid.open(url) fallback, and window.gameEnd() fires unconditionally when the interactive portion finishes.
  6. Check the total package size — everything combined must be 5 MB or smaller; compress textures or trim audio if a late asset swap pushed it over.
  7. Zip the folder itself, not its contents — compressing the files inside the folder directly, instead of the folder, is a common way the top-level folder silently disappears.
  8. Rename the finished ZIP to match, checking your zip tool didn't default to something like Archive.zip — a rename applied to the ZIP but not the folder inside it is a common way a correct package drifts out of sync.
  9. Test the callbacks on the actual build, including any skip or fast-forward path through the playable.
Why this is easy to get wrong even when the playable works: a naming mismatch produces no error in a browser preview. The HTML loads, the game plays, the CTA works — the failure only appears during Mintegral's own review, after submission, which is exactly why it's worth checking the archive/folder/file names explicitly before uploading rather than relying on a functional test to catch it.

How PlayableKit generates this automatically

You build the playable in Unity Playworks/Luna exactly as usual and upload that export to PlayableKit once. For Mintegral, PlayableKit then generates the output archive, the top-level folder, and the HTML entry file with one identical name — satisfying the matching-name rule by construction rather than by a manual rename that can drift out of sync later — places the entry file at the correct relative path with every asset nested so relative references resolve once unzipped, wires window.install() with the mraid.open(url) fallback plus window.gameEnd() at the right point, and flags the package before export if assets push it over the 5 MB cap.

The same source export can be packaged for Google Ads, Meta, AppLovin, TikTok, Unity Ads, and Vungle in the same pass, each with its own entry file and structural rules applied correctly — see the full walkthrough in Export Unity Playworks/Luna to Mintegral, or the broader spec in Mintegral Playable Ads. If you've already hit this specific rejection on a build packaged by hand, Mintegral Name Mismatch Rejected covers diagnosing and fixing that exact failure.

Before you submit: run any Mintegral ZIP — hand-built or PlayableKit-built — through the free playable ad validator to catch structural issues like this, and the size checker to confirm it's under the 5 MB cap before it becomes a rejection instead of a fix.