Unreal Engine SDK - Supporting Referrer Short Links

Creating Short Referrer Links

Generate short, shareable referrer links that enable user-to-user attribution and track app installs from organic referrals.

Version Requirement: This functionality requires SDK version 2.0.6 or higher. Short links remain active for 30 days after creation.

Overview

What Are Short Referrer Links

Short links transform long, parameter-filled Singular Links into compact, secure URLs convenient for sharing via SMS, social media, or in-app invitations.

Create short links dynamically so users can share them with friends to invite them to download and use your app. Each short link tracks the referring user, enabling you to measure viral growth and attribute new installs to specific advocates.


Implementation Requirements

Required Components

Gather these elements before creating a short referrer link:

  • Singular Link: A base tracking link that directs users to your app download. See Singular Links FAQ for setup instructions
  • Dynamic Parameters: Optional custom parameters to add context to the link. View available options in Tracking Link Parameters
  • Referrer Information: Name and ID of the user sharing the link to enable attribution of new installs back to the referrer

SDK Implementation

Register Short Link Delegate

Configure the delegate callback handler in your character class constructor to receive short link creation results.

C++
// Add to your character header file (.h)
#include "SingularDelegates.h"

// Declare delegate pointer and callback method
USingularDelegates* SingularDelegates;

UFUNCTION()
void OnSingularShortLinkResolved(const FSingularShortLinkParams& LinkParams);

// In your character implementation file (.cpp)
// Register the delegate in the constructor
AYourCharacter::AYourCharacter()
{
    if (SingularDelegates == nullptr)
    {
        // Create and register the delegate handler
        SingularDelegates = CreateDefaultSubobject<USingularDelegates>(
            TEXT("SingularShortLinksHandler")
        );

        SingularDelegates->OnSingularShortLinksResolved.AddDynamic(
            this, 
            &AYourCharacter::OnSingularShortLinkResolved
        );

        UE_LOG(LogTemp, Log, TEXT("Short link delegate registered"));
    }
}

// Implement the callback method
void AYourCharacter::OnSingularShortLinkResolved(const FSingularShortLinkParams& LinkParams)
{
    // Extract the short link URL or error message
    const FString ShortLinkURL = LinkParams.SingularShortLinksParams["data"];
    const FString ErrorMessage = LinkParams.SingularShortLinksParams["error"];

    if (!ShortLinkURL.IsEmpty())
    {
        // Success - short link was created
        UE_LOG(LogTemp, Log, TEXT("Generated short link: %s"), *ShortLinkURL);

        // Share the link using your preferred sharing method
        ShareLinkWithUser(ShortLinkURL);
    }
    else if (!ErrorMessage.IsEmpty())
    {
        // Error occurred during link creation
        UE_LOG(LogTemp, Error, TEXT("Short link error: %s"), *ErrorMessage);

        // Implement retry logic or show error to user
        HandleShortLinkError(ErrorMessage);
    }
}

Important: Register the delegate handler in your class constructor before creating any short links. The callback receives either a successful short link URL in the "data" field or an error message in the "error" field, but never both.


Create Short Referrer Link

Generate a short referrer link with custom parameters using the CreateReferrerShortLink method.

Method Signature:

static void CreateReferrerShortLink(
    FString baseLink, 
    FString referrerName, 
    FString referrerId, 
    TMap<FString, FString> args
)

Parameters:

  • baseLink: The original Singular tracking link URL
  • referrerName: Display name of the referring user
  • referrerId: Unique identifier for the referring user
  • args: TMap containing additional dynamic parameters (can be empty)

Usage Example

Create a short link with custom parameters and handle the response in your delegate callback.

C++
// Example: User clicks "Invite Friends" button
void AYourCharacter::OnInviteFriendsClicked()
{
    // Add custom parameters to the link
    TMap<FString, FString> LinkParameters;
    LinkParameters.Add(TEXT("channel"), TEXT("sms"));
    LinkParameters.Add(TEXT("campaign_id"), TEXT("summer_referral_2025"));
    LinkParameters.Add(TEXT("referral_type"), TEXT("friend_invite"));

    // Create the short referrer link
    USingularSDKBPLibrary::CreateReferrerShortLink(
        TEXT("https://sample.sng.link/B4tbm/v8fp?_dl=https%3A%2F%2Fmyapp.com"),  // Base link
        TEXT("John Doe"),                                                         // Referrer name
        TEXT("user_12345"),                                                       // Referrer ID
        LinkParameters                                                            // Custom parameters
    );

    UE_LOG(LogTemp, Log, TEXT("Short link creation requested"));
}

// Handle successful link creation
void AYourCharacter::ShareLinkWithUser(const FString& ShortLinkURL)
{
    // Example: Show share UI with the short link
    FString ShareMessage = FString::Printf(
        TEXT("Join me in this awesome game! %s"), 
        *ShortLinkURL
    );

    // Platform-specific sharing implementation
    #if PLATFORM_ANDROID
        ShareOnAndroid(ShareMessage);
    #elif PLATFORM_IOS
        ShareOnIOS(ShareMessage);
    #else
        // Fallback: Copy to clipboard
        FPlatformApplicationMisc::ClipboardCopy(*ShortLinkURL);
        UE_LOG(LogTemp, Log, TEXT("Link copied to clipboard: %s"), *ShortLinkURL);
    #endif
}

// Handle link creation errors
void AYourCharacter::HandleShortLinkError(const FString& ErrorMessage)
{
    // Log the error
    UE_LOG(LogTemp, Warning, TEXT("Short link failed: %s"), *ErrorMessage);

    // Retry logic for transient errors
    if (ErrorMessage.Contains(TEXT("network")) || ErrorMessage.Contains(TEXT("timeout")))
    {
        // Retry after delay
        FTimerHandle RetryTimer;
        GetWorldTimerManager().SetTimer(
            RetryTimer,
            this,
            &AYourCharacter::OnInviteFriendsClicked,
            2.0f,  // Retry after 2 seconds
            false
        );
    }
    else
    {
        // Show error message to user
        ShowErrorMessage(TEXT("Unable to create share link. Please try again later."));
    }
}

Best Practice: Include meaningful custom parameters that help you analyze which sharing channels and campaigns drive the most installs. Use consistent referrer IDs that match your internal user identification system for accurate attribution.


Implementation Best Practices

Error Handling

Implement robust error handling in your callback to manage network failures, invalid parameters, or server issues.

  • Retry Logic: Implement exponential backoff for transient network errors
  • User Feedback: Display clear error messages when link creation fails
  • Fallback Option: Provide alternative sharing methods (e.g., share the full Singular Link if short link creation fails)
  • Validation: Verify parameters before calling CreateReferrerShortLink to catch issues early

Network Dependency: Short link creation requires an active internet connection. Always handle network failures gracefully and provide feedback to users if link creation fails.


Tracking and Analytics

Leverage referrer information to build viral loops and measure organic growth.

Viral Growth Metrics: Use consistent referrer IDs to:

  • Attribute new installs to specific referring users
  • Reward users for successful referrals
  • Track viral coefficient and K-factor metrics
  • Identify your most valuable brand advocates

Link Expiration

Plan for the 30-day link lifecycle in your sharing strategy.

Important: Short links expire after 30 days. For long-term campaigns or persistent share features, generate new short links periodically or use the full Singular Link as a fallback.


Common Use Cases

In-App Referral Programs

Enable users to invite friends directly from your app with personalized referral links.

  • Reward System: Track referrals and reward users for successful friend signups
  • Social Sharing: Integrate with platform-native share functionality for SMS, social media, and messaging apps
  • Personal Invites: Include referrer name in the shared message for personalization
C++
// Example: Referral reward system
void AReferralManager::ProcessSuccessfulReferral(const FString& ReferrerId, const FString& NewUserId)
{
    // Track the referral event
    TMap<FString, FString> ReferralData;
    ReferralData.Add(TEXT("referrer_id"), ReferrerId);
    ReferralData.Add(TEXT("new_user_id"), NewUserId);
    ReferralData.Add(TEXT("referral_source"), TEXT("in_app_share"));

    USingularSDKBPLibrary::SendEventWithArgs(TEXT("referral_success"), ReferralData);

    // Award reward to referring user
    AwardReferralReward(ReferrerId);

    UE_LOG(LogTemp, Log, TEXT("Referral processed: %s referred %s"), *ReferrerId, *NewUserId);
}

User-Generated Content

Create shareable links when users generate content they want to share with others.

  • Content Attribution: Track which content drives the most app installs
  • Creator Recognition: Attribute new users to content creators for gamification
  • Campaign Tagging: Add dynamic parameters based on content type or category
C++
// Example: Share user-generated content
void AContentManager::ShareUserContent(const FString& ContentId, const FString& CreatorId, const FString& CreatorName)
{
    // Add content-specific parameters
    TMap<FString, FString> ContentParams;
    ContentParams.Add(TEXT("content_id"), ContentId);
    ContentParams.Add(TEXT("content_type"), TEXT("custom_level"));
    ContentParams.Add(TEXT("share_source"), TEXT("ugc_gallery"));

    // Create short link with content creator as referrer
    USingularSDKBPLibrary::CreateReferrerShortLink(
        TEXT("https://mygame.sng.link/Ab3d/cdef?_dl=mygame://content"),
        CreatorName,
        CreatorId,
        ContentParams
    );
}

Event Invitations

Generate unique links for event invitations that track which attendees bring new users.

  • Event Context: Include event ID and details in link parameters
  • Attendee Tracking: Measure viral spread from event to event
  • Network Effects: Identify events with the highest conversion rates
C++
// Example: Share event invitation
void AEventManager::InviteToEvent(const FString& EventId, const FString& EventName, const FString& HostId, const FString& HostName)
{
    // Add event-specific parameters
    TMap<FString, FString> EventParams;
    EventParams.Add(TEXT("event_id"), EventId);
    EventParams.Add(TEXT("event_name"), EventName);
    EventParams.Add(TEXT("event_date"), GetEventDateString(EventId));
    EventParams.Add(TEXT("invite_type"), TEXT("host_invite"));

    // Create short link with event host as referrer
    USingularSDKBPLibrary::CreateReferrerShortLink(
        TEXT("https://mygame.sng.link/Ev2nt/wxyz?_dl=mygame://event"),
        HostName,
        HostId,
        EventParams
    );

    UE_LOG(LogTemp, Log, TEXT("Event invitation link created for: %s"), *EventName);
}

Platform-Specific Sharing

Android Sharing Implementation

Implement native Android sharing using JNI to invoke the system share sheet.

C++
#if PLATFORM_ANDROID
void AYourCharacter::ShareOnAndroid(const FString& Message)
{
    if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
    {
        // Get the Intent class
        jclass IntentClass = FAndroidApplication::FindJavaClass("android/content/Intent");

        // Create Intent with ACTION_SEND
        jfieldID ActionSendField = Env->GetStaticFieldID(IntentClass, "ACTION_SEND", "Ljava/lang/String;");
        jobject ActionSend = Env->GetStaticObjectField(IntentClass, ActionSendField);

        jmethodID IntentConstructor = Env->GetMethodID(IntentClass, "<init>", "()V");
        jobject IntentObject = Env->NewObject(IntentClass, IntentConstructor);

        // Set action and type
        jmethodID SetActionMethod = Env->GetMethodID(IntentClass, "setAction", "(Ljava/lang/String;)Landroid/content/Intent;");
        Env->CallObjectMethod(IntentObject, SetActionMethod, ActionSend);

        jmethodID SetTypeMethod = Env->GetMethodID(IntentClass, "setType", "(Ljava/lang/String;)Landroid/content/Intent;");
        jstring TypeString = Env->NewStringUTF("text/plain");
        Env->CallObjectMethod(IntentObject, SetTypeMethod, TypeString);

        // Add the message
        jmethodID PutExtraMethod = Env->GetMethodID(IntentClass, "putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;");
        jfieldID ExtraTextField = Env->GetStaticFieldID(IntentClass, "EXTRA_TEXT", "Ljava/lang/String;");
        jobject ExtraText = Env->GetStaticObjectField(IntentClass, ExtraTextField);
        jstring MessageString = Env->NewStringUTF(TCHAR_TO_UTF8(*Message));
        Env->CallObjectMethod(IntentObject, PutExtraMethod, ExtraText, MessageString);

        // Create chooser and start activity
        jmethodID CreateChooserMethod = Env->GetStaticMethodID(IntentClass, "createChooser", "(Landroid/content/Intent;Ljava/lang/CharSequence;)Landroid/content/Intent;");
        jstring ChooserTitle = Env->NewStringUTF("Share via");
        jobject ChooserIntent = Env->CallStaticObjectMethod(IntentClass, CreateChooserMethod, IntentObject, ChooserTitle);

        // Start the activity
        FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "startActivity", "(Landroid/content/Intent;)V", false), ChooserIntent);

        // Cleanup
        Env->DeleteLocalRef(IntentClass);
        Env->DeleteLocalRef(ActionSend);
        Env->DeleteLocalRef(IntentObject);
        Env->DeleteLocalRef(TypeString);
        Env->DeleteLocalRef(MessageString);
        Env->DeleteLocalRef(ExtraText);
        Env->DeleteLocalRef(ChooserTitle);
        Env->DeleteLocalRef(ChooserIntent);

        UE_LOG(LogTemp, Log, TEXT("Android share dialog opened"));
    }
}
#endif

iOS Sharing Implementation

Implement native iOS sharing using Objective-C++ to present UIActivityViewController.

Implementation Note: iOS sharing requires Objective-C++ implementation. Create a separate .mm file for platform-specific code and expose C++ callable methods.