
Applovin Ads Integration
- 56 installs
- 41 repo stars
- Updated March 13, 2026
- finsilabs/awesome-ecommerce-skills
Integrate AppLovin MAX mediation and ad campaigns into a mobile commerce app for user acquisition, retargeting, and in-app purchase event tracking.
About
A skill for wiring AppLovin MAX mediation and ad campaigns into native iOS/Android shopping apps for acquisition and monetization. A developer uses it when running user acquisition or in-app ad monetization for a mobile store.
- MAX mediation SDK plus AppLovin Ads for acquisition/retargeting
- Native app only; not for web-only stores
Applovin Ads Integration by the numbers
- 56 all-time installs (skills.sh)
- Ranked #1,295 of 1,879 Marketing & SEO skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill applovin-ads-integrationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 56 |
|---|---|
| repo stars | ★ 41 |
| Last updated | March 13, 2026 |
| Repository | finsilabs/awesome-ecommerce-skills ↗ |
What it does
Integrate AppLovin MAX mediation and ad campaigns into a mobile commerce app for user acquisition, retargeting, and in-app purchase event tracking.
Files
AppLovin Ads Integration
Overview
AppLovin is a leading mobile advertising platform for commerce apps — combining the MAX mediation SDK (monetizing your app with ads) and AppLovin Ads (acquiring users and running retargeting campaigns). This skill applies to merchants who have a native iOS or Android shopping app and want to run user acquisition campaigns or monetize with in-app ads. It is not relevant for web-only stores.
When to Use This Skill
- When running user acquisition campaigns for a native mobile commerce app
- When monetizing a mobile commerce app with in-app advertising using MAX mediation
- When setting up purchase event postbacks for ROAS-optimized bidding
- When migrating from MoPub/ironSource to AppLovin MAX mediation
- When building a retargeting campaign for mobile app users who added to cart but did not purchase
- When implementing SKAdNetwork attribution for iOS 14+ compliance
Core Instructions
Step 1: Determine what you need
AppLovin serves two distinct use cases — choose the right one:
| Goal | What to Use | Difficulty |
|---|---|---|
| Acquire new app users and retarget existing ones | AppLovin Ads (demand-side platform) | Medium — configure via dashboard at manage.applovin.com |
| Monetize your app by showing ads to users | AppLovin MAX SDK | High — requires SDK integration in your mobile app |
| Track purchase events for ROAS optimization | SDK + MMP (Adjust, AppsFlyer, or Singular) | High — requires server-side postback setup |
Prerequisite: You need an AppLovin account at applovin.com and a mobile app that exists on the App Store or Google Play.
Step 2: Install the AppLovin MAX SDK in your mobile app
iOS (CocoaPods):
Add to your Podfile:
pod 'AppLovinSDK'
pod 'AppLovinMediationGoogleAdMobAdapter'
pod 'AppLovinMediationMetaAudienceNetworkAdapter'Initialize in AppDelegate.swift:
import AppLovinSDK
func application(_ app: UIApplication, didFinishLaunchingWithOptions opts: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
ALSdk.shared().mediationProvider = "max"
ALSdk.shared().userIdentifier = currentUser?.id ?? ""
ALSdk.shared().initializeSdk { sdkConfig in
// SDK ready — load your first ad
}
return true
}Android (Gradle):
In app/build.gradle:
dependencies {
implementation 'com.applovin:applovin-sdk:+'
implementation 'com.applovin.mediation:google-adapter:+'
implementation 'com.applovin.mediation:facebook-adapter:+'
}In Application.onCreate():
AppLovinSdk.getInstance(this).apply {
mediationProvider = "max"
userIdentifier = currentUser?.id ?: ""
initializeSdk { /* SDK ready */ }
}Step 3: Set up a Mobile Measurement Partner (MMP) — do this before running campaigns
Do not run AppLovin campaigns without an MMP. Direct postbacks miss cross-device attribution and SKAdNetwork decoding. Use one of:
- Adjust (adjust.com) — most widely used, strong AppLovin integration
- AppsFlyer (appsflyer.com) — industry standard, good for multi-network attribution
- Singular (singular.net) — good for privacy-focused attribution
Each MMP provides an AppLovin integration module that automatically sends purchase postbacks. In your MMP dashboard: 1. Navigate to Partner Configuration → AppLovin 2. Enter your AppLovin SDK key 3. Enable "In-App Purchase" postbacks 4. Configure conversion value mapping for SKAdNetwork
Step 4: Track purchase events in your app
Fire purchase events immediately after a confirmed purchase — both client-side and server-side:
Client-side (iOS):
func trackPurchase(orderId: String, revenue: Double, currency: String) {
ALEventService.shared().trackEvent(ALEventTypePurchasedProduct, withParameters: [
ALEventParameterRevenueAmount: NSNumber(value: revenue),
ALEventParameterRevenueCurrency: currency,
ALEventParameterProductIdentifier: orderId,
])
}
// Also track add-to-cart for retargeting signal
func trackAddToCart(productId: String, price: Double) {
ALEventService.shared().trackEvent(ALEventTypeAddedItemToCart, withParameters: [
ALEventParameterProductIdentifier: productId,
ALEventParameterRevenueAmount: NSNumber(value: price),
])
}Server-side postback (for signal reliability):
async function sendApplovinPurchasePostback(params: {
userId: string;
orderId: string;
revenue: number;
currency: string;
applovinId?: string;
}) {
const url = new URL('https://d.applovin.com/postback/v1/purchase');
url.searchParams.set('event_token', process.env.APPLOVIN_POSTBACK_TOKEN!);
url.searchParams.set('event_name', 'purchase');
url.searchParams.set('user_id', params.userId);
url.searchParams.set('transaction_id', params.orderId);
url.searchParams.set('revenue', params.revenue.toFixed(2));
url.searchParams.set('currency', params.currency);
if (params.applovinId) url.searchParams.set('device_id', params.applovinId);
await fetch(url.toString());
}Step 5: Create user acquisition campaigns
In AppLovin's advertising dashboard at manage.applovin.com:
1. Go to Campaigns → Create Campaign 2. Configure:
- Campaign Type: App Install (iOS or Android)
- Optimization Goal: Purchase (ROAS optimization)
- Bid Strategy: Target ROAS — start at 200%, increase after 50+ purchases/day
- Daily Budget: minimum $200/day for ROAS campaigns (algorithm needs data volume)
- Targeting: Tier-1 countries (US, CA, GB, AU) for highest ROAS; age 25–54
3. Upload creative assets: 15s and 30s video ads, playable ads, and static banners 4. Under Audience Signals, upload a lookalike audience based on your top purchasers (export from your MMP)
Step 6: Configure the MAX mediation waterfall (for app monetization only)
If you are monetizing your app with in-app ads (not just running user acquisition), configure your waterfall in the MAX dashboard:
1. Go to MAX → Ad Units → Create Ad Unit 2. Set up in-app bidding networks first (simultaneous auction, highest yield):
- AppLovin Exchange
- Meta Audience Network
- Google AdMob
3. Add traditional waterfall fallbacks with floor prices:
- $3.00 CPM → Vungle
- $2.00 CPM → Unity Ads
- $1.00 CPM → ironSource
Load and show interstitial ads in your app:
class CartViewController: UIViewController {
var interstitialAd: MAInterstitialAd?
override func viewDidLoad() {
super.viewDidLoad()
interstitialAd = MAInterstitialAd(adUnitIdentifier: "YOUR_AD_UNIT_ID")
interstitialAd?.delegate = self
interstitialAd?.load()
}
}
extension CartViewController: MAAdDelegate {
func didLoad(_ ad: MAAd) { /* ready to show */ }
func didHide(_ ad: MAAd) {
interstitialAd?.load() // preload immediately after hide
}
}Step 7: Configure SKAdNetwork for iOS 14+ attribution
Map your purchase value ranges to SKAdNetwork conversion values (0–63) in both AppLovin's dashboard and your app code:
func updateSKANConversionValue(orderValue: Double) {
let conversionValue: Int
switch orderValue {
case 0..<25: conversionValue = 10
case 25..<50: conversionValue = 20
case 50..<100: conversionValue = 30
case 100..<200: conversionValue = 40
default: conversionValue = 63
}
if #available(iOS 16.1, *) {
SKAdNetwork.updatePostbackConversionValue(conversionValue, coarseValue: .high, lockWindow: false) { _ in }
} else {
SKAdNetwork.updateConversionValue(conversionValue)
}
}Configure the identical schema in AppLovin's SKAN configuration panel (MAX → SKAN Configuration) so the platform can decode postbacks.
Best Practices
- Always use an MMP — direct postbacks miss cross-device attribution and SKAdNetwork decoding; MMPs handle this automatically
- Set revenue postbacks server-side — client-side events can be spoofed; server postbacks give AppLovin reliable ROAS signal
- Preload ads before they are needed — call
load()immediately afterdidHideto have an ad ready for the next impression - Use in-app bidding for all placements — simultaneous auction outperforms sequential waterfall by 15–30% eCPM
- Refresh creatives every two weeks — AppLovin's algorithm tires of creatives quickly; add new video and playable formats
- Cap retargeting frequency — limit to 3 impressions per user per day
Common Pitfalls
| Problem | Solution |
|---|---|
| Purchase postbacks not registering | Verify postback token is correct; ensure revenue uses decimal format (not integer) |
| SDK fails to initialize on iOS | Add NSUserTrackingUsageDescription to Info.plist; implement ATT prompt before SDK init |
| ROAS campaign underspending | Lower your tROAS target; ensure 50+ purchase events/day for the algorithm to optimize |
| SKAN conversion values showing all zeros | Confirm updateConversionValue is called after final purchase confirmation, not just payment intent |
| Rewarded ad not loading after first show | Call load() in didHide callback, not didDisplay |
| Android GAID missing in postbacks | Request AD_ID permission on Android 13+; user may have limited ad tracking in device settings |
Related Skills
- @tiktok-ads-integration
- @meta-ads-integration
- @marketing-attribution-dashboard
- @push-notifications
- @customer-retention-engine
{
"context": "Tests whether the agent correctly sets up AppLovin MAX on iOS using CocoaPods, initializes the SDK with the required settings, handles interstitial ad lifecycle properly by preloading after dismiss, implements ATT requirements, and recommends in-app bidding over traditional waterfall.",
"type": "weighted_checklist",
"checklist": [
{
"name": "AppLovinSDK pod",
"max_score": 7,
"description": "Podfile includes pod 'AppLovinSDK'"
},
{
"name": "Adapter pods",
"max_score": 7,
"description": "Podfile includes at least the Google AdMob adapter (AppLovinMediationGoogleAdMobAdapter) and Meta/Facebook adapter (AppLovinMediationMetaAudienceNetworkAdapter)"
},
{
"name": "mediationProvider set to max",
"max_score": 10,
"description": "AppDelegate sets ALSdk.shared().mediationProvider = \"max\" before initializeSdk"
},
{
"name": "userIdentifier assigned",
"max_score": 8,
"description": "AppDelegate sets ALSdk.shared().userIdentifier to an internal user ID before calling initializeSdk"
},
{
"name": "ATT prompt requirement",
"max_score": 10,
"description": "integration-notes.md or AppDelegate mentions NSUserTrackingUsageDescription in Info.plist AND implementing the ATT (App Tracking Transparency) prompt before SDK initialization"
},
{
"name": "Interstitial delegate implemented",
"max_score": 8,
"description": "CartViewController conforms to MAAdDelegate (or implements equivalent delegate methods): didLoad and didFailToLoadAd are present"
},
{
"name": "Preload on didHide",
"max_score": 12,
"description": "Calls interstitialAd.load() inside the didHide(_:) callback (NOT didDisplay) to preload the next ad immediately after dismissal"
},
{
"name": "Retry on failure",
"max_score": 8,
"description": "didFailToLoadAd callback includes logic for retry with exponential backoff (e.g. uses DispatchQueue.asyncAfter, increasing delay, or mentions exponential backoff)"
},
{
"name": "isReady guard before show",
"max_score": 8,
"description": "Checks interstitialAd.isReady before calling show() to avoid showing an unloaded ad"
},
{
"name": "In-app bidding preference",
"max_score": 12,
"description": "integration-notes.md explains that in-app bidding (simultaneous auction) is preferred over traditional waterfall because it achieves higher eCPM"
},
{
"name": "SDK init in application(_:didFinishLaunchingWithOptions:)",
"max_score": 10,
"description": "SDK initialization is performed inside application(_:didFinishLaunchingWithOptions:) in AppDelegate"
}
]
}
AppLovin MAX SDK Setup for iOS Commerce App
Problem/Feature Description
GearMarket, an outdoor equipment retailer, is launching an iOS app and wants to monetize it with interstitial ads displayed after users complete a cart review. The team is new to mobile ad SDKs and needs a complete reference implementation for integrating AppLovin MAX. The app uses CocoaPods for dependency management and is built in Swift.
The engineering lead wants a clean reference implementation that demonstrates: how to declare the SDK dependency, how to initialize the SDK correctly in the app entry point, and how to load and display interstitial ads in a view controller used for the cart screen. The team has been warned that iOS privacy rules require additional configuration before the SDK can function properly on iOS 14+ devices, and that handling ad lifecycle callbacks correctly is important to avoid missed impressions.
Output Specification
Produce the following files:
Podfile— CocoaPods dependency file declaring AppLovin MAX and adapter podsAppDelegate.swift— App delegate with proper SDK initializationCartViewController.swift— UIViewController subclass that loads and shows an interstitial ad, implementing the appropriate delegate callbacksintegration-notes.md— Brief notes covering: the iOS privacy requirement needed before SDK init, best practices for ad lifecycle management to avoid missed impressions, and a comparison of the two main MAX placement configuration strategies for maximizing eCPM
Input Files (optional)
No input files are required. Produce all implementation files from scratch.
{
"context": "Tests whether the agent implements the AppLovin purchase postback correctly: using the right URL endpoint, formatting revenue as a decimal, passing AppLovin's proprietary device ID, using server-to-server delivery, and recommending an MMP for production.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Postback URL",
"max_score": 12,
"description": "Uses the URL https://d.applovin.com/postback/v1/purchase as the endpoint"
},
{
"name": "event_token parameter",
"max_score": 8,
"description": "Reads the AppLovin postback token from an environment variable (not hardcoded) and passes it as event_token query parameter"
},
{
"name": "event_name=purchase",
"max_score": 8,
"description": "Sets event_name query parameter to the string 'purchase'"
},
{
"name": "Revenue decimal format",
"max_score": 12,
"description": "Formats revenue as a decimal string (e.g. using .toFixed(2) or equivalent), NOT as an integer"
},
{
"name": "Required purchase params",
"max_score": 8,
"description": "Passes user_id, transaction_id (or order_id), and currency as query parameters"
},
{
"name": "AppLovin device ID",
"max_score": 12,
"description": "Accepts an AppLovin-specific device identifier and passes it as the device_id parameter (in addition to or instead of IDFA/GAID)"
},
{
"name": "Optional IDFA/GAID",
"max_score": 8,
"description": "Includes IDFA (idfa) and GAID (gaid) as optional parameters, only appending them when present"
},
{
"name": "Server-to-server delivery",
"max_score": 10,
"description": "architecture-note.md explains that server-side postbacks are preferred over client-side because client-side events can be spoofed and server postbacks give reliable ROAS signal"
},
{
"name": "MMP recommendation",
"max_score": 12,
"description": "architecture-note.md recommends using an MMP (names at least one of: Adjust, AppsFlyer, Singular) for production to handle deduplication and SKAdNetwork attribution"
},
{
"name": "HTTP error handling",
"max_score": 10,
"description": "Checks the HTTP response status and throws or returns an error when the postback request fails"
}
]
}
Purchase Event Reporting to AppLovin
Problem/Feature Description
ShopFast, a mobile commerce startup, is running user acquisition campaigns on AppLovin and needs to report confirmed purchases back to the platform so AppLovin's ROAS optimization algorithm can improve targeting. Their backend is a Node.js/TypeScript service. The team has been told their campaign is underperforming because AppLovin isn't receiving reliable purchase signals, and the growth team suspects the attribution data is either missing or formatted incorrectly.
The engineering team needs to implement a purchase event reporting module that sends confirmed purchase data to AppLovin from the server side. The module should handle multiple device identifier types (since users may or may not have granted tracking permission) and correctly format all required fields. The team also needs a brief technical design note explaining their production architecture decision, since a product manager asked why they're not using a simpler client-side approach.
Output Specification
Produce the following files:
postback.ts— A TypeScript module exporting asendPurchasePostbackfunction that accepts purchase and user data and sends it to AppLovinarchitecture-note.md— A 1-2 paragraph technical decision document explaining the server-side vs client-side tradeoff and the role of an MMP in production attribution at scale
{
"context": "Tests whether the agent correctly implements SKAdNetwork conversion value tiers, uses the iOS 16.1+ SKAdNetwork 4.0 API with fallback, updates conversion values at the right point in the purchase flow, exports retargeting audiences with the right user segment and fields, and configures campaigns with correct ROAS targets, budget minimums, geo/age targeting, frequency caps, and dashboard SKAN alignment.",
"type": "weighted_checklist",
"checklist": [
{
"name": "SKAN conversion value tiers",
"max_score": 10,
"description": "skan-tracker.swift maps order value ranges to the correct integer tiers: 0-25 → 10, 25-50 → 20, 50-100 → 30, 100-200 → 40, 200-500 → 50, 500+ → 63"
},
{
"name": "iOS 16.1+ SKAN 4.0 API",
"max_score": 10,
"description": "skan-tracker.swift uses #available(iOS 16.1, *) check and calls SKAdNetwork.updatePostbackConversionValue(_:coarseValue:lockWindow:) for iOS 16.1+"
},
{
"name": "Fallback SKAN API",
"max_score": 8,
"description": "skan-tracker.swift calls SKAdNetwork.updateConversionValue(_:) in the else branch for iOS versions before 16.1"
},
{
"name": "Update after final purchase",
"max_score": 10,
"description": "campaign-guide.md or code comments specify that updateConversionValue must be called after the final purchase confirmation, not after payment intent"
},
{
"name": "SKAN dashboard alignment",
"max_score": 8,
"description": "campaign-guide.md mentions that the same conversion value schema must be configured in AppLovin's SKAN configuration panel so AppLovin can decode the postbacks"
},
{
"name": "Retargeting user segment",
"max_score": 10,
"description": "retargeting-export.ts filters for users where: lastOpenedAt is between 7 and 30 days ago, hasPlacedOrder is false, and hasAddedToCart is true"
},
{
"name": "Audience export fields",
"max_score": 8,
"description": "retargeting-export.ts outputs records with idfa (from idfaHash) and gaid (from advertisingId) fields for AppLovin Audience Manager upload"
},
{
"name": "ROAS bid strategy",
"max_score": 8,
"description": "campaign-guide.md specifies Target ROAS bid strategy starting at 200%, ramping up after reaching 50+ purchase events per day"
},
{
"name": "Daily budget minimum",
"max_score": 6,
"description": "campaign-guide.md specifies a minimum daily budget of $200 for ROAS-optimized campaigns"
},
{
"name": "Geo targeting",
"max_score": 6,
"description": "campaign-guide.md lists tier-1 countries (at least US, CA, GB, AU) as the recommended geographic targets for highest ROAS"
},
{
"name": "Age targeting",
"max_score": 6,
"description": "campaign-guide.md recommends targeting age range 25-54 as the demographic that skews toward mobile spenders"
},
{
"name": "Retargeting frequency cap",
"max_score": 10,
"description": "campaign-guide.md specifies capping retargeting ad frequency to 3 impressions per user per day"
}
]
}
iOS Attribution Setup and Retargeting Audience Export for AppLovin
Problem/Feature Description
StyleDrop, a fashion commerce app, has been running AppLovin user acquisition campaigns but their ROAS reports are showing wildly inaccurate revenue numbers and the attribution team can't figure out why. Additionally, the marketing team wants to set up a retargeting campaign focused on users who abandoned their cart. The iOS engineering team needs to fix the attribution pipeline and prepare the retargeting audience export.
The engineering team knows they need to implement SKAdNetwork conversion value tracking properly on iOS, including support for both newer and older iOS versions. They also need to export the right segment of users from the database for the retargeting audience upload. The campaign manager also needs a written campaign configuration guide for the user acquisition and retargeting campaigns, covering bid strategy, budget, targeting demographics, geographic focus, and frequency controls.
Output Specification
Produce the following files:
skan-tracker.swift— A Swift utility that updates SKAdNetwork conversion values based on purchase order value, supporting both iOS 16.1+ (SKAdNetwork 4.0) and older iOS versionsretargeting-export.ts— A TypeScript script that queries a database for the correct retargeting audience and returns/exports records in the format expected by AppLovin Audience Managercampaign-guide.md— A configuration guide covering: user acquisition campaign bid strategy and budget, geographic targeting, age targeting, the correct timing for calling the SKAN conversion value update relative to the purchase flow, frequency capping for retargeting, and any additional AppLovin platform configuration steps needed for accurate attribution reporting
Input Files (optional)
No additional files will be provided. The database schema can be assumed to have a table app_users with fields: id, advertisingId (GAID), idfaHash, email, lastOpenedAt, hasPlacedOrder, hasAddedToCart.
{
"name": "finsi/applovin-ads-integration",
"version": "0.1.0",
"summary": "Integrate AppLovin MAX mediation and ad campaigns for mobile commerce apps with user acquisition, retargeting, and in-app purchase event tracking",
"skills": {
"applovin-ads-integration": {
"path": "SKILL.md"
}
}
}