---
metadata:
  - name: generator
    content: Diplodoc Platform v5.57.3
alternate:
  - https://boost.yandex.com/doc/en/ad-monetization/dev/compose-multiplatform/app-open-ad.md
  - https://boost.yandex.com/doc/ru/ad-monetization/dev/compose-multiplatform/app-open-ad.md
  - href: en/ad-monetization/dev/compose-multiplatform/app-open-ad.md
    type: text/markdown
    title: Markdown version
  - href: llms.txt
    type: text/markdown
    title: llms.txt
---
> **Documentation Index:** Fetch the complete configuration index at https://boost.yandex.com/doc/en/llms.txt

# App open ad



<!-- source: en/ad-monetization/dev/_includes/app-open-ad.md -->
App open ads are a special ad format for monetizing app load screens. These ads can be closed at any time and are designed to be served:
* When the app is launched.
* When the app is brought to the foreground.
* When returning to the app from the background.
<!-- endsource: en/ad-monetization/dev/_includes/app-open-ad.md -->

This guide shows you how to integrate app open ads into a Compose Multiplatform app. Besides code samples and instructions, it contains format-specific recommendations and links to additional resources.

<!-- source: en/ad-monetization/dev/_includes/app-open-ad.md -->
{% note alert %}

App open ads are only supported for apps with a vertical orientation. These ads won't be served for apps with a horizontal orientation.

{% endnote %}
<!-- endsource: en/ad-monetization/dev/_includes/app-open-ad.md -->

## Appearance

App Open Ads include a **Go to the app** button, which indicates to users that they're currently in your app and can close the ad.

## Prerequisite {#pre}

<!-- source: en/ad-monetization/dev/_includes/pre-compose-multiplatform.md -->
1. Follow the Yandex Mobile Ads Compose Multiplatform plugin integration steps described under [Quick start](https://boost.yandex.com/doc/en/ad-monetization/dev/compose-multiplatform/quick-start.md).
2. Make sure that you have the [latest version of the Yandex Mobile Ads Compose Multiplatform plugin](https://boost.yandex.com/doc/en/ad-monetization/dev/platforms.md). If you're using mediation, update to the most recent [single build version](https://boost.yandex.com/doc/en/ad-monetization/dev/platforms.md).
<!-- endsource: en/ad-monetization/dev/_includes/pre-compose-multiplatform.md -->

### Terms

* **Cold start**: Launching the app when it isn't present in RAM, which creates a new app session.
* **Hot start**: Bringing the app from the background, where it's paused in RAM, into the foreground.

## Implementation {#implement}

1. Create an ad loader using `rememberAppOpenAdLoader()`.
2. Load the ad using the `loadAd()` suspend function.
3. If needed, attach a `AppOpenAdEventListener` to the loaded ad before calling `show()`.
4. Serve the ad using the `show()` method.

### Key steps

1. Create an `AppOpenAdLoader`.

    ```kotlin
    @Composable
    fun AppOpenRoot() {
        val loader = rememberAppOpenAdLoader()
        // ...
    }
    ```

2. Configure the ad request.

    ```kotlin
    val adUnitId = "demo-appopenad-yandex" // Replace with "R-M-XXXXXX-Y"
    val request = AdRequest(adUnitId = adUnitId)
    ```

    `adUnitId` is a unique identifier assigned in the Boost interface, formatted as R-M-XXXXXX-Y.

    {% note tip %}

    For testing purposes, you can use the demo ad unit `demo-appopenad-yandex`. Make sure to replace it with a production ID before release.

    Customize your request parameters using `AdRequest` (such as `targeting`, `parameters`, and `preferredTheme`). Adding more context to your request greatly improves ad relevance. For more details, see [Ad targeting](https://boost.yandex.com/doc/en/ad-monetization/dev/compose-multiplatform/target.md).

    {% endnote %}

3. Load the ad within a coroutine bound to the UI scope.

    ```kotlin
    val scope = rememberCoroutineScope()
    var appOpenAd by remember { mutableStateOf<AppOpenAd?>(null) }
    var isLoading by remember { mutableStateOf(false) }

    fun loadAppOpen() {
        isLoading = true
        scope.launch {
            try {
                val ad = loader.loadAd(request)
                appOpenAd = ad
                isLoading = false
            } catch (e: AdLoadException) {
                isLoading = false
                // Load error: e.error (AdRequestError). Unlimited retries are not recommended.
            }
        }
    }
    ```

4. Decide when to show ads. In Compose Multiplatform, you will typically use AndroidX Lifecycle to monitor the lifecycle.

5. Register a listener for user events.

    ```kotlin
    val ad = appOpenAd ?: return
    ad.setAdEventListener(
        object : AppOpenAdEventListener {
            override fun onAdShown() {
                // Called when an ad is shown.
            }

            override fun onAdFailedToShow(adError: AdError) {
                // Called when an ad failed to show.
                appOpenAd = null
                // Preload the next ad if appropriate.
            }

            override fun onAdDismissed() {
                // Called when an ad is dismissed.
                appOpenAd = null
                // Preload the next ad if appropriate.
            }

            override fun onAdClicked() {
                // Called when a click is recorded for an ad.
            }

            override fun onAdImpression(impressionData: ImpressionData?) {
                // Called when an impression is recorded for an ad.
            }
        },
    )
    ad.show()
    ```

6. After calling `show()`, keep the `AppOpenAd` instance only while it's on screen. Once the dismissal callbacks are triggered, clear the reference before loading the next creative.

7. If the loaded ad is no longer needed, set the nullable reference to null so the object can be garbage collected.

    ```kotlin
    appOpenAd = null
    ```

### Full code example

In the public app example, loading and showing the ad are handled on a separate screen. Below is the same pattern implemented in a single composable for reference:

```kotlin
@Composable
fun AppOpenSample(adUnitId: String) {
    val loader = rememberAppOpenAdLoader()
    val scope = rememberCoroutineScope()
    var appOpenAd by remember { mutableStateOf<AppOpenAd?>(null) }
    var isLoading by remember { mutableStateOf(false) }

    Column {
        Button(
            onClick = {
                isLoading = true
                scope.launch {
                    try {
                        appOpenAd = loader.loadAd(AdRequest(adUnitId = adUnitId))
                    } catch (e: AdLoadException) {
                        // Load error: e.error (AdRequestError). Unlimited retries are not recommended.
                    }
                    isLoading = false
                }
            },
            enabled = !isLoading,
        ) {
            Text(if (isLoading) "Loading..." else "Show app open ad")
        }

        Button(
            onClick = { appOpenAd?.show(); appOpenAd = null },
            enabled = appOpenAd != null,
        ) {
            Text("Show app open ad")
        }
    }
}
```

In production, bind the load and show calls to actual lifecycle events instead of button clicks.

## Features of app open ad integration {#features}

1. Ads may take a long time to load, so you should avoid increasing the cold start time if the ad hasn't loaded.
2. Preload ads for subsequent hot start impressions in advance.
3. We don't recommend loading app open ads alongside other ad formats right at app launch. During startup, the app may need to download its own system data, so loading ads at the same time can overload both the device and the network, slowing down the app launch.
4. If a request fails, don't trigger a new one right away. If you can't avoid reloading, limit the number of attempts. This helps prevent endless failed requests during network issues.

## Testing App Open Ad integration {#test}

{% list tabs %}

- Android

   <!-- source: en/ad-monetization/dev/_includes/test-android-app-open-ad.md -->
   ### Using demo ad units for ad testing {#demo-blocks}

   Use test ads to check your ad integration and the app itself. To make sure that test ads are returned for each ad request, you can use a special demo ad placement ID.

   Demo adUnitId: `demo-appopenad-yandex`.

   {% note warning %}

   Before publishing your app in the store, make sure to replace the demo placement ID with the real ID you obtained in the Boost interface.

   {% endnote %}

   For the list of all available demo ad placement IDs, see [Demo ad units for testing](https://boost.yandex.com/doc/en/ad-monetization/dev/android/demo-blocks.md).

   ### Testing ad integration {#test-int}

   You can check if your app open ads are integrated correctly using the SDK's built-in analyzer. A detailed report with the test results will appear in the log.

   To view the report, search for the keyword “YandexAds” in [Logcat](https://developer.android.com/studio/command-line/logcat), a tool for debugging Android apps.
   ```bash
   adb logcat -v brief '*:S YandexAds'
   ```

   If the integration is successful, the following message is returned:
   ```bash
   adb logcat -v brief '*:S YandexAds'
   mobileads$ adb logcat -v brief '*:S YandexAds'
   I/YandexAds(13719): [Integration] Ad type App Open Ad was integrated successfully
   ```

   If there are any ad integration issues, you'll get a detailed issue report and troubleshooting recommendations.
   <!-- endsource: en/ad-monetization/dev/_includes/test-android-app-open-ad.md -->

- iOS

   <!-- source: en/ad-monetization/dev/_includes/test-ios-app-open-ad.md -->
   ### Using demo ad units for ad testing {#demo-blocks}

   Use test ads to check your ad integration at app launch and during your testing process. To make sure that test ads are returned for each ad request, you can use a special demo ad placement ID.

   Demo adUnitId: `demo-appopenad-yandex`.

   {% note warning %}

   Before publishing your app in the store, make sure to replace the demo placement ID with the real ID you obtained in the Boost interface.

   {% endnote %}

   For the list of all available demo ad placement IDs, see [Demo ad units for testing](https://boost.yandex.com/doc/en/ad-monetization/dev/ios/demo-blocks.md).
   <!-- endsource: en/ad-monetization/dev/_includes/test-ios-app-open-ad.md -->

   ### Testing ad integration

   <!-- source: en/ad-monetization/dev/_includes/test-integration-ios.md -->
   You can test your ad integration using the native Console tool.

   To view detailed logs, call the `YandexAds` class's `enableLogging` method.

   ```swift
   YandexAds.enableLogging()
   ```

   To view SDK logs, go to the Console tool and set `Subsystem = com.mobile.ads.ads.sdk`. You can filter logs by category or error level.

   If you're having problems integrating ads, you'll get a detailed report on the issues and recommendations for how to fix them.

   <img src= "https://yastatic.net/s3/doc-binary/src/dev/mobile-ads/common/integration-ios-2.png">
   <!-- endsource: en/ad-monetization/dev/_includes/test-integration-ios.md -->

{% endlist %}

## Recommendations

1. Avoid showing app open ads before the app reaches the splash screen. Splash screens improve the user experience. This way, the user can be sure they opened the right app.

   In addition, you can use this screen to warn users about the upcoming ad. Use a loading indicator or a text message informing the user that they can continue viewing the app content after the ad.

2. Make sure to account for the delay between the ad request and the impression.

   If there's a delay between the ad request and the impression, the user may see an ad that is unrelated to the app content. One solution is to show the splash screen before displaying the main app content and to begin ad impressions from that screen. We don't recommend displaying an ad if the app has already opened content after the splash screen.

3. Avoid displaying ads immediately after the app is installed. Wait until the new user opens the app and uses it a few times.

   Show the ad only to users who meet specific in-app criteria. For example, if they completed a specific level, opened the app a certain number of times, or don't participate in reward offers.

4. Avoid serving an ad at every cold or hot app start. Adjust the frequency of impressions based on user behavior.

5. Display ads only if the app has been running in the background for a certain time (for example, 30 seconds, 2 minutes, or 15 minutes).

6. Run a test. Each app requires an individual approach to maximize revenue. To account for changes in user behavior and engagement, we recommend periodically testing different display strategies for in-app ads.

## Additional resources {#resources}

Full integration examples:

* <!-- source: en/ad-monetization/dev/_includes/github-pubdev-links.md -->
  Link to [GitHub](https://github.com/yandexmobile/yandex-ads-multiplatform).
  <!-- endsource: en/ad-monetization/dev/_includes/github-pubdev-links.md -->
