Guide 8 min read
Web-to-App on Your Own Domain: The Meta Setup That Restores Creative-Level Signal
A step-by-step guide to web-to-app campaigns for subscription apps: Meta web ads that route through your own domain to the App Store, attributed by the MMP you already run, with per-creative conversion truth instead of SKAN aggregates.
Bernard Bontemps · Founder, HyperScale
If you advertise an iOS subscription app on Meta the standard way (App promotion objective, SKAdNetwork measurement), you are optimizing through frosted glass. Postbacks arrive aggregated, delayed, and privacy-thresholded. Conversion values are coarse. And the dimension you need most for creative-testing economics, which ad drove the subscription, is exactly the one SKAN aggregates away.
There is a setup that removes most of that ceiling, and the sharpest subscription apps have been quietly running it for a while: web-objective campaigns that route the click through a page on your own domain, auto-continue to the App Store, and let the MMP you already run stitch the install and every in-app event back to the originating click. The MMP then feeds it all back to Meta through the Conversions API.
No new SDK. No attribution vendor beyond the MMP already in your app. We’ve validated this end to end with Singular, and AppsFlyer and Adjust ship the same primitives as documented product flows. This is the full setup.
The architecture in one pass
- The ad runs as a Sales (website) campaign, not App promotion. Destination: a URL on a domain you own, like
get.yourbrand.com/start. - The click opens that URL in the in-app browser. Meta appends
fbclid, and your URL parameters carry{{campaign.id}},{{adset.id}},{{ad.id}}via dynamic URL parameters. - Your page captures the click identity (
fbclid, the_fbpcookie, the ad IDs), fires the Pixel, and hands the user to your MMP’s attribution link, which 302s into the App Store. Total dwell time: under a second, with a real branded page and a manual store button as the fallback. - The install. The MMP SDK inside your app matches the new install to that web click: deterministically when the click ID survives the hop, probabilistically otherwise. This matching problem is the entire reason MMPs exist, and their web-to-app products solve it well.
- The postback. The MMP (or a thin relay you own) sends install, trial start, and purchase to Meta’s Conversions API as web events, carrying
fbcderived from the originalfbclidand anevent_idfor deduplication. - The loop closes. Because the events carry the click identity, Meta re-identifies the exact ad. Ads Manager shows conversions per creative, delivery optimizes on true down-funnel events, and your MMP dashboard shows the same campaign, ad set, and ad hierarchy it shows for everything else.
The trick that makes iOS tractable: the click identity lives on the web side of the fence, where measurement is pixel-grade, real-time, and unlimited by SKAN’s campaign caps. SKAN never enters the flow.
What you gain, and what it costs
Gained. Per-ad conversion attribution instead of campaign-level aggregates. Full-funnel events (trial start, trial-to-paid, renewals, values) instead of a coarse conversion-value schema. Near-real-time signal instead of day-scale postback delays. The complete web optimization surface: value optimization, pixel-based audiences and exclusions, the Sales objective’s maturity. And in many accounts, web auctions price meaningfully below app-install auctions. Worth testing rather than assuming.
Paid. A browser hop before the store: a real page load, so some drop-off. The sub-second redirect keeps it small, but it isn’t zero. Attribution is a match, not a guarantee: deterministic when the click ID survives to the install, modeled when it doesn’t (private browsing strips fbclid for a slice of users). And the numbers move between reporting surfaces. These installs are web conversions to Meta, so don’t panic when the app-campaign dashboards look quiet. Judge the whole setup on your MMP’s numbers and blended CAC, and if you’re rigorous, run a geo split against an app-campaign cell before migrating spend.
One honesty note on that trade: subscription apps are uniquely positioned to win it. Your economics don’t depend on day-0 impulse installs. They depend on knowing which creative produces subscribers, and trading a sliver of click-through friction for subscriber-grade attribution is a good trade at almost any realistic drop-off rate.
Why your own domain, specifically
Every MMP will happily give you a link on their shared domain. Use your own subdomain anyway: get.yourbrand.com, CNAME’d to the MMP’s branded-link product or pointed at a redirect worker you host. Four reasons.
- First-party context. The click lands on your registrable domain, so the identifiers you capture (
fbclidbecoming_fbc) are set in a first-party context, which is materially more durable under Safari’s tracking protections than a shared third-party link domain. - Ad-account trust. Your ads’ display URL matches your brand. Review goes smoother, and users hesitate less.
- Portability. Links you own outlive any vendor. Swap MMPs and your URLs, QR codes, and historical campaigns keep working.
- Data custody. The click log (timestamp, ad IDs, click ID) lands somewhere you can query, joined against whatever else you know.
Prerequisites (any MMP)
- Your app ships the MMP SDK (AppsFlyer, Adjust, or Singular). If you’re a serious subscription app, it already does.
- Meta Pixel created, plus Conversions API access: a system-user token or the MMP’s native integration.
- A subdomain you control, with the events that matter (
trial_start,purchase) defined in the MMP.
Setup with Singular (the one we’ve battle-tested)
Singular productizes this end to end, which is why it’s the cleanest reference implementation.
- Branded link domain. In Singular, configure a custom link subdomain on your domain (one CNAME).
- Create the web-to-app tracking link. Singular’s link builder lets you set the redirect destination per platform: App Store for iOS, Play for Android, a web fallback for desktop, so one URL serves every click (their web-to-app campaign doc).
- Put the link to work. Either paste it directly as the ad’s Website URL, or, in the own-domain pattern, serve a minimal branded page at your URL that captures parameters and forwards into the Singular link.
- Enable CAPI forwarding. Singular’s “optimize web campaigns for mobile acquisition using Conversion APIs” flow is the key switch: attributed installs and in-app events are sent to Meta with the attributed web click identity. Select the events worth Meta’s attention: install, trial start, purchase.
- Verify. Meta Events Manager should show your events arriving as server events with strong match quality (the
fbcparameter present), deduplicating cleanly against any Pixel events.
Setup with AppsFlyer
AppsFlyer documents this exact flow as web-based campaigns for Meta Ads.
- OneLink template on a branded subdomain (CNAME to AppsFlyer), redirecting to your store listings per platform.
- Smart Script on your landing page. This is AppsFlyer’s param-plumbing layer: it reads the incoming URL (
fbclid, UTMs, your ad-ID macros) and generates the outgoing OneLink with everything mapped into attribution parameters. The click identity survives the hop without hand-rolled JavaScript. - Enable the Meta CAPI leg. In the flow AppsFlyer describes, install and in-app events are sent back to Meta carrying the web click identity, which is what re-identifies the specific ad.
- Map events and verify exactly as above: Events Manager for arrival and match quality, AppsFlyer’s dashboard for the install hierarchy.
Setup with Adjust
Adjust ships the same primitives under web-to-app:
- Adjust link with a branded domain, configured to redirect into the stores per platform.
- Carry the click identity. Pass
fbclidand your ad-ID macros into the link’s parameters on the way through your page, so the install attribution retains the web click context. - Close the CAPI loop. Depending on your plan, use Adjust’s Meta integration to forward attributed conversions, or run the universal fallback that works with any MMP: subscribe to the MMP’s real-time callbacks and relay them to Meta’s Conversions API yourself. The relay is a small piece of infrastructure (receive postback, attach the stored
fbcand anevent_id, POST to Meta), and it keeps you MMP-agnostic forever.
The Meta campaign itself
- Objective: Sales, destination Website. Not App promotion, not Awareness.
- Optimization event: the deepest event you can feed at roughly 50 per week per ad set. For most subscription apps that’s
trial_start, notpurchase. The learning-phase math doesn’t care about your preferences; the full cost-of-signal analysis is in the testing-bottleneck essay. - URL parameters, set once at the ad level so every ad self-labels:
utm_source=meta&utm_medium=paid&cmp={{campaign.id}}&aset={{adset.id}}&ad={{ad.id}} - Structure: broad targeting, Advantage+ placements, consolidated ad sets. The delivery system does the matching; your job is the creative slate.
- The landing page: a real page (logo, one line of value, store badges) that auto-continues. It renders for reviewers, works with JavaScript disabled thanks to the buttons, and continues instantly for everyone else. Don’t cloak. There is nothing here that needs hiding.
The verification pass
Before scaling a dollar: preview an ad, click it on a real device, and watch the whole chain. The fbclid lands on your page. The store opens. The install happens on an App Store build, not TestFlight (TestFlight installs don’t attribute). The MMP logs the install under the right campaign, ad set, and ad. Events Manager receives trial_start as a server event with fbc populated and dedup passing. The conversion appears on the ad row in Ads Manager within the attribution window. If any link in that chain is dark, fix it before spend. Every later analysis inherits this plumbing.
What this is really for
The point of this setup isn’t reporting hygiene. It’s that per-creative conversion truth changes what you can do next.
With SKAN aggregates, a creative test reads at the campaign level, weeks late. Teams fall back on hook rates and proxy metrics, and the testing bottleneck stays budget-bound and signal-bound. With web-to-app in place, every ad carries its own subscriber math: cost per trial per creative, trial-to-paid per angle, payback per persona. Verdicts get faster, cheaper, and true, which raises your testing throughput without raising your budget. And as ad platforms shift to generative retrieval over creative content, day-scale creative feedback loops stop being a nice-to-have and become the operating requirement.
That’s also why this is the attribution posture we set up HyperScale customers with. Your agent team plans and produces the creative slate, and this pipe is what lets it read per-ad truth from your own MMP and your own domain, then plan the next round from evidence instead of proxies. Your data, your domain, your MMP. The agents just do the work.