{"id":20644014,"url":"https://github.com/adjust/unreal_sdk","last_synced_at":"2026-03-05T00:03:09.363Z","repository":{"id":46288972,"uuid":"167361497","full_name":"adjust/unreal_sdk","owner":"adjust","description":"This is the Unreal SDK of","archived":false,"fork":false,"pushed_at":"2025-02-17T13:30:18.000Z","size":30387,"stargazers_count":17,"open_issues_count":0,"forks_count":5,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-10-21T01:12:01.828Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.adjust.com","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adjust.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-01-24T12:07:45.000Z","updated_at":"2025-10-06T09:03:58.000Z","dependencies_parsed_at":"2025-02-17T14:26:09.953Z","dependency_job_id":"7f6c124f-d986-479c-b56c-e39e919f98df","html_url":"https://github.com/adjust/unreal_sdk","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/adjust/unreal_sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adjust%2Funreal_sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adjust%2Funreal_sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adjust%2Funreal_sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adjust%2Funreal_sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adjust","download_url":"https://codeload.github.com/adjust/unreal_sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adjust%2Funreal_sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30101690,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T23:59:36.199Z","status":"ssl_error","status_checked_at":"2026-03-04T23:56:48.556Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T16:14:32.299Z","updated_at":"2026-03-05T00:03:09.314Z","avatar_url":"https://github.com/adjust.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Summary\n\nThis is the Unreal Engine SDK of Adjust™. You can read more about Adjust™ at [Adjust.com].\n\n## Table of contents\n\n* [Basic integration](#basic-integration)\n   * [Get the SDK](#sdk-get)\n   * [Add the SDK to your project](#sdk-add)\n   * [Integrate the SDK into your app](#sdk-integrate)\n   * [Adjust logging](#sdk-logging)\n* [Additional features](#additional-features)\n   * [Send event information](#event-sending)\n      * [Event revenue](#event-revenue)\n      * [Event deduplication](#event-deduplication)\n      * [Event callback identifier](#event-callback-id)\n      * [Event callback parameters](#event-callback-params)\n      * [Event partner parameters](#event-partner-params)\n   * [User attribution](#user-attribution)\n      * [Attribution callback](#attribution-callback)\n      * [Get user attribution](#attribution-getter)\n   * [Preinstalled apps](#preinstalled-apps)\n      * [Preinstall tracking](#preinstall-tracking)\n      * [Default link token](#preinstall-default-link)\n   * [Global parameters](#global-params)\n      * [Global callback parameters](#global-callback-params)\n      * [Global partner parameters](#global-partner-params)\n   * [Privacy features](#privacy-features)\n      * [GDPR right to be forgotten](#gdpr-forget-me)\n      * [Third party sharing](#third-party-sharing)\n      * [Disable third-party sharing for specific users](#disable-third-party-sharing)\n      * [Enable or re-enable third-party sharing for specific users](#enable-third-party-sharing)\n      * [Send granular options](#send-granular-options)\n      * [Manage Facebook Limited Data Use](#facebook-limited-data-use)\n      * [Provide consent data to Google (Digital Markets Act compliance)](#digital-markets-act)\n      * [Update partner sharing settings](#partner-sharing-settings)\n      * [Consent measurement for specific users](#measurement-consent)\n      * [COPPA compliance](#coppa-compliance)\n      * [Play Store kids apps](#play-store-kids-apps)\n   * [Deep linking](#deeplinking)\n      * [Standard deep linking scenario](#deeplinking-standard)\n      * [Deferred deep linking scenario](#deeplinking-deferred)\n      * [Reattribution via deep links](#deeplinking-reattribution)\n      * [Resolve Adjust short links](#short-links-resolution)\n      * [Link resolution](#link-resolution)\n      * [Get last deeplink](#get-last-deeplink)\n      * [Handling deeplinks with referrer](#deeplink-referrer)\n   * [App Tracking Transparency](#app-tracking-transparency)\n      * [ATT authorization wrapper](#att-wrapper)\n      * [Get current authorization status](#att-status-getter)\n      * [ATT prompt waiting interval](#att-waiting-interval)\n      * [Disable the usage of App Tracking Transparency](#disable-att-usage)\n   * [SKAdNetwork and conversion values](#skan-framework)\n      * [Disable SKAdNetwork communication](#skan-disable)\n      * [Set up direct install postbacks](#skan-postbacks)\n      * [SKAdNetwork conversion value updated callback](#skan-conversion-value-updated)\n   * [Record ad revenue information](#adrevenue-recording)\n      * [Ad revenue amount](#adrevenue-amount)\n      * [Ad revenue network](#adrevenue-network)\n      * [Ad revenue unit](#adrevenue-unit)\n      * [Ad revenue placement](#adrevenue-placement)\n      * [Ad impressions count](#adrevenue-impressions)\n      * [Ad revenue callback parameters](#adrevenue-callback-params)\n      * [Ad revenue partner parameters](#adrevenue-partner-params)\n   * [Device IDs](#device-ids)\n      * [iOS advertising identifier](#idfa)\n      * [iOS identifier for vendors](#idfv)\n      * [Google Play Services advertising identifier](#gps-adid)\n      * [Amazon advertising identifier](#fire-adid)\n      * [Adjust device identifier](#adid)\n   * [Session and event callbacks](#session-event-callbacks)\n   * [Disable the SDK](#disable-sdk)\n   * [Offline mode](#offline-mode)\n   * [Sending from background](#background-sending)\n   * [External device ID](#external-device-id)\n   * [Push token](#push-token)\n   * [Disable AdServices information reading](#disable-ad-services)\n   * [First session delay](#first-session-delay)\n   * [Store information](#store-info)\n   * [URL strategy and data residency](#url-strategy)\n   * [Facebook App ID](#fb-app-id)\n   * [Purchase verification](#purchase-verification)\n   * [Subscription tracking](#subscription-tracking)\n* [License](#license)\n\n## \u003ca id=\"basic-integration\"\u003e\u003c/a\u003eBasic integration\n\nThese are the minimal steps required to integrate the Adjust SDK into your Unreal Engine project.\n\n### \u003ca id=\"sdk-get\"\u003e\u003c/a\u003eGet the SDK\n\nDownload the latest version from our [releases page][releases].\n\n### \u003ca id=\"sdk-add\"\u003e\u003c/a\u003eAdd the SDK to your project\n\nAdjust SDK plugin is located inside of the `Adjust` folder inside the archive you just downloaded. Copy `Adjust` folder inside of your app `Plugins` folder.\n\nAdd `Adjust` as a dependency to `PublicDependencyModuleNames` array inside of your app's `APPNAME.Build.cs` file:\n\n```cs\nPublicDependencyModuleNames.AddRange(new string[] { \"Core\", \"CoreUObject\", \"Engine\", \"InputCore\", \"Adjust\" });\n```\n\n### \u003ca id=\"sdk-integrate\"\u003e\u003c/a\u003eIntegrate the SDK into your app\n\nIt is recommended that you initialise Adjust SDK as soon as possible inside of your app. You can do this by invoking `InitSdk` method of the `Adjust` class:\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void InitSdk(const FAdjustConfig\u0026 Config);\n```\n\nIn order to successfully initialise SDK, it is mandatory that you set at least following properties of `FAdjustConfig` structure:\n- `AppToken` - Your app token which you can obtain from Adjust dashboard.\n- `Environment` - Environment in which you want to start Adjust SDK (either `EAdjustEnvironment::Sandbox` or `EAdjustEnvironment::Production`).\n\n**Important:** Environment value should only ever be set to `EAdjustEnvironment::Sandbox` if you or someone else is testing your app. Make sure to set the environment to `EAdjustEnvironment::Production` before you publish your app. Set it back to `EAdjustEnvironment::Sandbox` again when you start developing and testing your app. We use this environment to distinguish between real traffic and test traffic from test devices. It is imperative that you keep this value meaningful at all times.\n\n### \u003ca id=\"sdk-logging\"\u003e\u003c/a\u003eAdjust logging\n\nYou can increase or decrease the amount of logs you see in tests by setting `LogLevel` field on your `FAdjustConfig` structure instance with one of the following values:\n\n```\nEAdjustLogLevel::Verbose   // enable all logging\nEAdjustLogLevel::Debug     // enable more logging\nEAdjustLogLevel::Info      // default\nEAdjustLogLevel::Warn      // disable info logging and below\nEAdjustLogLevel::Error     // disable warnings as well\nEAdjustLogLevel::Assert    // disable errors as well\nEAdjustLogLevel::Suppress  // disable all log output\n```\n\nIn Android, you can check for log output from Adjust SDK by seaching for lines with tag `Adjust`. In iOS, you can find Adjust SDK log lines by looking the ones that start with `[Adjust]` string.\n\n## \u003ca id=\"additional-features\"\u003e\u003c/a\u003eAdditional features\n\nYou can take advantage of the following features once the Adjust SDK is integrated into your project.\n\n### \u003ca id=\"event-sending\"\u003e\u003c/a\u003eSend event information\n\nYou can tell Adjust about every event you want to record.\n\nIf you create a new event in your dashboard - let's say that event token is `abc123` - you can assign that token to `EventToken` field of the `FAdjustEvent` structure and invoke `TrackEvent` method of the `UAdjust` class:\n\n```cpp\n// Adjust method to invoke for event tracking.\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void TrackEvent(const FAdjustEvent\u0026 Event);\n```\n\n```cpp\n// FAdjustEvent structure EventToken member.\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString EventToken;\n```\n\n### \u003ca id=\"event-revenue\"\u003e\u003c/a\u003eEvent revenue\n\nIf your users can generate revenue by tapping on advertisements or making in-app purchases, then you can record those revenues with events. You could track the revenue by setting this info on `Revenue` and `Currency` fields on the `FAdjustEvent` structure:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nfloat Revenue;\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Currency;\n```\n\n### \u003ca id=\"event-deduplication\"\u003e\u003c/a\u003eEvent deduplication\n\nYou can also add an optional deduplication ID to avoid recording duplicate events. By default, the SDK stores the last 10 identifiers and skips revenue events with duplicate transaction IDs. In case you would like the SDK to store more than 10 identifiers, you can set the desired number of identifiers by assigning the value to `EventDeduplicationIdsMaxSize` property of your `FAdjustConfig` structure instance before SDK initialization.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nint EventDeduplicationIdsMaxSize = -1;\n```\n\nDeduplication ID can be assigned to `DeduplicationId` member of the `FAdjustEvent` structure.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString DeduplicationId;\n```\n\n### \u003ca id=\"event-callback-id\"\u003e\u003c/a\u003eEvent callback identifier\n\nYou can also add custom string identifier to each event you want to record. This identifier will later be reported in event success and/or event failure callbacks to enable you to keep track on which event was successfully recorded or not.  You can set this identifier by assigning the value to `CallbackId` member of `FAdjustEvent` structure:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString CallbackId;\n```\n\n### \u003ca id=\"event-callback-params\"\u003e\u003c/a\u003eEvent callback parameters\n\nYou can also register a callback URL for that event in your [dashboard](https://dash.adjust.com), and we will send a GET request to that URL whenever the event gets recorded. In that case, you can also put some key-value pairs to `CallbackParameters` map member of the `FAdjustEvent` structure before tracking the event. We will then append these parameters to your callback URL.\n\nFor example, suppose you have registered the URL `http://www.adjust.com/callback` for your event and that you add two key-value pairs (`(\"key\", \"value\")` and `(\"foo\", \"bar\")`) to `CallbackParameters` member:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nTMap\u003cFString, FString\u003e CallbackParameters;\n```\n\nIn this case, we would track the event and send a request to:\n\n```\nhttp://www.adjust.com/callback?key=value\u0026foo=bar\n```\n\nIt should be mentioned that we support a variety of placeholders, like `{idfa}` for iOS or `{gps_adid}` for Android, that can be used as parameter values.  In the resulting callback, the `{idfa}` placeholder would be replaced with the ID for advertisers of the current device for iOS and the `{gps_adid}` would be replaced with the Google advertising ID of the current device for Android. Also note that we don't store any of your custom parameters, but only append them to your callbacks. If you haven't registered a callback for an event, these parameters won't even be read.\n\n### \u003ca id=\"event-partner-params\"\u003e\u003c/a\u003eEvent partner parameters\n\nYou can also add parameters for integrations that have been activated in your Adjust dashboard that can be transmitted to network partners.\n\nThis works similarly to the callback parameters mentioned above, by adding key-value pairs to `PartnerParameters` map member of the `FAdjustEvent` structure.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nTMap\u003cFString, FString\u003e PartnerParameters;\n```\n\n### \u003ca id=\"user-attribution\"\u003e\u003c/a\u003eUser attribution\n\nEach recorded install is getting certain attribution assigned and also, during the app lifetime, the attribution can change.\n\n### \u003ca id=\"attribution-callback\"\u003e\u003c/a\u003eAttribution callback\n\nYou can register a callback to be notified of attribution changes. Due to the different sources considered for attribution, this information can not be provided synchronously.\n\nAttribution callback exists in `UAdjustDelegates` class and has following signature:\n\n```cpp\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAttributionChangedDelegate, const FAdjustAttribution\u0026, Attribution);\n\n// ...\n\nUPROPERTY(BlueprintAssignable, Category = Adjust)\nFOnAttributionChangedDelegate OnAttributionChangedDelegate;\n```\n\nOnce implemented in your app and triggered, you can access following attribution information inside `FAdjustAttribution` struct instance:\n\n```cpp\n// the campaign link token of the current attribution\nUPROPERTY(BlueprintReadWrite, Category = \"Adjust\")\nFString TrackerToken;\n\n// the campaign link name of the current attribution\nUPROPERTY(BlueprintReadWrite, Category = \"Adjust\")\nFString TrackerName;\n\n// the network grouping level of the current attribution\nUPROPERTY(BlueprintReadWrite, Category = \"Adjust\")\nFString Network;\n\n// the campaign grouping level of the current attribution\nUPROPERTY(BlueprintReadWrite, Category = \"Adjust\")\nFString Campaign;\n\n// the ad group grouping level of the current attribution\nUPROPERTY(BlueprintReadWrite, Category = \"Adjust\")\nFString Adgroup;\n\n// the creative grouping level of the current attribution\nUPROPERTY(BlueprintReadWrite, Category = \"Adjust\")\nFString Creative;\n\n// the click label of the current attribution\nUPROPERTY(BlueprintReadWrite, Category = \"Adjust\")\nFString ClickLabel;\n\n// the cost type in case cost data is part of the attribution\nUPROPERTY(BlueprintReadOnly, Category = \"Adjust\")\nFString CostType;\n\n// the cost amount in case cost data is part of the attribution\nUPROPERTY(BlueprintReadOnly, Category = \"Adjust\")\ndouble CostAmount;   \n\n// the cost currency in case cost data is part of the attribution\nUPROPERTY(BlueprintReadOnly, Category = \"Adjust\")\nFString CostCurrency;\n\n// the FB install referrer value in case install is attributed to it (Android only)\nUPROPERTY(BlueprintReadOnly, Category = \"Adjust\")\nFString FbInstallReferrer;\n\n// the attribution response that the backend sends to the SDK\nUPROPERTY(BlueprintReadOnly, Category = \"Adjust\")\nFString JsonResponse;\n```\n\n### \u003ca id=\"attribution-getter\"\u003e\u003c/a\u003eGet user attribution\n\nIf you want to access information about a user's current attribution whenever you need it, you can make a call to the `GetAttribution` method of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the attribution information.\n\n```cpp\n// C++-only method with lambda callback\nstatic void GetAttribution(TFunction\u003cvoid(const FAdjustAttribution\u0026)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::GetAttribution([](const FAdjustAttribution\u0026 Attribution) {\n    if (!Attribution.TrackerToken.IsEmpty()) {\n        UE_LOG(LogTemp, Log, TEXT(\"Tracker token: %s\"), *Attribution.TrackerToken);\n    }\n});\n```\n\nYou can also use the timeout version to retrieve attribution with a specified timeout:\n\n```cpp\n// C++-only method with timeout and lambda callback\nstatic void GetAttributionWithTimeout(int32 TimeoutInMilliseconds, TFunction\u003cvoid(const FAdjustAttribution\u0026)\u003e Callback);\n```\n\n**Example usage with timeout:**\n\n```cpp\nUAdjust::GetAttributionWithTimeout(5000, [](const FAdjustAttribution\u0026 Attribution) {\n    // attribution will be empty if timeout occurred\n    if (Attribution.TrackerToken.IsEmpty() \u0026\u0026 Attribution.TrackerName.IsEmpty()) {\n        UE_LOG(LogTemp, Warning, TEXT(\"Attribution retrieval timed out\"));\n    } else {\n        UE_LOG(LogTemp, Log, TEXT(\"Tracker token: %s\"), *Attribution.TrackerToken);\n    }\n});\n```\n\n**Note**: Information about current attribution is available after app installation has been recorded by the Adjust backend and the attribution callback has been initially triggered. From that moment on, the Adjust SDK has information about a user's attribution and you can access it with this method. So, **it is not possible** to access a user's attribution value before the SDK has been initialised and an attribution callback has been triggered.\n\n### \u003ca id=\"preinstalled-apps\"\u003e\u003c/a\u003ePreinstalled apps\n\nYou can use the Adjust SDK to record activity from apps that came preinstalled on a user's device. This enables you to attribute these users to a custom defined campaign link instead to an organic one.\n\n### \u003ca id=\"preinstall-tracking\"\u003e\u003c/a\u003ePreinstall tracking\n\n\u003e Note: This feature is Android only.\n\nYou can enable preinstall tracking by setting the `IsPreinstallTrackingEnabled` property to `true` on your `FAdjustConfig` structure instance before SDK initialization. Optionally, you can also set the `PreinstallFilePath` property to specify the path to the file with preinstall data.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsPreinstallTrackingEnabled = false;\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString PreinstallFilePath;\n```\n\n### \u003ca id=\"preinstall-default-link\"\u003e\u003c/a\u003eDefault link token\n\nConfiguring a default link token enables you to attribute all preinstalls to a predefined Adjust link. Adjust records all information against this token until the attribution source changes. To set this up, first you need to [create a new campaign link in Campaign Lab](https://help.adjust.com/en/article/links). After doing this set the default tracker member of your `FAdjustConfig` structure instance:\n\n ```cpp\n UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\n FString DefaultTracker;\n ```\n\nIn case this approach is not applicable to your preinstall use case, please reach out to support@adjust.com to explore other ways of how the attribution for preinstalled apps can be handled.\n\n### \u003ca id=\"global-params\"\u003e\u003c/a\u003eGlobal parameters\n\nSome parameters are saved to be sent in every session, event, ad revenue and subscription request of the Adjust SDK. Once you have added any of these parameters, you don't need to add them every time, since they will be saved locally. If you add the same parameter twice, there will be no effect. These global parameters can be set before the Adjust SDK is launched to make sure they are sent even on install.\n\n### \u003ca id=\"global-callback-params\"\u003e\u003c/a\u003eGlobal callback parameters\n\n### \u003ca id=\"session-callback-parameters\"\u003e\u003c/a\u003eSession callback parameters\n\nYou can save the same callback parameters that are registered for [events](#callback-parameters) to be sent in every event or session of the Adjust SDK.\n\nThe global callback parameters have a similar interface to the event callback parameters. Instead of adding the key and its value to an event, it's added through a call to the `AddGlobalCallbackParameter` method of the `UAdjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void AddGlobalCallbackParameter(const FString\u0026 Key, const FString\u0026 Value);\n```\n\nThe global callback parameters will be merged with the callback parameters added to an event / ad revenue / subscription. The callback parameters added to any of these packages take precedence over the global callback parameters. Meaning that, when adding a callback parameter to any of these packages with the same key to one added globaly, the value that prevails is the callback parameter added any of these particular packages.\n\nIt's possible to remove a specific global callback parameter by passing the desired key to the method `RemoveGlobalCallbackParameter` of the `UAdjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void RemoveGlobalCallbackParameter(const FString\u0026 Key);\n```\n\nIf you wish to remove all keys and values from the global callback parameters, you can reset it with the method `RemoveGlobalCallbackParameters` of the `UAdjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void RemoveGlobalCallbackParameters();\n```\n\n### \u003ca id=\"global-partner-params\"\u003e\u003c/a\u003eGlobal partner parameters\n\nIn the same way that there are [global callback parameters](#session-callback-params) that are sent for every event or session of the Adjust SDK, there are also global partner parameters.\n\nThese will be transmitted to network partners, for the integrations that have been activated in your Adjust [dashboard](https://dash.adjust.com).\n\nThe global partner parameters have a similar interface to the event / ad revenue / subscription partner parameters. Instead of adding the key and its value to an event, it's added through a call to the `AddGlobalPartnerParameter` method of the `UAdjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void AddGlobalPartnerParameter(const FString\u0026 Key, const FString\u0026 Value);\n```\n\nThe global partner parameters will be merged with the partner parameters added to an event / ad revenue / subscription. The partner parameters added to any of thes packages take precedence over the global partner parameters. Meaning that, when adding a partner parameter to any of these packages with the same key to one added globally, the value that prevails is the partner parameter added to any of these particular packages.\n\nIt's possible to remove a specific global partner parameter by passing the desired key to the method `RemoveGlobalPartnerParameter` of the `UAdjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void RemoveGlobalPartnerParameter(const FString\u0026 Key);\n```\n\nIf you wish to remove all keys and values from the global partner parameters, you can reset them with the method `RemoveGlobalPartnerParameters` of the `Adjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void RemoveGlobalPartnerParameters();\n```\n\n### \u003ca id=\"privacy-features\"\u003e\u003c/a\u003ePrivacy features\n\nThe Adjust SDK contains features that you can use to handle user privacy in your app.\n\n### \u003ca id=\"gdpr-forget-me\"\u003e\u003c/a\u003eGDPR right to be forgotten\n\nIn accordance with article 17 of the EU's General Data Protection Regulation (GDPR), you can notify Adjust when a user has exercised their right to be forgotten. Calling the following method will instruct the Adjust SDK to communicate the user's choice to be forgotten to the Adjust backend:\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void GdprForgetMe();\n```\n\nUpon receiving this information, Adjust will erase the user's data and no requests from this device will be sent to Adjust in the future.\n\n### \u003ca id=\"third-party-sharing\"\u003e\u003c/a\u003eThird-party sharing for specific users\n\nYou can notify Adjust when a user disables, enables, and re-enables data sharing with third-party partners.\n\n### \u003ca id=\"disable-third-party-sharing\"\u003e\u003c/a\u003eDisable third-party sharing for specific users\n\nIn order to change third party sharing settings for your users, you need to invoke `TrackThirdPartySharing` method of the `UAdjust` class:\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void TrackThirdPartySharing(const FAdjustThirdPartySharing\u0026 ThirdPartySharing);\n```\n\nCall the following method to instruct the Adjust SDK to communicate the user's choice to disable data sharing to the Adjust backend:\n\n```cpp\nFAdjustThirdPartySharing adjustThirdPartySharing;\nadjustThirdPartySharing.Sharing = EAdjustThirdPartySharingState::Disable;\n\nUAdjust::TrackThirdPartySharing(adjustThirdPartySharing);\n```\n\nUpon receiving this information, Adjust will block the sharing of that specific user's data to partners and the Adjust SDK will continue to work as usual.\n\n### \u003ca id=\"enable-third-party-sharing\"\u003eEnable or re-enable third-party sharing for specific users\u003c/a\u003e\n\nCall the following method to instruct the Adjust SDK to communicate the user's choice to share data or change data sharing, to the Adjust backend:\n\n```cpp\nFAdjustThirdPartySharing adjustThirdPartySharing;\nadjustThirdPartySharing.Sharing = EAdjustThirdPartySharingState::Enable;\n\nUAdjust::TrackThirdPartySharing(adjustThirdPartySharing);\n```\n\nUpon receiving this information, Adjust changes sharing the specific user's data to partners. The Adjust SDK will continue to work as expected.\n\n### \u003ca id=\"send-granular-options\"\u003eSend granular options\u003c/a\u003e\n\nYou can attach granular information when a user updates their third-party sharing preferences. Use this information to communicate more detail about a user’s decision. To do this, call the `GranularOption.Add` method like this:\n\n```cpp\nFAdjustThirdPartySharing adjustThirdPartySharing;\nadjustThirdPartySharing.Sharing = EAdjustThirdPartySharingState::Current;\n\nFAdjustGranularOption GranularOptions;\nGranularOptions.GranularOption.Add(\"key\", \"value\");\nadjustThirdPartySharing.GranularOptions.Add(\"partnerName\", GranularOptions);\n\nUAdjust::TrackThirdPartySharing(adjustThirdPartySharing);\n```\n\nThe following partners are available:\n\n| Partner name              | String value                  |\n|---------------------------|-------------------------------|\n| AppleAds                  | apple_ads                     |\n| Facebook                  | facebook                      |\n| GoogleAds                 | adwords                       |\n| GoogleMarketingPlatform   | google_marketing_platform     |\n| Snapchat                  | snapchat                      |\n| Tencent                   | tencent                       |\n| TikTokSan                 | tiktok_san                    |\n| X (formerly Twitter)      | twitter                       |\n| YahooGemini               | yahoo_gemini                  |\n| YahooJapanSearch          | yahoo_japan_search            |\n\n### \u003ca id=\"facebook-limited-data-use\"\u003eManage Facebook Limited Data Use\u003c/a\u003e\n\nFacebook provides a feature called Limited Data Use (LDU) to comply with the California Consumer Privacy Act (CCPA). This feature enables you to notify Facebook when a California-based user is opted out of the sale of data. You can also use it if you want to opt all users out by default.\n\nYou can update the Facebook LDU status by passing arguments following arguments:\n\n| Parameter                        | Description                                                                 |\n|----------------------------------|-----------------------------------------------------------------------------|\n| `partner_name`                   | Use `facebook` to toggle LDU.                                              |\n| `data_processing_options_country`| The country in which the user is located.                                  |\n|                                  | - `0`: Request that Facebook use geolocation.                              |\n|                                  | - `1`: United States of America.                                           |\n| `data_processing_options_state`  | Notifies Facebook in which state the user is located.                      |\n|                                  | - `0`: Request that Facebook use geolocation.                              |\n|                                  | - `1000`: California.                                                      |\n|                                  | - `1001`: Colorado.                                                        |\n|                                  | - `1002`: Connecticut.                                                     |\n\n\u003e Note: If you call this method with a 0 value for **either** `data_processing_options_country` or `data_processing_options_state`, the Adjust SDK passes **both** fields back as 0.\n\n```cpp\nFAdjustThirdPartySharing adjustThirdPartySharing;\nadjustThirdPartySharing.Sharing = EAdjustThirdPartySharingState::Current;\n\nFAdjustGranularOption GranularOptions;\nGranularOptions.GranularOption.Add(\"data_processing_options_country\", \"1\");\nGranularOptions.GranularOption.Add(\"data_processing_options_state\", \"1000\");\nadjustThirdPartySharing.GranularOptions.Add(\"facebook\", GranularOptions);\n\nUAdjust::TrackThirdPartySharing(adjustThirdPartySharing);\n```\n\n### \u003ca id=\"digital-markets-act\"\u003eProvide consent data to Google (Digital Markets Act compliance)\u003c/a\u003e\n\n\u003e Important: Passing these options is required if you use Google Ads or Google Marketing Platform and have users located in the European Economic Area (EEA).\n\nTo comply with the EU’s Digital Markets Act (DMA), Google Ads and the Google Marketing Platform require explicit consent to receive Adjust’s attribution requests to their APIs. To communicate this consent, you need to add the following granular options to your third party sharing instance for the partner `google_dma`.\n\n| Key                 | Value               | Description                                                                                                      |\n|---------------------|---------------------|------------------------------------------------------------------------------------------------------------------|\n| `eea`               | `1` (positive) \\| `0` (negative) | Informs Adjust whether users installing the app are within the European Economic Area. Includes EU member states, Switzerland, Norway, Iceland, and Slovenia. |\n| `ad_personalization`| `1` (positive) \\| `0` (negative) | Informs Adjust whether users consented with being served personalized ads via Google Ads and/or Google Marketing Platform. This parameter also informs the `npa` parameter reserved for Google Marketing Platform. |\n| `ad_user_data`      | `1` (positive) \\| `0` (negative) | Informs Adjust whether users consented with their advertiser ID being leveraged for attribution purposes.         |\n\n```cpp\nFAdjustThirdPartySharing adjustThirdPartySharing;\nadjustThirdPartySharing.Sharing = EAdjustThirdPartySharingState::Current;\n\nFAdjustGranularOption GranularOptions;\nGranularOptions.GranularOption.Add(\"eea\", \"1\");\nGranularOptions.GranularOption.Add(\"ad_personalization\", \"1\");\nGranularOptions.GranularOption.Add(\"ad_user_data\", \"1\");\nadjustThirdPartySharing.GranularOptions.Add(\"google_dma\", GranularOptions);\n\nUAdjust::TrackThirdPartySharing(adjustThirdPartySharing);\n```\n\n### \u003ca id=\"partner-sharing-settings\"\u003eUpdate partner sharing settings\u003c/a\u003e\n\nBy default, Adjust shares all metrics with any partners you’ve configured in your app settings. You can use the Adjust SDK to update your third party sharing settings on a per-partner basis. To do this, call the `PartnerSharingSetting.Add` method by passing the partner sharing structure where you will need to set following parameters:\n\n| Argument     | Data type | Description                                                |\n|--------------|-----------|------------------------------------------------------------|\n| `partnerName`| String    | The name of the partner. [Download the full list of available partners](https://assets.ctfassets.net/5s247im0esyq/5WvsJ7J7fGFUlfsFeGdalj/643651619adc3256acac7885ec60624d/modules.csv). |\n| `key`        | String    | The metric to share with the partner.                      |\n| `value`      | Boolean   | The user’s decision.                                       |\n\nYou can use the `key` to specify which metrics you want to disable or re-enable. If you want to enable/disable sharing all metrics, you can use the `all` key. The full list of available metrics is available below:\n\n- `ad_revenue`\n- `all`\n- `attribution`\n- `update`\n- `att_update`\n- `cost_update`\n- `event`\n- `install`\n- `reattribution`\n- `reattribution_reinstall`\n- `reinstall`\n- `rejected_install`\n- `rejected_reattribution`\n- `sdk_click`\n- `sdk_info`\n- `session`\n- `subscription`\n- `uninstall`\n\nWhen you set a `false` value against a metric for a partner, Adjust stops sharing the metric with the partner.\n\n\u003e Tip: If you only want to share a few metrics with a partner, you can pass the `all` key with a `false` value to disable all sharing and then pass individual metrics with a `true` value to limit what you share.\n\nExamples:\n\nIf you want to stop sharing all metrics with a specific partner, pass the `all` key with a `false` value.\n\n```cpp\nFAdjustThirdPartySharing adjustThirdPartySharing;\nadjustThirdPartySharing.Sharing = EAdjustThirdPartySharingState::Current;\n\nFAdjustPartnerSharingSetting PartnerSettings;\nPartnerSettings.PartnerSharingSetting.Add(\"all\", false);\nadjustThirdPartySharing.PartnerSharingSettings.Add(\"PartnerA\", PartnerSettings);\n\nUAdjust::TrackThirdPartySharing(adjustThirdPartySharing);\n```\n\nTo re-enable sharing, pass the `all` key with a `true` value.\n\n```cpp\nFAdjustThirdPartySharing adjustThirdPartySharing;\nadjustThirdPartySharing.Sharing = EAdjustThirdPartySharingState::Current;\n\nFAdjustPartnerSharingSetting PartnerSettings;\nPartnerSettings.PartnerSharingSetting.Add(\"all\", true);\nadjustThirdPartySharing.PartnerSharingSettings.Add(\"PartnerA\", PartnerSettings);\n\nUAdjust::TrackThirdPartySharing(adjustThirdPartySharing);\n```\n\nYou can stop or start sharing specific metrics by calling the `PartnerSharingSetting.Add` method multiple times with different keys. For example, if you only want to share event information with a partner, you can pass:\n\n- `all` with a `false` value to disable sharing all information\n- `event` with a `true` value to enable event sharing\n\n\u003e Note: Specific keys always take priority over `all`. If you pass `all` with other keys, the individual key values override the `all` setting.\n\n\n```cpp\nFAdjustThirdPartySharing adjustThirdPartySharing;\nadjustThirdPartySharing.Sharing = EAdjustThirdPartySharingState::Current;\n\nFAdjustPartnerSharingSetting PartnerSettings;\nPartnerSettings.PartnerSharingSetting.Add(\"all\", false);\nPartnerSettings.PartnerSharingSetting.Add(\"event\", true);\nadjustThirdPartySharing.PartnerSharingSettings.Add(\"PartnerA\", PartnerSettings);\n\nUAdjust::TrackThirdPartySharing(adjustThirdPartySharing);\n```\n\n### \u003ca id=\"measurement-consent\"\u003e\u003c/a\u003eConsent measurement for specific users\n\nIf you’re using [Data Privacy settings](https://help.adjust.com/en/article/manage-data-collection-and-retention) in your Adjust dashboard, you need to set up the Adjust SDK to work with them. This includes settings such as consent expiry period and user data retention period.\n\nTo toggle this feature, call the `TrackMeasurementConsent` method of `UAdjust` class with the boolean argument which indicates whether consent measurement is enabled (`true`) or not (`false`).\n\nWhen enabled, the SDK communicates the data privacy settings to Adjust’s servers. Adjust’s servers then applies your data privacy rules to the user. The Adjust SDK continues to work as expected.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void TrackMeasurementConsent(bool MeasurementConsent);\n```\n\n### \u003ca id=\"coppa-compliance\"\u003e\u003c/a\u003eCOPPA compliance\n\nf you need your app to be compliant with the Children’s Online Privacy Protection Act (COPPA), set the `IsCoppaComplianceEnabled` field on your `FAdjustConfig` structure to `true` before initializing the SDK. This performs the following actions:\n\n1. Disables third-party sharing **before** the user launches their first `session`.\n2. Prevents the SDK from reading device and advertising IDs (for example: `gps_adid`, `idfa`, and `android_id`).\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsCoppaComplianceEnabled = false;\n```\n\nBy default, the SDK is not being launched in COPPA compliance mode.\n\n### \u003ca id=\"play-store-kids-apps\"\u003e\u003c/a\u003ePlay Store kids apps\n\nIf your app targets users under the age of 13, and the install region **isn’t** the USA, you need to mark it as a Kids App. This prevents the SDK from reading device and advertising IDs (for example: `idfa`, `gps_adid` and `android_id`).\n\nTo mark your app as a Play Store Kids App, set the `IsPlayStoreKidsComplianceEnabled` field on your `FAdjustConfig` structure to `true` before initializing the SDK.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsPlayStoreKidsComplianceEnabled = false;\n```\n\nBy deafult, the SDK is not being launched in Play Store Kids compliance mode.\n\n### \u003ca id=\"deeplinking\"\u003e\u003c/a\u003eDeep linking\n\nIf you are using the Adjust campaign link URL with an option to deep link into your app from the URL, there is the possibility to get information about the deep link URL and its content. Hitting the URL can happen when the user has your app already installed (standard deep linking scenario) or if they don't have the app on their device (deferred deep linking scenario).\n\n### \u003ca id=\"deeplinking-standard\"\u003e\u003c/a\u003eStandard deep linking scenario\n\nThe standard deep linking scenario is a platform specific feature in which an app gets opened when user clicks on the deep link. This guide is going to assume that you are aware how deep linking should be set up in your app for both, iOS and Android platforms.\n\n### \u003ca id=\"deeplinking-deferred\"\u003e\u003c/a\u003eDeferred deep linking scenario\n\nWhile deferred deep linking is not supported out of the box on Android and iOS, our Adjust SDK makes it possible.\n\nIn order to get information about the URL content in a deferred deep linking scenario, you should set a callback method on the `UAdjustDelegates` object to be able to \n\n```cpp\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDeferredDeeplinkDelegate, const FString\u0026, Deeplink);\n\n// ...\n\nUPROPERTY(BlueprintAssignable, BlueprintCallable, Category = Adjust)\nFOnDeferredDeeplinkDelegate OnDeferredDeeplinkDelegate;\n```\n\nIn a deferred deep linking scenario, there is one additional setting which can be set on the `FAdjustConfig` structure. Once the Adjust SDK gets the deferred deep link information, you have the possibility to choose whether our SDK should open this URL or not. You can influence default SDK behavior by setting the `IsDeferredDeeplinkOpeningEnabled` field on the `FAdjustConfig` instance to `false`\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsDeferredDeeplinkOpeningEnabled = true;\n```\n\nIf nothing is set, **the Adjust SDK will always try to launch the URL by default**.\n\n### \u003ca id=\"deeplinking-reattribution\"\u003e\u003c/a\u003eReattribution via deep links\n\nAdjust enables you to run re-engagement campaigns through deep links.\n\nIf you are using this feature, in order for your user to be properly reattributed, you need to make one additional call to the Adjust SDK in your app.\n\nOnce you have received deep link content information in your app, add a call to the `ProcessDeeplink` method of `UAdjust` class. By making this call, the Adjust SDK will try to find if there is any new attribution information inside of the deep link. If there is any, it will be sent to the Adjust backend. If your user should be reattributed due to a click on the Adjust campaign link URL with deep link content, you will see the [attribution callback](#attribution-callback) in your app being triggered with new attribution info for this user.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void ProcessDeeplink(const FAdjustDeeplink\u0026 Deeplink);\n```\n\n```cpp\nFAdjustDeeplink adjustDeeplink;\nadjustDeeplink.Deeplink = \"your-app-scheme://deep-link-content\";\nUAdjust::ProcessDeeplink(adjustDeeplink);\n```\n\n### \u003ca id=\"short-links-resolution\"\u003e\u003c/a\u003eResolve Adjust short links\n\nTo resolve an Adjust shortened deep link, instantiate an `FAdjustDeeplink` structure with your shortened deep link and pass it to the `ProcessAndResolveDeeplink` method of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the resolved link.\n\n```cpp\n// C++-only method with lambda callback\nstatic void ProcessAndResolveDeeplink(const FAdjustDeeplink\u0026 Deeplink, TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nFAdjustDeeplink adjustDeeplink;\nadjustDeeplink.Deeplink = TEXT(\"https://short.example.com/abcd1234\");\n\nUAdjust::ProcessAndResolveDeeplink(adjustDeeplink, [](const FString\u0026 ResolvedLink) {\n   UE_LOG(LogTemp, Log, TEXT(\"Resolved deeplink: %s\"), *ResolvedLink);\n});\n```\n\n\u003e Note: If the link passed to the `ProcessAndResolveDeeplink` method was shortened, the callback function receives the extended original link. Otherwise, the callback function receives the link you passed.\n\n### \u003ca id=\"link-resolution\"\u003e\u003c/a\u003eLink resolution\n\nYou need to set up link resolution for deep linking via email, SMS, QR codes, and platforms that shorten links. If you don't set up link resolution for such cases, a redirect from a universal link sends all users to the App Store, even if they have your app installed. With link resolution, the redirect to the universal link occurs within your app, and existing users aren't sent to the App Store.\n\n\u003e Note: Check with your marketing team to see if link resolution is needed for the app. You can then set up link resolution domains for different use cases.\n\n#### How it works\n\nLink resolution is only applicable when users that have your app installed click on a redirect URL. You need to configure the domain in the redirect URL as a universal link domain in your app.\n\nLink resolution works as follows:\n\n1. When an existing user clicks a redirect link, iOS opens your app.\n2. Your app passes the redirect URL to the `ResolveLink` method in the Adjust SDK.\n3. The link resolution method in the Adjust SDK compares the domain in the redirect URL against the link resolution domain that the developer has set in the Adjust SDK, and one of the following happens:\n   - Domains don't match - The method forwards the deep link URL as is.\n   - Domains match - The method resolves the link and returns the resulting deep link.\n   \n   The Adjust SDK will follow up to ten redirects when attempting to resolve a URL. If there are more than ten redirects, the SDK will return the tenth redirect URL.\n4. Your app receives the returned URL and opens deep link content and displays it to the user. Your app also calls the `ProcessDeeplink` method in the Adjust SDK with the returned URL. This sends the resolved URL to Adjust's servers to be recorded.\n\n\u003e Note: If a user who doesn't have your app installed clicks on the redirect URL, iOS handles this as a normal web URL and redirects the user to the App Store. In this case, link resolution isn't applicable.\n\n#### Use cases\n\nLink resolution is applicable for the following cases:\n\n- Email marketing\n- Platforms that shorten URLs\n\n#### Email marketing\n\nWhen email marketers run campaigns, the email marketing platform typically wraps all links in the emails with its own click measurement redirect URL. This lets email marketers view click-through statistics in the email marketing platform. However, if the emails contain universal links, the redirect URL causes iOS to not resolve the universal links.\n\n**Example:** An email marketer builds their email using a template. This template contains a link or an image with a universal link:\n```\nhttps://example.go.link/summer-clothes?promo=beach\u0026adj_t=abc123\n```\n\nBefore the email is sent, the email marketing platform wraps the universal link with its own redirect URL:\n```\nhttps://email.example.com/2wuTnQvU\n```\n\nA user, who has your app installed, clicks on the redirect URL in the email. iOS opens your app and passes the redirect URL to your app. Your app passes the redirect URL to the link resolution method in the Adjust SDK. The Adjust SDK resolves the redirect URL from within your app, so `https://email.example.com/2wuTnQvU` redirects to `https://example.go.link/summer-clothes?promo=beach\u0026adj_t=abc123`. The link resolution method returns the resolved URL. Your app handles the returned URL and calls the `ProcessDeeplink` method in the Adjust SDK with the returned URL.\n\n#### URL shorteners\n\nWhen marketers run certain types of campaigns, sometimes a short URL is required. For example, SMS has a 160 character limit. Sometimes, customers want to shorten a link and share it on team communication platforms, such as Slack. However, if the short URL redirects to a universal link, iOS doesn't resolve the universal link.\n\n**Example:** A marketer creates a universal link:\n```\nhttps://example.go.link/summer-clothes?promo=beach\u0026adj_t=abc123\n```\n\nThe marketer uses a URL shortener service to generate a shortened link:\n```\nhttps://short.example.com/2wuTnQvU\n```\n\nA user, who has your app installed, clicks on the short URL in the SMS message. iOS opens your app and passes the short URL to your app. Your app passes the short URL to the link resolution method in the Adjust SDK. The Adjust SDK resolves the short URL from within your app, so `https://short.example.com/2wuTnQvU` redirects to `https://example.go.link/summer-clothes?promo=beach\u0026adj_t=abc123`. The link resolution method returns the resolved URL. Your app handles the returned URL and calls the `ProcessDeeplink` method in the Adjust SDK with the returned URL.\n\n#### Setup\n\nTo resolve a link, call the `ResolveLink` method of the `UAdjust` class with the URL you want to resolve, an array of URL suffixes to match against, and a lambda callback that will be invoked with the resolved link.\n\n```cpp\n// C++-only method with lambda callback\nstatic void ResolveLink(const FString\u0026 Url, const TArray\u003cFString\u003e\u0026 ResolveUrlSuffixArray, TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example: Email marketing**\n\n```cpp\nTArray\u003cFString\u003e ResolveUrlSuffixArray;\nResolveUrlSuffixArray.Add(TEXT(\"email.example.com\"));\n\nUAdjust::ResolveLink(TEXT(\"https://email.example.com/2wuTnQvU\"), ResolveUrlSuffixArray, [](const FString\u0026 ResolvedLink) {\n    if (!ResolvedLink.IsEmpty()) {\n        UE_LOG(LogTemp, Log, TEXT(\"Resolved link: %s\"), *ResolvedLink);\n        // Process the resolved link\n        FAdjustDeeplink adjustDeeplink;\n        adjustDeeplink.Deeplink = ResolvedLink;\n        UAdjust::ProcessDeeplink(adjustDeeplink);\n    }\n});\n```\n\n**Example: URL shorteners**\n\n```cpp\nTArray\u003cFString\u003e ResolveUrlSuffixArray;\nResolveUrlSuffixArray.Add(TEXT(\"short.example.com\"));\n\nUAdjust::ResolveLink(TEXT(\"https://short.example.com/2wuTnQvU\"), ResolveUrlSuffixArray, [](const FString\u0026 ResolvedLink) {\n    if (!ResolvedLink.IsEmpty()) {\n        UE_LOG(LogTemp, Log, TEXT(\"Resolved link: %s\"), *ResolvedLink);\n        // Process the resolved link\n        FAdjustDeeplink adjustDeeplink;\n        adjustDeeplink.Deeplink = ResolvedLink;\n        UAdjust::ProcessDeeplink(adjustDeeplink);\n    }\n});\n```\n\n\u003e Note: For more detailed information on this topic in iOS and Android, check native guides: [iOS](https://dev.adjust.com/en/sdk/ios/features/deep-links/resolution) and [Android](https://dev.adjust.com/en/sdk/android/features/deep-links#link-resolution).\n\n### \u003ca id=\"get-last-deeplink\"\u003e\u003c/a\u003eGet last deeplink\n\nYou can retrieve the last processed deeplink at any time. Call the `GetLastDeeplink` method of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the last deeplink as a string.\n\n```cpp\n// C++-only method with lambda callback\nstatic void GetLastDeeplink(TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::GetLastDeeplink([](const FString\u0026 LastDeeplink) {\n    if (!LastDeeplink.IsEmpty()) {\n        UE_LOG(LogTemp, Log, TEXT(\"Last deeplink: %s\"), *LastDeeplink);\n    } else {\n        UE_LOG(LogTemp, Warning, TEXT(\"No deeplink has been processed yet\"));\n    }\n});\n```\n\n### \u003ca id=\"deeplink-referrer\"\u003e\u003c/a\u003eHandling deeplinks with referrer\n\nAn optional referrer URL can be used to track the source of the deeplink or app open for better attribution or reattribution and deep linking. For example, channels like SEO / Organic Search, Adjust links are not directly used. If the client's root domain has Android App Links implemented and triggers an app opening, for such channels, we may have to rely on signals coming from the referrer URL to attribute or reattribute users.\n\nIf your app is able to obtain this information internally, you can pass the referrer information to the SDK by setting the `Referrer` property of your `FAdjustDeeplink` structure instance:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Referrer;\n```\n\n```cpp\nFAdjustDeeplink adjustDeeplink;\nadjustDeeplink.Deeplink = TEXT(\"your-app-scheme://deep-link-content\");\nadjustDeeplink.Referrer = TEXT(\"https://example.com/referrer\");\nUAdjust::ProcessDeeplink(adjustDeeplink);\n```\n\n### \u003ca id=\"app-tracking-transparency\"\u003e\u003c/a\u003eApp Tracking Transparency\n\n\u003e Note: This feature is iOS only.\n\nIf you want to record the device's ID for Advertisers (IDFA), you must display a prompt to get your user's authorization. To do this, you need to include Apple's App Tracking Transparency (ATT) framework in your app. The Adjust SDK stores the user's authorization status and sends it to Adjust's servers with each request.\n\nBelow, you can find the list of possible ATT status values:\n\n| Status                                    | Code | Description                                                          |\n|-------------------------------------------|------|----------------------------------------------------------------------|\n| `ATTrackingManagerAuthorizationStatusNotDetermined` | `0`  | The user hasn’t responded to the access prompt yet                   |\n| `ATTrackingManagerAuthorizationStatusRestricted`   | `1`  | Access to app-related data is blocked at the device level            |\n| `ATTrackingManagerAuthorizationStatusDenied`       | `2`  | The user has denied access to app-related data for device measurement |\n| `ATTrackingManagerAuthorizationStatusAuthorized`   | `3`  | The user has approved access to app-related data for device measurement |\n\n\u003e Note: You might receive a status code of -1 if the SDK is unable to retrieve the ATT (App Tracking Transparency) status.\n\n### \u003ca id=\"att-wrapper\"\u003e\u003c/a\u003eATT authorization wrapper\n\n\u003e Note: This feature is iOS only.\n\nThe Adjust SDK contains a wrapper around [Apple's requestTrackingAuthorizationWithCompletionHandler: method](https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/3547037-requesttrackingauthorizationwith). You can use this wrapper if you don't want to use the ATT prompt.\n\nThe callback method triggers when your user responds to the consent dialog. This method sends the user’s consent status code to Adjust’s servers. You can define responses to each status code within the callback function.\n\nYou must specify text content for the ATT. To do this, add your text to the `NSUserTrackingUsageDescription` key in your `Info.plist` file.\n\n```xml\n \u003ckey\u003eNSUserTrackingUsageDescription\u003c/key\u003e\n \u003cstring\u003eYour custom message explaining why is access to IDFA necessary.\u003c/string\u003e\n```\n\nYou can trigger ATT prompt via Adjust SDK wrapper method. This method accepts a lambda callback that will be invoked with the authorization status.\n\n```cpp\n// C++-only method with lambda callback\nstatic void RequestAppTrackingAuthorization(TFunction\u003cvoid(int)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::RequestAppTrackingAuthorization([](int AuthorizationStatus) {\n    switch (AuthorizationStatus) {\n        case 0: // ATTrackingManagerAuthorizationStatusNotDetermined\n            UE_LOG(LogTemp, Log, TEXT(\"ATT status: Not Determined\"));\n            break;\n        case 1: // ATTrackingManagerAuthorizationStatusRestricted\n            UE_LOG(LogTemp, Log, TEXT(\"ATT status: Restricted\"));\n            break;\n        case 2: // ATTrackingManagerAuthorizationStatusDenied\n            UE_LOG(LogTemp, Log, TEXT(\"ATT status: Denied\"));\n            break;\n        case 3: // ATTrackingManagerAuthorizationStatusAuthorized\n            UE_LOG(LogTemp, Log, TEXT(\"ATT status: Authorized\"));\n            break;\n        default:\n            UE_LOG(LogTemp, Warning, TEXT(\"ATT status: Unknown (%d)\"), AuthorizationStatus);\n            break;\n    }\n});\n```\n\n### \u003ca id=\"att-status-getter\"\u003e\u003c/a\u003eGet current authorization status\n\nYou can retrieve a user's current authorization status at any time. Call the `GetAppTrackingAuthorizationStatus` method. This method accepts a lambda callback that will be invoked with the authorization status.\n\n```cpp\n// C++-only method with lambda callback\nstatic void GetAppTrackingAuthorizationStatus(TFunction\u003cvoid(int)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::GetAppTrackingAuthorizationStatus([](int AuthorizationStatus) {\n    switch (AuthorizationStatus) {\n        case 0: // ATTrackingManagerAuthorizationStatusNotDetermined\n            UE_LOG(LogTemp, Log, TEXT(\"Current ATT status: Not Determined\"));\n            break;\n        case 1: // ATTrackingManagerAuthorizationStatusRestricted\n            UE_LOG(LogTemp, Log, TEXT(\"Current ATT status: Restricted\"));\n            break;\n        case 2: // ATTrackingManagerAuthorizationStatusDenied\n            UE_LOG(LogTemp, Log, TEXT(\"Current ATT status: Denied\"));\n            break;\n        case 3: // ATTrackingManagerAuthorizationStatusAuthorized\n            UE_LOG(LogTemp, Log, TEXT(\"Current ATT status: Authorized\"));\n            break;\n        default:\n            UE_LOG(LogTemp, Warning, TEXT(\"Current ATT status: Unknown (%d)\"), AuthorizationStatus);\n            break;\n    }\n});\n```\n\n### \u003ca id=\"att-waiting-interval\"\u003e\u003c/a\u003eATT prompt waiting interval\n\nIf your app includes an onboarding process or a tutorial, you may want to delay sending your user's ATT consent status until after the user has completed this process. To do this, you can set the `AttConsentWaitingInterval` method of your `FAdjustConfig` structure to delay the sending of data for up to **360 seconds** to give the user time to complete the initial onboarding. After the timeout ends or the user sets their consent status, the SDK sends all information it has recorded during the delay to Adjust's servers along with the user's consent status.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nint AttConsentWaitingInterval = 0;\n```\n\n### \u003ca id=\"disable-att-usage\"\u003e\u003c/a\u003eDisable the usage of App Tracking Transparency\n\n\u003e Note: This feature is iOS only.\n\nIn case you want to disable Adjust SDK's automatic interaction with `AppTrackingTransparency.framework`, you need to set the `IsAppTrackingTransparencyUsageEnabled` property on your `FAdjustConfig` structure instance to `false` before SDK initialization.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsAppTrackingTransparencyUsageEnabled = true;\n```\n\n\u003e Note: Even with this setup, the SDK will still allow you to use `RequestAppTrackingAuthorization` and `GetAppTrackingAuthorizationStatus` methods.\n\n### \u003ca id=\"skan-framework\"\u003e\u003c/a\u003eSKAdNetwork and conversion values\n\n\u003e Important: This feature is only available on devices running iOS 14 and above.\n\nSKAdNetwork is Apple’s attribution framework for app install and reinstall attribution. The SKAdNetwork workflow goes like this:\n\n1. Apple gathers attribution information and notifies the relevant ad network.\n2. The network sends a postback with this information to Adjust.\n3. Adjust displays SKAdNetwork data in [Datascape](https://help.adjust.com/en/suite/article/datascape).\n\n### \u003ca id=\"skan-disable\"\u003e\u003c/a\u003eDisable SKAdNetwork communication\n\nThe Adjust SDK communicates with SKAdNetwork by default. The SDK registers for SKAdNetwork attribution upon initialization.\n\nYou can change this behavior by setting the `IsSkanAttributionEnabled` field of your `FAdjustConfig` structure to `false`.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsSkanAttributionEnabled = true;\n```\n\n### \u003ca id=\"skan-postbacks\"\u003e\u003c/a\u003eSet up direct install postbacks\n\n\u003e Note: Direct install postbacks contain only SKAdNetwork information. Information such as campaign data isn't included in these postbacks.\n\nYou can configure your app to send a copy of winning SKAdNetwork callbacks to Adjust. This enables you to use SKAdNetwork information in your analytics.\n\nTo set up direct install postbacks, you need to add the Adjust callback URL to your `Info.plist` file:\n\n```xml\n\u003ckey\u003eNSAdvertisingAttributionReportEndpoint\u003c/key\u003e\n\u003cstring\u003ehttps://adjust-skadnetwork.com\u003c/string\u003e\n```\n\n\u003e See also: See Apple's guide on [Configuring an Advertised App](https://developer.apple.com/documentation/storekit/skadnetwork/configuring_an_advertised_app) for more information.\n\n### \u003ca id=\"skan-conversion-value-updated\"\u003e\u003c/a\u003eSKAdNetwork conversion value updated callback\n\n\u003e Note: This feature is iOS only.\n\nYou can register a callback to be notified whenever the Adjust SDK updates the SKAdNetwork conversion value. This callback provides a dictionary containing the conversion value data set by the SDK and any possible API invocation errors.\n\nThe dictionary may contain the following keys:\n- `conversion_value`: The conversion value that was set by the Adjust SDK\n- `coarse_value`: The coarse value that was set by the Adjust SDK\n- `lock_window`: Whether the postback will be sent before the conversion window ends\n- `error`: Any error that occurred during the conversion value update\n\nYou can use this callback even while using pre 4.0 SKAdNetwork. In that case, the dictionary will contain only the `conversion_value` key.\n\nTo implement the callback, bind to the `OnSkanConversionValueUpdatedDelegate` on your `UAdjustDelegates` instance:\n\n```cpp\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSkanConversionValueUpdatedDelegate, const FAdjustSkanConversionDataMap\u0026, ConversionData);\n\n// ...\n\nUPROPERTY(BlueprintAssignable, BlueprintCallable, Category = Adjust)\nFOnSkanConversionValueUpdatedDelegate OnSkanConversionValueUpdatedDelegate;\n```\n\nThe `FAdjustSkanConversionDataMap` struct contains a `Data` property of type `TMap\u003cFString, FString\u003e` which holds the conversion value data dictionary.\n\nExample implementation:\n\n```cpp\nvoid AMyGameMode::OnSkanConversionValueUpdated(const FAdjustSkanConversionDataMap\u0026 ConversionData)\n{\n    for (const auto\u0026 Pair : ConversionData.Data)\n    {\n        UE_LOG(LogTemp, Log, TEXT(\"SKAN Conversion Data - %s: %s\"), *Pair.Key, *Pair.Value);\n    }\n}\n\n// In BeginPlay or similar:\nAdjustDelegatesInstance-\u003eOnSkanConversionValueUpdatedDelegate.AddDynamic(this, \u0026AMyGameMode::OnSkanConversionValueUpdated);\n```\n\n### \u003ca id=\"adrevenue-recording\"\u003e\u003c/a\u003eRecord ad revenue information\n\nYou can record ad revenue for [supported network partners](https://help.adjust.com/en/article/ad-revenue) using the Adjust SDK.\n\n\u003e Important: You need to perform some extra setup steps in your Adjust dashboard to measure ad revenue. Contact your Technical Account Manager or support@adjust.com to get started.\n\nTo send ad revenue information with the Adjust SDK, you need to instantiate an `FAdjustAdRevenue` structure. This structure contains variables that are sent to Adjust when ad revenue is recorded in your app.\n\nYou can set the following parameters:\n\n- `Source`: The source of the ad revenue. This parameter is mandatory. See the table below for available sources.\n\n| Argument                     | Ad revenue Source        |\n|------------------------------|--------------------------|\n| `\"applovin_max_sdk\"`         | AppLovin MAX            |\n| `\"admob_sdk\"`                | AdMob                   |\n| `\"ironsource_sdk\"`           | ironSource              |\n| `\"admost_sdk\"`               | AdMost                  |\n| `\"unity_sdk\"`                | Unity                   |\n| `\"helium_chartboost_sdk\"`    | Helium Chartboost       |\n| `\"adx_sdk\"`                  | Ad(X)                   |\n| `\"tradplus_sdk\"`             | TradPlus                |\n| `\"topon_sdk\"`                | TopOn                   |\n| `\"publisher_sdk\"`            | Generic source          |\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Source;\n```\n\n### \u003ca id=\"adrevenue-amount\"\u003e\u003c/a\u003eAd revenue amount\n\nTo send the ad revenue amount, set the `Revenue` and `Currency` fields of your `FAdjustAdRevenue` structure:\n\n- `Revenue`: The amount of revenue\n- `Currency`: The 3 character [ISO 4217 code](https://www.iban.com/currency-codes) of your reporting currency\n\n\u003e See also: Check the [guide to recording purchases in different currencies](https://help.adjust.com/en/article/currency-conversion) for more information.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\ndouble Revenue = 0.0;\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Currency;\n```\n\n### \u003ca id=\"adrevenue-network\"\u003e\u003c/a\u003eAd revenue network\n\nTo record the network associated with the ad revenue, set `AdRevenueNetwork` field of your `FAdjustAdRevenue` structure with the network name.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString AdRevenueNetwork;\n```\n\n### \u003ca id=\"adrevenue-unit\"\u003e\u003c/a\u003eAd revenue unit\n\nTo send the ad revenue unit, set `AdRevenueUnit` field of your `FAdjustAdRevenue` structure with the unit value.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString AdRevenueUnit;\n```\n\n### \u003ca id=\"adrevenue-placement\"\u003e\u003c/a\u003eAd revenue placement\n\nTo send the ad revenue placement, set `AdRevenuePlacement` field of your `FAdjustAdRevenue` structure with the placement value.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString AdRevenuePlacement;\n```\n\n### \u003ca id=\"adrevenue-impressions\"\u003e\u003c/a\u003eAd impressions count\n\nTo send the number of recorded ad impressions, set `AdImpressionsCount` field of your `FAdjustAdRevenue` structure with the number of ad impressions.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nint AdImpressionsCount = 0;\n```\n\n### \u003ca id=\"adrevenue-callback-params\"\u003e\u003c/a\u003eAd revenue callback parameters\n\nSimilar to how one can set [event callback parameters](#event-callback-params), the same can be done for ad revenue:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nTMap\u003cFString, FString\u003e CallbackParameters;\n```\n\n### \u003ca id=\"adrevenue-partner-params\"\u003e\u003c/a\u003eAd revenue partner parameters\n\nSimilar to how one can set [event partner parameters](#event-partner-params), the same can be done for ad revenue:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nTMap\u003cFString, FString\u003e PartnerParameters;\n```\n\n### \u003ca id=\"device-ids\"\u003e\u003c/a\u003eDevice IDs\n\nThe Adjust SDK contains helper methods that return device information. Use these methods to add details to your callbacks and improve your reporting.\n\n### \u003ca id=\"idfa\"\u003e\u003c/a\u003eIDFA\n\n\u003e Note: This feature is iOS only.\n\nTo obtain the IDFA, call the `GetIdfa` method of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the IDFA value.\n\n```cpp\n// C++-only method with lambda callback\nstatic void GetIdfa(TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::GetIdfa([](const FString\u0026 Idfa) {\n    if (!Idfa.IsEmpty()) {\n        UE_LOG(LogTemp, Log, TEXT(\"IDFA: %s\"), *Idfa);\n    } else {\n        UE_LOG(LogTemp, Warning, TEXT(\"IDFA is not available\"));\n    }\n});\n```\n\n### \u003ca id=\"idfv\"\u003e\u003c/a\u003eIDFV\n\n\u003e Note: This feature is iOS only.\n\nTo obtain the IDFV, call the `GetIdfv` method of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the IDFV value.\n\n```cpp\n// C++-only method with lambda callback\nstatic void GetIdfv(TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::GetIdfv([](const FString\u0026 Idfv) {\n    if (!Idfv.IsEmpty()) {\n        UE_LOG(LogTemp, Log, TEXT(\"IDFV: %s\"), *Idfv);\n    }\n});\n```\n\n### \u003ca id=\"gps-adid\"\u003e\u003c/a\u003eGoogle advertising identifier\n\n\u003e Note: This feature is Android only.\n\nTo obtain Google advertising ID, call the `GetGoogleAdId` method of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the Google advertising ID value.\n\n```cpp\n// C++-only method with lambda callback\nstatic void GetGoogleAdId(TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::GetGoogleAdId([](const FString\u0026 GoogleAdId) {\n    if (!GoogleAdId.IsEmpty()) {\n        UE_LOG(LogTemp, Log, TEXT(\"Google Ad ID: %s\"), *GoogleAdId);\n    } else {\n        UE_LOG(LogTemp, Warning, TEXT(\"Google Ad ID is not available\"));\n    }\n});\n```\n\n### \u003ca id=\"fire-adid\"\u003e\u003c/a\u003eAmazon advertising identifier\n\n\u003e Note: This feature is Android only.\n\nIf you need to obtain the Amazon advertising ID, you can call the `GetAmazonAdId` method of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the Amazon advertising ID value.\n\n```cpp\n// C++-only method with lambda callback\nstatic void GetAmazonAdId(TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::GetAmazonAdId([](const FString\u0026 AmazonAdId) {\n    if (!AmazonAdId.IsEmpty()) {\n        UE_LOG(LogTemp, Log, TEXT(\"Amazon Ad ID: %s\"), *AmazonAdId);\n    } else {\n        UE_LOG(LogTemp, Warning, TEXT(\"Amazon Ad ID is not available\"));\n    }\n});\n```\n\n### \u003ca id=\"adid\"\u003e\u003c/a\u003eAdjust device identifier\n\nFor every device with your app installed on it, the Adjust backend generates a unique **Adjust device identifier** (**adid**). In order to obtain this identifier, you can make a call to `GetAdid` method of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the Adjust device ID value.\n\n```cpp\n// C++-only method with lambda callback\nstatic void GetAdid(TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::GetAdid([](const FString\u0026 Adid) {\n   UE_LOG(LogTemp, Log, TEXT(\"Adjust device ID: %s\"), *Adid);\n});\n```\n\nYou can also use the timeout version to retrieve ADID with a specified timeout:\n\n```cpp\n// C++-only method with timeout and lambda callback\nstatic void GetAdidWithTimeout(int32 TimeoutInMilliseconds, TFunction\u003cvoid(const FString\u0026)\u003e Callback);\n```\n\n**Example usage with timeout:**\n\n```cpp\nUAdjust::GetAdidWithTimeout(5000, [](const FString\u0026 Adid) {\n    // adid will be empty if timeout occurred\n    if (Adid.IsEmpty()) {\n        UE_LOG(LogTemp, Warning, TEXT(\"ADID retrieval timed out or ADID is not available\"));\n    } else {\n        UE_LOG(LogTemp, Log, TEXT(\"Adjust device ID: %s\"), *Adid);\n    }\n});\n```\n\n**Note**: Information about the **adid** is available after app installation has been recorded by the Adjust backend. From that moment on, the Adjust SDK has information about the device **adid** and you can access it with this method. So, **it is not possible** to access the **adid** value before the SDK has been initialised and installation of your app has been successfully recorded.\n\n### \u003ca id=\"session-event-callbacks\"\u003e\u003c/a\u003eSession and event callbacks\n\nYou can register a callback to be notified of successful and failed recorded events and/or sessions.\n\nFollow the same steps as in the [attribution callback section above](#attribution-callback) if you want to implement the callback function for successfully tracked events:\n\n```cpp\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnEventSuccessDelegate, const FAdjustEventSuccess\u0026, EventSuccess);\n\n// ...\n\nUPROPERTY(BlueprintAssignable, Category = Adjust)\nFOnEventSuccessDelegate OnEventSuccessDelegate;\n```\n\nOnce implemented in your app and triggered, you can access following information inside `FAdjustEventSuccess` struct instance:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString EventToken;   // The event token.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString CallbackId;   // The callback ID of the event.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Message;      // The message from the server or the error logged by the SDK.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Timestamp;    // The timestamp from the server.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Adid;         // A unique device identifier provided by Adjust.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString JsonResponse; // The JSON object with the response from the server.\n```\n\nThe following callback function is used for failed events:\n\n```cpp\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnEventFailureDelegate, const FAdjustEventFailure\u0026, EventFailure);\n\n// ...\n\nUPROPERTY(BlueprintAssignable, Category = Adjust)\nFOnEventFailureDelegate OnEventFailureDelegate;\n```\n\nOnce implemented in your app and triggered, you can access following information inside `FAdjustEventFailure` struct instance:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString EventToken;   // The event token.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString CallbackId;   // The callback ID of the event.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Message;      // The message from the server or the error logged by the SDK.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Timestamp;    // The timestamp from the server.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Adid;         // A unique device identifier provided by Adjust.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString JsonResponse; // The JSON object with the response from the server.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool WillRetry;       // Indicates there will be an attempt to resend the package at a later time.\n```\n\nFor successfully tracked sessions:\n\n```cpp\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSessionSuccessDelegate, const FAdjustSessionSuccess\u0026, SessionSuccess);\n\n// ...\n\nUPROPERTY(BlueprintAssignable, Category = Adjust)\nFOnSessionSuccessDelegate OnSessionSuccessDelegate;\n```\n\nOnce implemented in your app and triggered, you can access following information inside `FAdjustSessionSuccess` struct instance:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Message;      // The message from the server or the error logged by the SDK.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Timestamp;    // The timestamp from the server.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Adid;         // A unique device identifier provided by Adjust.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString JsonResponse; // The JSON object with the response from the server.\n```\n\nAnd for session failures:\n\n```cpp\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSessionFailureDelegate, const FAdjustSessionFailure\u0026, SessionFailure);\n\n//...\n\nUPROPERTY(BlueprintAssignable, Category = Adjust)\nFOnSessionFailureDelegate OnSessionFailureDelegate;\n```\n\nOnce implemented in your app and triggered, you can access following information inside `FAdjustSessionFailure` struct instance:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Message;      // The message from the server or the error logged by the SDK.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Timestamp;    // The timestamp from the server.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString Adid;         // A unique device identifier provided by Adjust.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString JsonResponse; // The JSON object with the response from the server.\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool WillRetry;       // Indicates there will be an attempt to resend the package at a later time.\n```\n\n### \u003ca id=\"disable-sdk\"\u003e\u003c/a\u003eDisable the SDK\n\nYou can disable the Adjust SDK from recording any activity by invoking the method `Disable` of the `UAdjust` class. This setting is **remembered between sessions**.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void Disable();\n```\n\nYou can verify if the Adjust SDK is currently active with the method `IsEnabled` of the `UAdjust` class. This method accepts a lambda callback that will be invoked with the enabled status.\n\n```cpp\n// C++-only method with lambda callback\nstatic void IsEnabled(TFunction\u003cvoid(bool)\u003e Callback);\n```\n\n**Example usage:**\n\n```cpp\nUAdjust::IsEnabled([](bool IsEnabled) {\n    if (IsEnabled) {\n        UE_LOG(LogTemp, Log, TEXT(\"Adjust SDK is enabled\"));\n    } else {\n        UE_LOG(LogTemp, Log, TEXT(\"Adjust SDK is disabled\"));\n    }\n});\n```\n\nIt is always possible to activate the Adjust SDK by invoking `Enable` method of the `UAdjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void Enable();\n```\n\n### \u003ca id=\"offline-mode\"\u003e\u003c/a\u003eOffline mode\n\nYou can put the Adjust SDK in offline mode to suspend transmission to our servers, while still retaining recorded data to be sent later. While in offline mode, all information is saved in a file, so be careful not to trigger too many events while in offline mode.\n\nYou can activate offline mode by calling the method `WwitchToOfflineMode` of the `UAdjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void SwitchToOfflineMode();\n```\n\nConversely, you can deactivate the offline mode by calling `SwitchBackToOnlineMode` method of the `UAdjust` class.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void SwitchBackToOnlineMode();\n```\n\nWhen the Adjust SDK is put back in online mode, all saved information is sent to our servers with the correct timestamps.\n\nUnlike disabling the SDK, this setting is **not remembered between sessions**. This means that the SDK is in online mode whenever it is started, even if the app was terminated in offline mode.\n\n### \u003ca id=\"background-sending\"\u003e\u003c/a\u003eSending from background \n\nThe default behaviour of the Adjust SDK is to **pause sending HTTP requests while the app is in the background**. You can change this in your `FAdjustConfig` structure by setting the `IsSendingInBackgroundEnabled` field to `true`.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsSendingInBackgroundEnabled = false;\n```\n\nIf nothing is set, sending in background is **disabled by default**.\n\n### \u003ca id=\"external-device-id\"\u003e\u003c/a\u003eSet external device ID\n\n\u003e **Note** If you want to use external device IDs, please contact your Adjust representative. They will talk you through the best approach for your use case.\n\nAn external device identifier is a custom value that you can assign to a device or user. They can help you to recognize users across sessions and platforms. They can also help you to deduplicate installs by user so that a user isn't counted as multiple new installs.\n\nYou can also use an external device ID as a custom identifier for a device. This can be useful if you use these identifiers elsewhere and want to keep continuity.\n\nCheck out our [external device identifiers article](https://help.adjust.com/en/article/external-device-identifiers) for more information.\n\nTo set an external device ID, assign the identifier to the `ExternalDeviceId` field of your `FAdjustConfig` structure. Do this before you initialize the Adjust SDK.\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString ExternalDeviceId;\n```\n\n\u003e **Important**: You need to make sure this ID is **unique to the user or device** depending on your use-case. Using the same ID across different users or devices could lead to duplicated data. Talk to your Adjust representative for more information.\n\nIf you want to use the external device ID in your business analytics, you can pass it as a session callback parameter. See the section on [session callback parameters](#session-callback-params) for more information.\n\nYou can import existing external device IDs into Adjust. This ensures that the backend matches future data to your existing device records. If you want to do this, please contact your Adjust representative.\n\n### \u003ca id=\"push-token\"\u003e\u003c/a\u003ePush token\n\nTo send us the push notification token, add the following call to Adjust **whenever you get your token in the app or when it gets updated**:\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void SetPushToken(const FString\u0026 PushToken);\n```\n\nPush tokens are used for Audience Builder and client callbacks, and they are required for the uninstall detection feature.\n\n### \u003ca id=\"disable-ad-services\"\u003e\u003c/a\u003eDisable AdServices information reading\n\n\u003e Note: This feature is iOS only.\n\nThe SDK is enabled by default to try to communicate with `AdServices.framework` on iOS in order to try to obtain attribution token which is later being used for handling Apple Search Ads attribution. In case you would not like Adjust to show information from Apple Search Ads campaigns, you can disable this in the SDK by setting `IsAdServicesEnabled` field of your `FAdjustConfig` structure to `false`:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsAdServicesEnabled = true;\n```\n\n### \u003ca id=\"first-session-delay\"\u003e\u003c/a\u003eFirst session delay\n\nThe First Session Delay feature allows you to delay SDK initialization during the very first SDK session only. While in this delay mode, the Adjust SDK records all activity (such as installs and events) in memory, but does not transmit any data to Adjust servers.\n\nThis gives your app an opportunity to gather additional data that may not be available at launch and, if needed, modify the SDK configuration before any data is sent. Once the delay ends, SDK will apply all the settings configured during the delay before tracking an install.\n\n#### When and why to use first session delay\n\nUse this feature if you need to:\n\n- Show the App Tracking Transparency (ATT) dialog and act on the user's response.\n- Set third-party sharing settings.\n- Set DMA consent parameters.\n- Set COPPA compliance for the user.\n- Indicate that the user falls under the Play Store's \"Designed for Families\" (kids) category.\n- Assign an external device ID.\n- Set consent measurement for specific users.\n- Set global partner or callback parameters.\n\n\u003e Note: This feature can effectively replace the ATT waiting interval. If both are used in parallel, the first session delay takes precedence, and the ATT waiting interval will be ignored.\n\n#### Enabling first session delay\n\nTo initialize the SDK in delayed mode, set the `IsFirstSessionDelayEnabled` property to `true` on your `FAdjustConfig` structure instance before SDK initialization:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsFirstSessionDelayEnabled = false;\n```\n\n```cpp\nFAdjustConfig adjustConfig;\nadjustConfig.AppToken = TEXT(\"{YourAppToken}\");\nadjustConfig.Environment = EAdjustEnvironment::Sandbox;\nadjustConfig.IsFirstSessionDelayEnabled = true;\n\nUAdjust::InitSdk(adjustConfig);\n```\n\nAfter this, the SDK will be initialized in memory and will not process anything until you explicitly call:\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void EndFirstSessionDelay();\n```\n\n\u003e Note: The delay only occurs during the install session of the SDK (i.e., the first-ever SDK initialization). The delay will end only when `EndFirstSessionDelay` is called. If it is not called during the app's runtime, any delayed calls will be lost upon app restart. The next SDK initialization will then be treated as a first session again, and the SDK will initialize in delayed mode once more. Once the delay has ended or is no longer applicable (e.g., in subsequent sessions), any attempts to call `EndFirstSessionDelay` will be ignored.\n\n#### Configuration changing while on delay\n\nWhile the SDK is in first session delay mode, it is possible to change various SDK settings as if they were set in the config during `InitSdk`:\n\n**Enable COPPA compliance:**\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void EnableCoppaComplianceInDelay();\n```\n\n**Disable COPPA compliance:**\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void DisableCoppaComplianceInDelay();\n```\n\n**Enable Play Store kids compliance:**\n\n\u003e Note: This feature is Android only.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void EnablePlayStoreKidsComplianceInDelay();\n```\n\n**Disable Play Store kids compliance:**\n\n\u003e Note: This feature is Android only.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void DisablePlayStoreKidsComplianceInDelay();\n```\n\n**Set external device ID:**\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void SetExternalDeviceIdInDelay(const FString\u0026 ExternalDeviceId);\n```\n\n\u003e Note: Similar to the methods for configuring and ending the first session delay, once the delay has ended or is no longer applicable (e.g., in subsequent sessions), any calls to methods that allow configuration changes during the delay will be ignored.\n\n### \u003ca id=\"store-info\"\u003e\u003c/a\u003eStore information\n\nYou can use the Adjust SDK to record information about the store from which an app was installed on a user's device. Adjust supports a predefined list of store types.\n\nTo configure store information, set the `StoreInfo` property on your `FAdjustConfig` structure instance before SDK initialization:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFAdjustStoreInfo StoreInfo;\n```\n\nThe `FAdjustStoreInfo` structure contains the following properties:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString StoreName;\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString StoreAppId;\n```\n\n### \u003ca id=\"url-strategy\"\u003e\u003c/a\u003eURL strategy and data residency\n\nThe URL strategy feature allows you to set either:\n\n- The country in which Adjust stores your data (data residency).\n- The endpoint to which the Adjust SDK sends traffic (URL strategy).\n\nThis is useful if you're operating in a country with strict privacy requirements. When you set your URL strategy, Adjust stores data in the selected data residency region or sends traffic to the chosen domain.\n\nTo set your URL strategy, configure the following properties on your `FAdjustConfig` structure instance before SDK initialization:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nTArray\u003cFString\u003e UrlStrategyDomains;\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool ShouldUseSubdomains = false;\n\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nbool IsDataResidency = false;\n```\n\n- `UrlStrategyDomains` (`TArray\u003cFString\u003e`): The country or countries of data residence, or the endpoints to which you want to send SDK traffic.\n- `ShouldUseSubdomains` (`bool`): Whether the domain should be treated as an Adjust domain. If `true`, the SDK will prefix the domains with Adjust-specific subdomains. If `false`, the SDK will use the provided domain as-is, without adding any prefixes.\n- `IsDataResidency` (`bool`): Whether the domain should be used for data residency.\n\nThe following table shows all available URL strategy and data residency configurations:\n\n| Strategy              | Main and fallback domain      | Use subdomains | Is data residency |\n| --------------------- | ----------------------------- | -------------- | ----------------- |\n| EU data residency     | `eu.adjust.com`               | `true`         | `true`            |\n| Turkish data residency| `tr.adjust.com`               | `true`         | `true`            |\n| US data residency     | `us.adjust.com`               | `true`         | `true`            |\n| China global URL strategy | `adjust.world`, `adjust.com` | `true`         | `false`           |\n| China URL strategy    | `adjust.cn`, `adjust.com`     | `true`         | `false`           |\n| China only URL strategy | `adjust.cn`                  | `true`         | `false`           |\n| India URL strategy    | `adjust.net.in`, `adjust.com` | `true`         | `false`           |\n\n**Example: EU data residency**\n\n```cpp\nFAdjustConfig adjustConfig;\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"eu.adjust.com\"));\nadjustConfig.ShouldUseSubdomains = true;\nadjustConfig.IsDataResidency = true;\n```\n\n**Example: Turkish data residency**\n\n```cpp\nFAdjustConfig adjustConfig;\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"tr.adjust.com\"));\nadjustConfig.ShouldUseSubdomains = true;\nadjustConfig.IsDataResidency = true;\n```\n\n**Example: US data residency**\n\n```cpp\nFAdjustConfig adjustConfig;\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"us.adjust.com\"));\nadjustConfig.ShouldUseSubdomains = true;\nadjustConfig.IsDataResidency = true;\n```\n\n**Example: China global URL strategy**\n\n```cpp\nFAdjustConfig adjustConfig;\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"adjust.world\"));\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"adjust.com\"));\nadjustConfig.ShouldUseSubdomains = true;\nadjustConfig.IsDataResidency = false;\n```\n\n**Example: China URL strategy**\n\n```cpp\nFAdjustConfig adjustConfig;\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"adjust.cn\"));\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"adjust.com\"));\nadjustConfig.ShouldUseSubdomains = true;\nadjustConfig.IsDataResidency = false;\n```\n\n**Example: China only URL strategy**\n\n```cpp\nFAdjustConfig adjustConfig;\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"adjust.cn\"));\nadjustConfig.ShouldUseSubdomains = true;\nadjustConfig.IsDataResidency = false;\n```\n\n**Example: India URL strategy**\n\n```cpp\nFAdjustConfig adjustConfig;\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"adjust.net.in\"));\nadjustConfig.UrlStrategyDomains.Add(TEXT(\"adjust.com\"));\nadjustConfig.ShouldUseSubdomains = true;\nadjustConfig.IsDataResidency = false;\n```\n\n### \u003ca id=\"fb-app-id\"\u003e\u003c/a\u003eFacebook App ID\n\n\u003e Note: This feature is Android only.\n\nYou can set the Facebook App ID by setting the `FbAppId` property on your `FAdjustConfig` structure instance before SDK initialization:\n\n```cpp\nUPROPERTY(EditAnywhere, BlueprintReadWrite, Category = \"Adjust\")\nFString FbAppId;\n```\n\n## \u003ca id=\"purchase-verification\"\u003e\u003c/a\u003ePurchase verification\n\nIf you've enabled [purchase verification](https://help.adjust.com/en/article/purchase-verification), you can use the Adjust SDK to request purchase verification. There are two ways to verify purchases with the Adjust SDK:\n\n1. Create an `FAdjustEvent` object that represents your purchase and configure purchase properties for the target store.\n2. Create an `FAdjustAppStorePurchase` (Apple App Store) or `FAdjustPlayStorePurchase` (Google Play Store) object representing the purchase.\n\n\u003e Tip: If you use revenue events to measure your purchases in Adjust, you should use the `FAdjustEvent` class. If you only want to verify a purchase but don't want to associate it with an event, use the `FAdjustAppStorePurchase` or `FAdjustPlayStorePurchase` class.\n\nWhen you send purchase information with the Adjust SDK, Adjust does the following:\n\n1. Sends the information to the relevant store and waits for a status response.\n2. Forwards the status response to the Adjust SDK.\n\nYou can access the purchase verification status by using a callback. Results are returned as `FAdjustPurchaseVerificationResult` objects containing the following properties:\n\n- `VerificationStatus` (`FString`): The status of the purchase.\n- `Code` (`int`): The status code of the purchase.\n- `Message` (`FString`): Any message returned by the store.\n\n### \u003ca id=\"verify-purchase-and-track\"\u003e\u003c/a\u003eVerify purchase and record event\n\nTo send a revenue event for verification and listen for the purchase verification status, follow these steps:\n\n**For App Store:**\n\n1. Instantiate an `FAdjustEvent` object with your event token and set the following parameters:\n   - `ProductId` (`FString`): The product identifier of the item that was successfully purchased.\n   - `TransactionId` (`FString`): The ID of the transaction you want to verify.\n2. Call the `VerifyAndTrackAppStorePurchase` method with your event object.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void VerifyAndTrackAppStorePurchase(const FAdjustEvent\u0026 Event);\n```\n\n**For Play Store:**\n\n1. Instantiate an `FAdjustEvent` object with your event token and set the following parameters:\n   - `ProductId` (`FString`): The ID of the product that has been purchased.\n   - `PurchaseToken` (`FString`): The purchase token associated with the purchase.\n2. Call the `VerifyAndTrackPlayStorePurchase` method with your event object.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void VerifyAndTrackPlayStorePurchase(const FAdjustEvent\u0026 Event);\n```\n\nBefore making these calls, you need to assign a callback method to the instance of `UAdjustDelegates` class:\n\n```cpp\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPurchaseVerificationFinishedDelegate, const FAdjustPurchaseVerificationResult\u0026, VerificationResult);\n\n// ...\n\nUPROPERTY(BlueprintAssignable, BlueprintCallable, Category = Adjust)\nFOnPurchaseVerificationFinishedDelegate OnPurchaseVerificationFinishedDelegate;\n```\n\n### \u003ca id=\"verify-purchase-only\"\u003e\u003c/a\u003eOnly verify purchase\n\nTo send a standalone purchase and listen for the purchase verification status, follow these steps:\n\n**For App Store:**\n\n1. Instantiate an `FAdjustAppStorePurchase` object with the following arguments:\n   - `ProductId` (`FString`): The product identifier of the item that was successfully purchased.\n   - `TransactionId` (`FString`): The ID of the transaction you want to verify.\n2. Call the `VerifyAppStorePurchase` method with your purchase object.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void VerifyAppStorePurchase(const FAdjustAppStorePurchase\u0026 Purchase);\n```\n\n**For Play Store:**\n\n1. Instantiate an `FAdjustPlayStorePurchase` object with the following arguments:\n   - `ProductId` (`FString`): The ID of the product that has been purchased.\n   - `PurchaseToken` (`FString`): The purchase token associated with the purchase.\n2. Call the `VerifyPlayStorePurchase` method with your purchase object.\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void VerifyPlayStorePurchase(const FAdjustPlayStorePurchase\u0026 Purchase);\n```\n\nThe same callback delegate (`OnPurchaseVerificationFinishedDelegate`) is used for both methods.\n\n## \u003ca id=\"subscription-tracking\"\u003e\u003c/a\u003eSubscription tracking\n\n\u003e Important: The following steps only set up subscription measurement within the Adjust SDK. To enable the feature, follow the steps at [Set up subscriptions for your app](https://help.adjust.com/en/article/set-up-subscriptions-for-your-app).\n\nYou can record App Store and Play Store subscriptions with the Adjust SDK. After the user purchases a subscription, create an `FAdjustAppStoreSubscription` or `FAdjustPlayStoreSubscription` instance containing the details.\n\n### \u003ca id=\"app-store-subscription\"\u003e\u003c/a\u003eApp Store subscription\n\nCreate an `FAdjustAppStoreSubscription` object with the following properties:\n\n- `Price` (`double`): The price of the subscription.\n- `Currency` (`FString`): The currency of the subscription.\n- `TransactionId` (`FString`): Your ID for the transaction.\n- `TransactionDate` (`FString`): The date on which the user purchased a subscription (Unix timestamp string). This field is optional.\n- `SalesRegion` (`FString`): The region in which the user purchased a subscription (country code). This field is optional.\n- `CallbackParameters` (`TMap\u003cFString, FString\u003e`): Callback parameters to append to your callback URL.\n- `PartnerParameters` (`TMap\u003cFString, FString\u003e`): Partner parameters to send to network partners.\n\n```cpp\nFAdjustAppStoreSubscription Subscription;\nSubscription.Price = 9.99;\nSubscription.Currency = TEXT(\"USD\");\nSubscription.TransactionId = TEXT(\"transaction-id\");\nSubscription.TransactionDate = TEXT(\"1234567890\");\nSubscription.SalesRegion = TEXT(\"US\");\nSubscription.CallbackParameters.Add(TEXT(\"key1\"), TEXT(\"value1\"));\nSubscription.PartnerParameters.Add(TEXT(\"key1\"), TEXT(\"value1\"));\n\nUAdjust::TrackAppStoreSubscription(Subscription);\n```\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void TrackAppStoreSubscription(const FAdjustAppStoreSubscription\u0026 Subscription);\n```\n\n### \u003ca id=\"play-store-subscription\"\u003e\u003c/a\u003ePlay Store subscription\n\nCreate an `FAdjustPlayStoreSubscription` object with the following properties:\n\n- `Price` (`int64`): The price of the subscription (in micros).\n- `Currency` (`FString`): The currency of the subscription.\n- `Sku` (`FString`): The ID of the product.\n- `OrderId` (`FString`): Your ID for the transaction.\n- `Signature` (`FString`): The signature of the purchase data.\n- `PurchaseToken` (`FString`): The unique token of the transaction.\n- `PurchaseTime` (`int64`): The date on which the user purchased a subscription (Unix timestamp in milliseconds). This field is optional.\n- `CallbackParameters` (`TMap\u003cFString, FString\u003e`): Callback parameters to append to your callback URL.\n- `PartnerParameters` (`TMap\u003cFString, FString\u003e`): Partner parameters to send to network partners.\n\n```cpp\nFAdjustPlayStoreSubscription Subscription;\nSubscription.Price = 9990000; // 9.99 in micros\nSubscription.Currency = TEXT(\"USD\");\nSubscription.Sku = TEXT(\"sku-id\");\nSubscription.OrderId = TEXT(\"order-id\");\nSubscription.Signature = TEXT(\"signature\");\nSubscription.PurchaseToken = TEXT(\"purchase-token\");\nSubscription.PurchaseTime = 1234567890000;\nSubscription.CallbackParameters.Add(TEXT(\"key1\"), TEXT(\"value1\"));\nSubscription.PartnerParameters.Add(TEXT(\"key1\"), TEXT(\"value1\"));\n\nUAdjust::TrackPlayStoreSubscription(Subscription);\n```\n\n```cpp\nUFUNCTION(BlueprintCallable, Category = \"Adjust\")\nstatic void TrackPlayStoreSubscription(const FAdjustPlayStoreSubscription\u0026 Subscription);\n```\n\n## \u003ca id=\"license\"\u003e\u003c/a\u003eLicense\n\nThe Adjust SDK is licensed under the MIT License.\n\nCopyright (c) 2018-Present Adjust GmbH, http://www.adjust.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadjust%2Funreal_sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadjust%2Funreal_sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadjust%2Funreal_sdk/lists"}