# Unity SDK 2

## What you need <a href="#what-you-need" id="what-you-need"></a>

To use the Metica Unity SDK you need:

* An `API key`, obtainable in the Metica platform
* An `appId`, obtainable in the Metica platform.
* A `Max SDK Key`, obtainable from Applovin platfom

## Dependencies

Import the AppLovin Unity Plugin into your project by following the guide below.&#x20;

Only the Import the **AppLovin MAX Unity plugin** step is required, the Metica SDK handles everything else. The minimum version of MAX plugin that Metica requires is **8.2.0**.

{% embed url="<https://support.axon.ai/en/max/unity/overview/integration#import-the-applovin-max-unity-plugin>" %}

## Supported Ad Formats

The Metica SDK supports the following ad formats:

| Format           | Description                                                      |
| ---------------- | ---------------------------------------------------------------- |
| **Banner**       | Standard banner ads displayed at the top or bottom of the screen |
| **MREC**         | Medium Rectangle ads (300x250)                                   |
| **Interstitial** | Full-screen ads shown between content transitions                |
| **Rewarded**     | Video ads that reward users for watching                         |

{% hint style="info" %}
[#app-open-a-ds-not-natively-supported](#app-open-a-ds-not-natively-supported "mention"). See App Open Ads for a workaround using MAX SDK directly.
{% endhint %}

## Unity 2022 Android Build Configuration

Unity 2022 ships with an older Android Gradle Plugin (AGP) and Gradle version that are incompatible with the Metica SDK's dependencies. To build for Android, you must upgrade these tools manually.

{% hint style="info" %}
Unity 6 users: No additional configuration is needed — Unity 6 ships with AGP 8.4.0+, Gradle 8.6+, and JDK 17 by default.
{% endhint %}

### Prerequisites

* **JDK 17** or later installed on your machine. You can download [Aws Corretto](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/downloads-list.html) or [Adoptium](https://adoptium.net/).
* **Gradle 8.6** or later. Download it [here](https://services.gradle.org/distributions/gradle-8.6-bin.zip) and extract it to a known location.

{% stepper %}
{% step %}

### Step 1: Configure External Gradle

Unity 2022.3 bundles Gradle 7.5.1, which is too old. You need to point Unity to an external Gradle 8.6+ installation.

1. In Unity, go to **Preferences > External Tools** (macOS) or **Edit > Preferences > External Tools** (Windows)
2. Uncheck **"Gradle Installed with Unity (recommended)"**
3. Set the path to your Gradle 8.6 installation directory
   {% endstep %}

{% step %}

### Step 2: Update `baseProjectTemplate.gradle`

Enable the **Custom Base Gradle Template** in **Project Settings > Player > Android > Publishing Settings > Build**, then update `Assets/Plugins/Android/baseProjectTemplate.gradle`:

```javascript
buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:8.4.0'
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22'
    }
}
plugins {
    id 'com.android.application' version '8.4.0' apply false
    id 'com.android.library' version '8.4.0' apply false
    **BUILD_SCRIPT_DEPS**
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
```

{% endstep %}

{% step %}

### Step 3: Configure JDK 17 for Gradle

Enable the **Custom Gradle Properties Template** in **Project Settings > Player > Android > Publishing Settings > Build**, then add the following line to `Assets/Plugins/Android/gradleTemplate.properties`:

```properties
org.gradle.java.home=<PATH_TO_JDK_17>
```

Replace `<PATH_TO_JDK_17>` with the absolute path to your JDK 17 installation

{% hint style="warning" %}
Do not use a relative path or environment variable, Gradle requires an absolute path to the JDK installation directory.
{% endhint %}
{% endstep %}
{% endstepper %}

## Installation <a href="#installation" id="installation"></a>

In Unity, you need to import a custom package stored here:

{% embed url="<https://github.com/meticalabs/metica-unity-package>" %}

{% hint style="info" %}
Before installing any new Metica `.unitypackage` , please remove any old Metica versions from your `Assets`
{% endhint %}

In Unity Editor, click on `Assets` -> `Import Package` -> `Custom Package` and load the `.unitypackage` downloaded from our repository

{% hint style="danger" %}
Do *not* call, reference, or initialize the Max SDK library (AppLovin MAX) directly in your code. Metica’s SDK already packages and manages the Max SDK integration internally. If you attempt to use MaxSDK directly, you may cause version conflicts, duplicate initialization, and unexpected behaviour in Metica’s ad logic. Only exception is related to [#app-open-a-ds-not-natively-supported](#app-open-a-ds-not-natively-supported "mention")
{% endhint %}

## Initialization

Initialize the SDK using your credentials and mediation configuration.

In `MeticaInitConfig`, `API_KEY` and `APP_ID` are mandatory. The `USER_ID` is optional, if you don't provide one (or pass an empty string), the Metica SDK will generate a unique UUID per player for you.

In `MeticaMediationInfo` provide the `Max SDK Key`.

The SDK provides two ways to initialize: a **callback-based** approach and an **async** approach. Both return a `MeticaInitResponse` object with the following properties:

* `SmartFloors.UserGroup` – the experiment group assigned to the current player (`holdout` or `trial`).
* `SmartFloors.IsSuccess` – a boolean indicating whether initialization completed successfully. If false, the player is automatically assigned to the holdout group.
* `UserId` – the user ID for the current player. If you did not provide a `USER_ID` during initialization, this will contain the UUID that the SDK generated automatically.

{% hint style="danger" %}
`SmartFloors.UserGroup` and `SmartFloors.IsSuccess` are provided **for analytics and logging purposes only**. You do not need to branch your code or implement any fallback logic based on these values — the SDK handles all experiment assignment and holdout behavior internally.
{% endhint %}

### Callback-based Initialization

Use `MeticaSdk.Initialize` with a callback to be notified when initialization completes. This approach works well in standard Unity `MonoBehaviour` lifecycles without requiring `async/await`.

```csharp
using Metica;
using Metica.Ads;
using UnityEngine;

public class MyGameManager : MonoBehaviour
{
    void Start()
    {
        // Set privacy preferences before initialization
        MeticaSdk.Ads.SetHasUserConsent(true);
        MeticaSdk.Ads.SetDoNotSell(false);

        MeticaSdk.SetLogEnabled(true);

        var config = new MeticaInitConfig("YOUR_API_KEY", "YOUR_APP_ID", "user-id");
        var mediationInfo = new MeticaMediationInfo(MeticaMediationType.MAX, "YOUR_MAX_SDK_KEY");

        // Initialize SDK with callback
        MeticaSdk.Initialize(config, mediationInfo, OnInitialized);
    }

    private void OnInitialized(MeticaInitResponse initResponse)
    {
        Debug.Log($"Current user is part of {initResponse.SmartFloors.UserGroup}");

        // When the initialization is not successful, the player
        // will be excluded from Metica treatment
        // and it will receive the normal treatment.
        // This information is useful only for your analytics
        Debug.Log($"Metica initialization completed: {initResponse.SmartFloors.IsSuccess}");
        
        Debug.Log($"User ID: {initResponse.UserId}");

        Debug.Log("Metica SDK initialized successfully");

        // Now you can load ads
    }
}
```

### Async Initialization

Alternatively, you can use the async version if your codebase uses `async/await`:

```cs
using Metica;
using Metica.Ads;
using UnityEngine;

public class MyGameManager : MonoBehaviour
{
    void Start()
    {
        InitializeMetica();
    }

    async void InitializeMetica()
    {
        var config = new MeticaInitConfig("YOUR_API_KEY", "YOUR_APP_ID", "user-id");
        var mediationInfo = new MeticaMediationInfo(MeticaMediationType.MAX, "YOUR_MAX_SDK_KEY");

        // Set privacy preferences before initialization
        MeticaSdk.Ads.SetHasUserConsent(true);
        MeticaSdk.Ads.SetDoNotSell(false);

        // Initialize SDK
        var initResponse = await MeticaSdk.InitializeAsync(config, mediationInfo);

        Debug.Log($"Current user is part of {initResponse.SmartFloors.UserGroup}");

        // When the initialization is not successful, the player
        // will be excluded from Metica treatment
        // and it will receive the normal treatment.
        // This information is useful only for your analytics
        Debug.Log($"Metica initialization completed: {initResponse.SmartFloors.IsSuccess}");
        
        Debug.Log($"User ID: {initResponse.UserId}");

        Debug.Log("Metica SDK initialized successfully");

        // Now you can load ads
    }
}
```

## **Ad implementation**

The SDK supports `Banner`, `MREC`, `Interstitial`  and `Rewarded` ads. All ad operations are accessed via `MeticaSdk.Ads`.&#x20;

### Banner Ads

Standard banner ads with auto-refresh functionality.

```csharp
using Metica;
using Metica.Ads;
using UnityEngine;

public class BannerExample : MonoBehaviour
{
    private const string BannerAdUnitId = "YOUR_BANNER_AD_UNIT_ID";

    void Start()
    {
        // Subscribe to callbacks
        MeticaAdsCallbacks.Banner.OnAdLoadSuccess += OnBannerLoaded;
        MeticaAdsCallbacks.Banner.OnAdLoadFailed += OnBannerLoadFailed;
        MeticaAdsCallbacks.Banner.OnAdClicked += OnBannerClicked;
        MeticaAdsCallbacks.Banner.OnAdRevenuePaid += OnBannerRevenuePaid;

        // Create and show banner
        var config = new MeticaAdViewConfiguration(MeticaAdViewPosition.BottomCenter);
        MeticaSdk.Ads.CreateBanner(BannerAdUnitId, config);
        MeticaSdk.Ads.ShowBanner(BannerAdUnitId);
    }

    void OnApplicationFocus(bool hasFocus)
    {
        if (hasFocus)
        {
            MeticaSdk.Ads.ShowBanner(BannerAdUnitId);
        }
        else
        {
            MeticaSdk.Ads.HideBanner(BannerAdUnitId);
        }
    }

    private void OnBannerLoaded(MeticaAd ad)
    {
        Debug.Log($"Banner loaded: {ad.adUnitId}");
    }

    private void OnBannerLoadFailed(MeticaAdError error)
    {
        Debug.LogError($"Banner failed to load: {error.message}");
    }

    private void OnBannerClicked(MeticaAd ad)
    {
        Debug.Log($"Banner clicked: {ad.adUnitId}");
    }

    private void OnBannerRevenuePaid(MeticaAd ad)
    {
        Debug.Log($"Banner revenue: ${ad.revenue} from {ad.networkName}");
    }
}
```

Banner ads auto-refresh by default. To control refresh manually these are the methods available:

```csharp
MeticaSdk.Ads.StopBannerAutoRefresh(BannerAdUnitId);  // Stop auto-refresh
MeticaSdk.Ads.LoadBanner(BannerAdUnitId);              // Manually load
MeticaSdk.Ads.StartBannerAutoRefresh(BannerAdUnitId); // Re-enable auto-refresh
```

### MREC Ads (300x250)

Medium Rectangle ads work the same way as banners but with a larger size.

```csharp
using Metica;
using Metica.Ads;
using UnityEngine;

public class MrecExample : MonoBehaviour
{
    private const string MrecAdUnitId = "YOUR_MREC_AD_UNIT_ID";

    void Start()
    {
        // Subscribe to callbacks
        MeticaAdsCallbacks.Mrec.OnAdLoadSuccess += OnMrecLoaded;
        MeticaAdsCallbacks.Mrec.OnAdLoadFailed += OnMrecLoadFailed;
        MeticaAdsCallbacks.Mrec.OnAdClicked += OnMrecClicked;
        MeticaAdsCallbacks.Mrec.OnAdRevenuePaid += OnMrecRevenuePaid;

        // Create and show MREC
        var config = new MeticaAdViewConfiguration(MeticaAdViewPosition.Centered);
        MeticaSdk.Ads.CreateMrec(MrecAdUnitId, config);
        MeticaSdk.Ads.ShowMrec(MrecAdUnitId);
    }

    void OnApplicationFocus(bool hasFocus)
    {
        if (hasFocus)
        {
            MeticaSdk.Ads.ShowMrec(MrecAdUnitId);
        }
        else
        {
            MeticaSdk.Ads.HideMrec(MrecAdUnitId);
        }
    }

    private void OnMrecLoaded(MeticaAd ad)
    {
        Debug.Log($"MREC loaded: {ad.adUnitId}");
    }

    private void OnMrecLoadFailed(MeticaAdError error)
    {
        Debug.LogError($"MREC failed to load: {error.message}");
    }

    private void OnMrecClicked(MeticaAd ad)
    {
        Debug.Log($"MREC clicked: {ad.adUnitId}");
    }

    private void OnMrecRevenuePaid(MeticaAd ad)
    {
        Debug.Log($"MREC revenue: ${ad.revenue} from {ad.networkName}");
    }
}
```

MREC ads also auto-refresh by default. Use the same refresh control methods as banners:

```csharp
MeticaSdk.Ads.StopMrecAutoRefresh(MrecAdUnitId);
MeticaSdk.Ads.LoadMrec(MrecAdUnitId);
MeticaSdk.Ads.StartMrecAutoRefresh(MrecAdUnitId);
```

### Interstitial Ads

Full-screen ads that are shown between content transitions.

{% hint style="info" %}
`ShowInterstitial` accepts optional `placementId` and `customData` parameters for analytics tracking.
{% endhint %}

```csharp
using Metica;
using Metica.Ads;
using UnityEngine;

public class InterstitialExample : MonoBehaviour
{
    private const string InterstitialAdUnitId = "YOUR_INTERSTITIAL_AD_UNIT_ID";
    private int interstitialRetryAttempt = 0;

    void Start()
    {
        // Subscribe to callbacks
        MeticaAdsCallbacks.Interstitial.OnAdLoadSuccess += OnInterstitialLoaded;
        MeticaAdsCallbacks.Interstitial.OnAdLoadFailed += OnInterstitialLoadFailed;
        MeticaAdsCallbacks.Interstitial.OnAdShowSuccess += OnInterstitialShown;
        MeticaAdsCallbacks.Interstitial.OnAdShowFailed += OnInterstitialShowFailed;
        MeticaAdsCallbacks.Interstitial.OnAdHidden += OnInterstitialHidden;
        MeticaAdsCallbacks.Interstitial.OnAdClicked += OnInterstitialClicked;
        MeticaAdsCallbacks.Interstitial.OnAdRevenuePaid += OnInterstitialRevenuePaid;

        // Load interstitial
        LoadInterstitial();
    }
    
    private void LoadInterstitial()
    {
        MeticaSdk.Ads.LoadInterstitial(InterstitialAdUnitId);
    }

    public void ShowInterstitial()
    {
        if (MeticaSdk.Ads.IsInterstitialReady(InterstitialAdUnitId))
        {
            MeticaSdk.Ads.ShowInterstitial(InterstitialAdUnitId, "main_menu", "level_complete");
        }
        else
        {
            Debug.LogWarning("Interstitial not ready yet");
        }
    }

    private void OnInterstitialLoaded(MeticaAd ad)
    {
        interstitialRetryAttempt = 0;
        Debug.Log($"Interstitial loaded: {ad.adUnitId}");
    }

    private void OnInterstitialLoadFailed(MeticaAdError error)
    {    
        interstitialRetryAttempt++;
        double delay = System.Math.Pow(2, System.Math.Min(6, interstitialRetryAttempt));
        Debug.LogWarning($"Load failed: {error.message}, retrying in {delay}s");
        Invoke(nameof(LoadInterstitial), (float)delay);
    }

    private void OnInterstitialShown(MeticaAd ad)
    {
        Debug.Log($"Interstitial shown: {ad.adUnitId}");
    }

    private void OnInterstitialShowFailed(MeticaAd ad, MeticaAdError error)
    {
        Debug.LogError($"Interstitial failed to show: {error.message}");
    }

    private void OnInterstitialHidden(MeticaAd ad)
    {
        Debug.Log($"Interstitial hidden: {ad.adUnitId}");
        // Reload for next time
        LoadInterstitial();
    }

    private void OnInterstitialClicked(MeticaAd ad)
    {
        Debug.Log($"Interstitial clicked: {ad.adUnitId}");
    }

    private void OnInterstitialRevenuePaid(MeticaAd ad)
    {
        Debug.Log($"Interstitial revenue: ${ad.revenue} from {ad.networkName}");
    }
}
```

### Rewarded Ads

Reward users for watching video ads.

{% hint style="info" %}
`ShowRewarded` accepts optional `placementId` and `customData` parameters for analytics tracking.
{% endhint %}

```csharp
using Metica; 
using Metica.Ads; 
using UnityEngine;

public class RewardedExample : MonoBehaviour { 
    private const string RewardedAdUnitId = "YOUR_REWARDED_AD_UNIT_ID"; 
    private int rewardedRetryAttempt = 0;

    void Start()
    {
        // Subscribe to callbacks
        MeticaAdsCallbacks.Rewarded.OnAdLoadSuccess += OnRewardedLoaded;
        MeticaAdsCallbacks.Rewarded.OnAdLoadFailed += OnRewardedLoadFailed;
        MeticaAdsCallbacks.Rewarded.OnAdShowSuccess += OnRewardedShown;
        MeticaAdsCallbacks.Rewarded.OnAdShowFailed += OnRewardedShowFailed;
        MeticaAdsCallbacks.Rewarded.OnAdHidden += OnRewardedHidden;
        MeticaAdsCallbacks.Rewarded.OnAdClicked += OnRewardedClicked;
        MeticaAdsCallbacks.Rewarded.OnAdRewarded += OnUserRewarded;
        MeticaAdsCallbacks.Rewarded.OnAdRevenuePaid += OnRewardedRevenuePaid;
    
        // Load rewarded ad
        LoadRewarded();
    }
    
    private void LoadRewarded()
    {
        MeticaSdk.Ads.LoadRewarded(RewardedAdUnitId);
    }
    
    public void ShowRewardedAd()
    {
        if (MeticaSdk.Ads.IsRewardedReady(RewardedAdUnitId))
        {
            MeticaSdk.Ads.ShowRewarded(RewardedAdUnitId, "shop", "extra_coins");
        }
        else
        {
            Debug.LogWarning("Rewarded ad not ready yet");
        }
    }
    
    private void OnRewardedLoaded(MeticaAd ad)
    {
        rewardedRetryAttempt = 0;
        Debug.Log($"Rewarded ad loaded: {ad.adUnitId}");
    }
    
    private void OnRewardedLoadFailed(MeticaAdError error)
    {
        rewardedRetryAttempt++;
        double delay = System.Math.Pow(2, System.Math.Min(6, rewardedRetryAttempt));
        Debug.LogWarning($"Rewarded failed: {error.message}, retrying in {delay}s");
        Invoke(nameof(LoadRewarded), (float)delay);
    }
    
    private void OnRewardedShown(MeticaAd ad)
    {
        Debug.Log($"Rewarded ad shown: {ad.adUnitId}");
    }
    
    private void OnRewardedShowFailed(MeticaAd ad, MeticaAdError error)
    {
        Debug.LogError($"Rewarded ad failed to show: {error.message}");
    }
    
    private void OnRewardedHidden(MeticaAd ad)
    {
        Debug.Log($"Rewarded ad hidden: {ad.adUnitId}");
        // Reload for next time
        LoadRewarded();
    }
    
    private void OnRewardedClicked(MeticaAd ad)
    {
        Debug.Log($"Rewarded ad clicked: {ad.adUnitId}");
    }
    
    private void OnUserRewarded(MeticaAd ad)
    {
        Debug.Log($"User earned reward from: {ad.adUnitId}");
        // Grant reward to user here
        GrantRewardToUser();
    }
    
    private void OnRewardedRevenuePaid(MeticaAd ad)
    {
        Debug.Log($"Rewarded ad revenue: ${ad.revenue} from {ad.networkName}");
    }
    
    private void GrantRewardToUser()
    {
        // Your reward logic here
        Debug.Log("Granting reward to user!");
    }
}
```

### App Open Ads (not natively supported)

The Metica SDK **does not currently support** the App Open ad format natively. If your application requires App Open ads, you can use the MAX SDK alongside the Metica SDK with the following considerations.

#### Integration Requirements

**Initialization Order**

```cs
// 1. Initialize Metica SDK first
await MeticaSdk.InitializeAsync(meticaInitConfig, meticaMediationInfo);

// 2. Initialize MAX SDK after Metica initialization completes
MaxSdkCallbacks.OnSdkInitializedEvent += OnMaxSdkInitialized;
MaxSdk.InitializeSdk();
```

**Callback Restrictions**

When using MAX SDK for App Open ads alongside Metica SDK, you must only register and use MAX SDK callbacks that are specifically related to App Open ads. Do not register MAX SDK callbacks for other ad types (banners, interstitials, rewarded) as these are managed by the Metica SDK.

```cs
private void OnMaxSdkInitialized(MaxSdkBase.SdkConfiguration sdkConfiguration)
{
    // ✅ Allowed: App Open specific callbacks
    MaxSdkCallbacks.AppOpen.OnAdLoadedEvent += OnAppOpenAdLoaded;
    MaxSdkCallbacks.AppOpen.OnAdLoadFailedEvent += OnAppOpenAdLoadFailed;
    MaxSdkCallbacks.AppOpen.OnAdDisplayedEvent += OnAppOpenAdDisplayed;
    MaxSdkCallbacks.AppOpen.OnAdHiddenEvent += OnAppOpenAdHidden;
    MaxSdkCallbacks.AppOpen.OnAdClickedEvent += OnAppOpenAdClicked;
    MaxSdkCallbacks.AppOpen.OnAdRevenuePaidEvent += OnAppOpenAdRevenuePaid;
    
    // ❌ Do not register: Other ad type callbacks (managed by Metica SDK)
    // MaxSdkCallbacks.Interstitial...
    // MaxSdkCallbacks.Rewarded...
    // MaxSdkCallbacks.Banner...
}
```

{% hint style="warning" %}
All other ad types (banners, interstitials, rewarded videos) should continue to be managed through the Metica SDK. Mixing callbacks for non-App Open ad types may cause unexpected behaviour or conflicts between the SDKs.
{% endhint %}

## API Reference

### MeticaSdk Methods

#### Initialization & Configuration

<table><thead><tr><th width="322.203125">Method</th><th>Return Type</th><th>Description</th></tr></thead><tbody><tr><td><code>InitializeAsync(MeticaInitConfig, MeticaMediationInfo)</code></td><td><code>Task&#x3C;MeticaInitResponse></code></td><td>Initializes the SDK.</td></tr><tr><td><code>SetLogEnabled(bool)</code></td><td><code>void</code></td><td>Enables/disables debug logging (default: <code>false</code>).</td></tr></tbody></table>

### MeticaSdk.Ads Methods

#### Privacy

<table><thead><tr><th width="251.796875">Method</th><th>Description</th></tr></thead><tbody><tr><td><code>SetHasUserConsent(bool)</code></td><td>Sets GDPR consent status. Call before initialization.</td></tr><tr><td><code>SetDoNotSell(bool)</code></td><td>Sets CCPA do-not-sell flag. Call before initialization.</td></tr></tbody></table>

#### Banner Methods

<table><thead><tr><th width="508.125">Method</th><th>Description</th></tr></thead><tbody><tr><td><code>CreateBanner(string adUnitId, MeticaAdViewConfiguration config)</code></td><td>Creates a banner ad view.</td></tr><tr><td><code>ShowBanner(string adUnitId)</code></td><td>Shows a banner ad.</td></tr><tr><td><code>HideBanner(string adUnitId)</code></td><td>Hides a banner ad.</td></tr><tr><td><code>LoadBanner(string adUnitId)</code></td><td>Manually loads a banner ad (only when auto-refresh is disabled).</td></tr><tr><td><code>StartBannerAutoRefresh(string adUnitId)</code></td><td>Starts automatic banner refresh.</td></tr><tr><td><code>StopBannerAutoRefresh(string adUnitId)</code></td><td>Stops automatic banner refresh.</td></tr><tr><td><code>DestroyBanner(string adUnitId)</code></td><td>Destroys a banner ad view.</td></tr><tr><td><code>SetBannerPlacement(string adUnitId, string? placement)</code></td><td>Sets the placement for a banner ad. Call before <code>LoadBanner</code>.</td></tr><tr><td><code>SetBannerCustomData(string adUnitId, string? customData)</code></td><td>Sets custom data for a banner ad.</td></tr><tr><td><code>SetBannerExtraParameter(string adUnitId, string key, string? value)</code></td><td>Sets an extra parameter for a banner ad.</td></tr><tr><td><code>SetBannerLocalExtraParameter(string adUnitId, string key, object? value)</code></td><td>Sets a local extra parameter for a banner ad.</td></tr><tr><td><code>SetBannerLocalExtraParameterJson(string adUnitId, string key, string? value)</code></td><td>Sets a local extra parameter for a banner ad using a JSON string value.</td></tr><tr><td><code>SetBannerWidth(string adUnitId, float widthDp)</code></td><td>Sets the width for a banner ad in density-independent pixels.</td></tr><tr><td><code>SetBannerBackgroundColor(string adUnitId, string hexColorCode)</code></td><td>Sets the background color for a banner ad using a hex color code.</td></tr></tbody></table>

#### MREC Methods

<table><thead><tr><th width="470.11328125">Method</th><th>Description</th></tr></thead><tbody><tr><td><code>CreateMrec(string adUnitId, MeticaAdViewConfiguration config)</code></td><td>Creates an MREC ad view.</td></tr><tr><td><code>ShowMrec(string adUnitId)</code></td><td>Shows an MREC ad.</td></tr><tr><td><code>HideMrec(string adUnitId)</code></td><td>Hides an MREC ad.</td></tr><tr><td><code>LoadMrec(string adUnitId)</code></td><td>Manually loads an MREC ad (only when auto-refresh is disabled).</td></tr><tr><td><code>StartMrecAutoRefresh(string adUnitId)</code></td><td>Starts automatic MREC refresh.</td></tr><tr><td><code>StopMrecAutoRefresh(string adUnitId)</code></td><td>Stops automatic MREC refresh.</td></tr><tr><td><code>DestroyMrec(string adUnitId)</code></td><td>Destroys an MREC ad view.</td></tr><tr><td><code>SetMrecPlacement(string adUnitId, string? placement)</code></td><td>Sets the placement for an MREC ad. Call before <code>LoadMrec</code>.</td></tr><tr><td><code>SetMrecCustomData(string adUnitId, string? customData)</code></td><td>Sets custom data for an MREC ad.</td></tr><tr><td><code>SetMrecExtraParameter(string adUnitId, string key, string? value)</code></td><td>Sets an extra parameter for an MREC ad.</td></tr><tr><td><code>SetMrecLocalExtraParameter(string adUnitId, string key, object? value)</code></td><td>Sets a local extra parameter for an MREC ad.</td></tr><tr><td><code>SetMrecLocalExtraParameterJson(string adUnitId, string key, string? value)</code></td><td>Sets a local extra parameter for an MREC ad using a JSON string value.</td></tr></tbody></table>

#### Interstitial Methods

<table><thead><tr><th width="482.625">Method</th><th width="131.171875">Return Type</th><th>Description</th></tr></thead><tbody><tr><td><code>LoadInterstitial(string adUnitId)</code></td><td><code>void</code></td><td>Loads an interstitial ad.</td></tr><tr><td><code>ShowInterstitial(string adUnitId, string? placementId, string? customData)</code></td><td><code>void</code></td><td>Shows an interstitial ad with optional tracking parameters.</td></tr><tr><td><code>IsInterstitialReady(string adUnitId)</code></td><td><code>bool</code></td><td>Checks if interstitial is ready to show.</td></tr><tr><td><code>SetInterstitialExtraParameter(string adUnitId, string key, string? value)</code></td><td><code>void</code></td><td>Sets an extra parameter for an interstitial ad.</td></tr><tr><td><code>SetInterstitialLocalExtraParameter(string adUnitId, string key, object? value)</code></td><td><code>void</code></td><td>Sets a local extra parameter for an interstitial ad.</td></tr></tbody></table>

#### Rewarded Methods

<table><thead><tr><th width="409.45703125">Method</th><th width="126.3671875">Return Type</th><th>Description</th></tr></thead><tbody><tr><td><code>LoadRewarded(string adUnitId)</code></td><td><code>void</code></td><td>Loads a rewarded ad.</td></tr><tr><td><code>ShowRewarded(string adUnitId, string? placementId, string? customData)</code></td><td><code>void</code></td><td>Shows a rewarded ad with optional tracking parameters.</td></tr><tr><td><code>IsRewardedReady(string adUnitId)</code></td><td><code>bool</code></td><td>Checks if rewarded ad is ready to show.</td></tr><tr><td><code>SetRewardedAdExtraParameter(string adUnitId, string key, string? value)</code></td><td><code>void</code></td><td>Sets an extra parameter for a rewarded ad.</td></tr><tr><td><code>SetRewardedAdLocalExtraParameter(string adUnitId, string key, object? value)</code></td><td><code>void</code></td><td>Sets a local extra parameter for a rewarded ad.</td></tr></tbody></table>

### MeticaSdk.Ads.Max Methods

| Method                                         | Return Type                           | Description                                 |
| ---------------------------------------------- | ------------------------------------- | ------------------------------------------- |
| `SetExtraParameter(string key, string? value)` | `void`                                | Sets an extra parameter on the MAX SDK.     |
| `ShowMediationDebugger()`                      | `void`                                | Shows the AppLovin MAX mediation debugger.  |
| `HasUserConsent()`                             | `bool`                                | Returns whether user has consented.         |
| `IsUserConsentSet()`                           | `bool`                                | Returns whether consent was explicitly set. |
| `GetConsentFlowUserGeography()`                | `MaxSdkBase.ConsentFlowUserGeography` | Returns user's geography for consent flow.  |

### MeticaAd Properties

<table><thead><tr><th width="195.41796875">Property</th><th width="184.80859375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>adUnitId</code></td><td><code>string</code></td><td>Ad unit identifier.</td></tr><tr><td><code>revenue</code></td><td><code>double?</code></td><td>Revenue generated by this ad impression (nullable).</td></tr><tr><td><code>networkName</code></td><td><code>string?</code></td><td>The ad network name (nullable).</td></tr><tr><td><code>placementTag</code></td><td><code>string?</code></td><td>Placement tag (nullable).</td></tr><tr><td><code>adFormat</code></td><td><code>string?</code></td><td>Ad format type (nullable).</td></tr><tr><td><code>creativeId</code></td><td><code>string?</code></td><td>Creative identifier (nullable).</td></tr><tr><td><code>latency</code></td><td><code>long?</code></td><td>Load latency in milliseconds (nullable).</td></tr></tbody></table>

### MeticaAdError Properties

<table><thead><tr><th width="203.9609375">Property</th><th width="179.703125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>message</code></td><td><code>string</code></td><td>Error message.</td></tr><tr><td><code>adUnitId</code></td><td><code>string?</code></td><td>Associated ad unit identifier (nullable).</td></tr></tbody></table>

### MeticaAdViewPosition Enum

Position options for banner and MREC ads:

<table><thead><tr><th width="207.5625">Value</th><th>Description</th></tr></thead><tbody><tr><td><code>TopCenter</code></td><td>Top center of the screen.</td></tr><tr><td><code>Centered</code></td><td>Center of the screen.</td></tr><tr><td><code>BottomCenter</code></td><td>Bottom center of the screen.</td></tr></tbody></table>

### MeticaMediationType Enum

Supported mediation platforms:

<table><thead><tr><th width="214.5859375">Value</th><th>Description</th></tr></thead><tbody><tr><td><code>MAX</code></td><td>AppLovin MAX mediation platform.</td></tr></tbody></table>

### MeticaAdsCallbacks Events

#### Banner Callbacks

<table><thead><tr><th width="374.796875">Event</th><th width="206.80859375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>MeticaAdsCallbacks.Banner.OnAdLoadSuccess</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Banner ad loaded successfully.</td></tr><tr><td><code>MeticaAdsCallbacks.Banner.OnAdLoadFailed</code></td><td><code>Action&#x3C;MeticaAdError></code></td><td>Banner ad failed to load.</td></tr><tr><td><code>MeticaAdsCallbacks.Banner.OnAdClicked</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Banner ad was clicked.</td></tr><tr><td><code>MeticaAdsCallbacks.Banner.OnAdRevenuePaid</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Banner ad revenue was recorded.</td></tr></tbody></table>

#### MREC Callbacks

<table><thead><tr><th width="358.73046875">Event</th><th width="220.046875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>MeticaAdsCallbacks.Mrec.OnAdLoadSuccess</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>MREC ad loaded successfully.</td></tr><tr><td><code>MeticaAdsCallbacks.Mrec.OnAdLoadFailed</code></td><td><code>Action&#x3C;MeticaAdError></code></td><td>MREC ad failed to load.</td></tr><tr><td><code>MeticaAdsCallbacks.Mrec.OnAdClicked</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>MREC ad was clicked.</td></tr><tr><td><code>MeticaAdsCallbacks.Mrec.OnAdRevenuePaid</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>MREC ad revenue was recorded.</td></tr></tbody></table>

#### Interstitial Callbacks

<table><thead><tr><th width="426.97265625">Event</th><th width="298.9609375">Type</th><th width="211.8515625">Description</th></tr></thead><tbody><tr><td><code>MeticaAdsCallbacks.Interstitial.OnAdLoadSuccess</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Interstitial ad loaded successfully.</td></tr><tr><td><code>MeticaAdsCallbacks.Interstitial.OnAdLoadFailed</code></td><td><code>Action&#x3C;MeticaAdError></code></td><td>Interstitial ad failed to load.</td></tr><tr><td><code>MeticaAdsCallbacks.Interstitial.OnAdShowSuccess</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Interstitial ad displayed successfully.</td></tr><tr><td><code>MeticaAdsCallbacks.Interstitial.OnAdShowFailed</code></td><td><code>Action&#x3C;MeticaAd, MeticaAdError></code></td><td>Interstitial ad failed to display.</td></tr><tr><td><code>MeticaAdsCallbacks.Interstitial.OnAdHidden</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Interstitial ad was dismissed.</td></tr><tr><td><code>MeticaAdsCallbacks.Interstitial.OnAdClicked</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Interstitial ad was clicked.</td></tr><tr><td><code>MeticaAdsCallbacks.Interstitial.OnAdRevenuePaid</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Interstitial ad revenue was recorded.</td></tr></tbody></table>

#### Rewarded Callbacks

<table><thead><tr><th width="404.3125">Event</th><th width="293.640625">Type</th><th width="235.60546875">Description</th></tr></thead><tbody><tr><td><code>MeticaAdsCallbacks.Rewarded.OnAdLoadSuccess</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Rewarded ad loaded successfully.</td></tr><tr><td><code>MeticaAdsCallbacks.Rewarded.OnAdLoadFailed</code></td><td><code>Action&#x3C;MeticaAdError></code></td><td>Rewarded ad failed to load.</td></tr><tr><td><code>MeticaAdsCallbacks.Rewarded.OnAdShowSuccess</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Rewarded ad displayed successfully.</td></tr><tr><td><code>MeticaAdsCallbacks.Rewarded.OnAdShowFailed</code></td><td><code>Action&#x3C;MeticaAd, MeticaAdError></code></td><td>Rewarded ad failed to display.</td></tr><tr><td><code>MeticaAdsCallbacks.Rewarded.OnAdHidden</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Rewarded ad was dismissed.</td></tr><tr><td><code>MeticaAdsCallbacks.Rewarded.OnAdClicked</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Rewarded ad was clicked.</td></tr><tr><td><code>MeticaAdsCallbacks.Rewarded.OnAdRewarded</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>User earned the reward.</td></tr><tr><td><code>MeticaAdsCallbacks.Rewarded.OnAdRevenuePaid</code></td><td><code>Action&#x3C;MeticaAd></code></td><td>Rewarded ad revenue was recorded.</td></tr></tbody></table>

## Troubleshooting

### Max SDK Conflict

The Metica Unity SDK already includes and manages the AppLovin MAX integration internally. Do not reference, call, or initialize MaxSdk or subscribe to MAX callbacks directly in your code, this includes any callbacks related to:

* SDK initialization
* Banner
* MREC
* Interstitial
* Rewarded

Direct usage of MAX APIs or subscribing to MAX events can cause version conflicts, duplicate initialization, callback collisions, or unexpected behavior. Instead, rely on the callbacks exposed by the Metica SDK for all ad lifecycle events.

### Moloco SDK Version

Moloco’s libraries (SDK and adapters) must be kept up to date to avoid dependency and build issues when used alongside Metica’s mediation setup.

* Ensure the Moloco SDK and its adapters are at least version 4.3.0 or above.

Older Moloco versions may lead to dependency resolution issues and incompatibilities with other mediation components.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.metica.com/api/unity-sdk/unity-sdk-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
