# Getting Started for Native Mobile

Use this guide to add GrowSurf referral sharing, attribution, and the native GrowSurf window to a native iOS or Android app.

{% hint style="info" %}
Native apps use a public Mobile SDK key. Keep your secret REST API key on your backend, especially for purchases, subscriptions, and actions that determine whether rewards should be issued.
{% endhint %}

## How the mobile flow works

1. Enable Mobile SDK access for your GrowSurf program.
2. Install the native SDK.
3. Create or load the participant in your app.
4. Share the participant's `shareUrl`.
5. Capture referral attribution when the referred friend opens or installs the app.
6. Show referral links, referral counts, referral statuses, and rewards in your app, or present the native GrowSurf window.
7. Trigger referral credit when the referred friend qualifies.

The SDK saves referral attribution locally and includes it when you create the referred friend's participant record.

## Install the SDK

{% tabs %}
{% tab title="iOS CocoaPods" %}
Add the tag-pinned public podspec:

```ruby
growsurf_podspec = 'https://raw.githubusercontent.com/growsurf/growsurf-ios-sdk-distribution/v0.2.0/GrowSurfSDK.podspec'

pod 'GrowSurfSDK', :podspec => growsurf_podspec
```

{% endtab %}

{% tab title="iOS SPM" %}
In Xcode, add the public binary package repository:

```
https://github.com/growsurf/growsurf-ios-sdk-distribution.git
```

Use version `0.2.0` or later and add the `GrowSurfSDK` product to your app target.

For a `Package.swift` target:

```swift
dependencies: [
    .package(url: "https://github.com/growsurf/growsurf-ios-sdk-distribution.git", from: "0.2.0"),
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [
            .product(name: "GrowSurfSDK", package: "growsurf-ios-sdk-distribution"),
        ]
    ),
]
```

{% endtab %}

{% tab title="iOS Manual" %}
Download `GrowSurfSDK.xcframework.zip` from the public release:

```
https://github.com/growsurf/growsurf-ios-sdk-distribution/releases/tag/v0.2.0
```

Unzip it, drag `GrowSurfSDK.xcframework` into your Xcode project, and set it to **Embed & Sign** in your app target.
{% endtab %}

{% tab title="Android Kotlin DSL" %}
Add the Android SDK from Maven Central:

```kotlin
repositories {
    mavenCentral()
}

dependencies {
    implementation("com.growsurf:growsurf-android-sdk:0.2.0")
}
```

{% endtab %}

{% tab title="Android Groovy" %}
Add the Android SDK from Maven Central:

```groovy
repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.growsurf:growsurf-android-sdk:0.2.0'
}
```

{% endtab %}
{% endtabs %}

For Android apps, make sure AndroidX is enabled:

```properties
android.useAndroidX=true
```

## Initialize

Configure the SDK once when your app starts or before your first GrowSurf call.

{% tabs %}
{% tab title="Swift" %}

```swift
import GrowSurfSDK

let growsurf = GrowSurf.configure(
    campaignId: "abc123",
    publicKey: "pk_mobile"
)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import com.growsurf.sdk.GrowSurfSdk

val growsurf = GrowSurfSdk.configure(
    context = context,
    campaignId = "abc123",
    publicKey = "pk_mobile",
)
```

{% endtab %}
{% endtabs %}

Most apps do not need to create a session manually. The SDK creates one when it needs to call GrowSurf.

## Capture attribution

Configure your Share URL, app link, or attribution-provider link to preserve the GrowSurf referral value when referred friends open or install your app:

* Android installs can use Google Play Install Referrer with the GrowSurf referral value.
* iOS installs can use your attribution-provider link with the GrowSurf referral value.
* Direct app links can include `grsf`, `ref`, or `referredBy`.

Capture referral attribution before you create the referred friend's participant record.

{% tabs %}
{% tab title="Swift" %}
For direct app links that already contain `grsf`, `ref`, or `referredBy`:

```swift
if let url {
    try await growsurf.handleDeepLink(url)
}
```

For deferred deep links from an iOS attribution provider, pass the provider callback payload into GrowSurf before calling `addReferredParticipant()`:

```swift
try await growsurf.handleAttributionParameters(
    [
        "grsf": "referrer_id",
        "click_id": "click_123",
        "unique": "true",
    ],
    provider: "branch"
)
```

{% endtab %}

{% tab title="Kotlin" %}
For direct app links that already contain `grsf`, `ref`, or `referredBy`:

```kotlin
intent.data?.let { uri ->
    growsurf.handleDeepLink(uri)
}
```

For Google Play installs, `addReferredParticipant()` checks Play Install Referrer once when no explicit or pending attribution exists. You can also call `handleDeferredDeepLink()` before signup when you want to inspect attribution earlier:

```kotlin
lifecycleScope.launch {
    growsurf.handleDeferredDeepLink()
}
```

For deferred deep links from an attribution provider, pass the provider callback payload into GrowSurf before calling `addReferredParticipant()`:

```kotlin
growsurf.handleAttributionParameters(
    mapOf(
        "grsf" to "referrer_id",
        "click_id" to "click_123",
        "unique" to "true",
    ),
    provider = "branch",
)
```

{% endtab %}
{% endtabs %}

See [iOS SDK Attribution Providers](/developer-tools/ios-sdk/attribution-providers.md) and [Android SDK Attribution Providers](/developer-tools/android-sdk/attribution-providers.md) for Branch, Adjust, AppsFlyer, Singular, direct deep link, and Google Play setup details.

## Create signed-in participants

After your app authenticates a user, call GrowSurf from your backend to ensure the participant exists and mint a mobile participant token.

If the SDK captured referral attribution from a direct link, Google Play Install Referrer, or an attribution provider, read the pending attribution in the app and send the `referredBy` value to your backend before calling the REST API. For mobile anti-fraud, also send the SDK-generated lowercase mobile instance ID as `mobileInstanceId`. This handoff is required because the REST API call happens on your backend, while attribution and the mobile instance ID are stored locally in the app.

{% tabs %}
{% tab title="Swift" %}

```swift
let attribution = try await growsurf.pendingAttribution()
let mobileInstanceId = try await growsurf.mobileInstanceId()
try await api.createMobileParticipantToken(
    email: user.email,
    referredBy: attribution?.referredBy,
    mobileInstanceId: mobileInstanceId
)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val attribution = growsurf.getPendingAttribution()
val mobileInstanceId = growsurf.getMobileInstanceId()
api.createMobileParticipantToken(
    email = user.email,
    referredBy = attribution?.referredBy,
    mobileInstanceId = mobileInstanceId,
)
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Backend cURL" %}

```bash
curl -X POST "https://api.growsurf.com/v2/campaign/YOUR_PROGRAM_ID/mobile-participant-token" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
   "email": "person@example.com",
   "firstName": "Ada",
	   "lastName": "Lovelace",
	   "referredBy": "referrer_id",
	   "metadata": {
	      "plan": "pro"
	   }
}'
```

{% endtab %}
{% endtabs %}

Return `participantToken` from your backend to your app.

{% tabs %}
{% tab title="Swift" %}

```swift
try await growsurf.setParticipantToken(participantToken)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
growsurf.setParticipantToken(participantToken)
```

{% endtab %}
{% endtabs %}

Use SDK `addReferredParticipant()` to track referred signups. The method creates a referred participant only when the referrer is valid, and returns a normal not-added result when no valid referrer is present.

{% tabs %}
{% tab title="Swift" %}

```swift
let created = try await growsurf.addReferredParticipant(
    .init(email: "person@example.com")
)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val created = growsurf.addReferredParticipant(
    GrowSurfParticipantInput(email = "person@example.com")
)
```

{% endtab %}
{% endtabs %}

## Show the GrowSurf window

{% hint style="info" %}
The native GrowSurf window is beta in SDK `0.2.0`. It is fully native on iOS and Android, uses the GrowSurf window settings from your dashboard, and does not add a default launcher or floating button.
{% endhint %}

Open the GrowSurf window from your own button, menu item, or referral screen. For signed-in users, pass a backend-minted participant token.

{% tabs %}
{% tab title="Swift" %}

```swift
growsurf.presentGrowSurfWindow(
    from: viewController,
    identity: .existingParticipantToken(participantToken),
    theme: GrowSurfWindowTheme(
        primaryColorHex: "#13795B",
        presentationStyle: .automatic
    ),
    callbacks: GrowSurfWindowCallbacks(
        onShareTracked: { type in
            print("Share tracked: \(type)")
        },
        onError: { error in
            print(error.localizedDescription)
        }
    )
)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
growsurf.presentGrowSurfWindow(
    activity = this,
    identity = GrowSurfWindowIdentity.ExistingParticipantToken(participantToken),
    theme = GrowSurfWindowTheme(
        primaryColor = 0xFF13795B,
        presentationStyle = GrowSurfWindowPresentationStyle.AUTOMATIC,
    ),
    callbacks = GrowSurfWindowCallbacks(
        onShareTracked = { type ->
            Log.d("GrowSurf", "Share tracked: $type")
        },
        onError = { error ->
            Log.e("GrowSurf", "GrowSurf window error", error)
        },
    ),
)
```

{% endtab %}
{% endtabs %}

Use the participant-token identity for signed-in users. Use the participant-fields identity only for public signup flows where the SDK should create a participant from fields before showing the GrowSurf window. Use the anonymous identity when you want the GrowSurf window to show signup state first.

The GrowSurf window can show the referral link, native share sheet, enabled share channels, QR code, email invites, referrals, rewards, leaderboard, affiliate summary, commissions, payouts, participant settings, how-it-works, FAQ, and terms. It only shows sections enabled for your program.

Native platforms and channel apps control how much prefilled share text they allow. Facebook often blocks prefilled text; when a channel target is unavailable or restricted, use the native share sheet fallback.

## Build a custom referral portal

Use the headless SDK methods to build a custom native referral portal without exposing your REST API key in the app.

{% tabs %}
{% tab title="Swift" %}

```swift
let participant = try await growsurf.getParticipant(id: participantId)
let referrals = try await growsurf.getParticipantReferrals(id: participantId)
let rewards = try await growsurf.getParticipantRewards(id: participantId)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val participant = growsurf.getParticipant(participantId)
val referrals = growsurf.getParticipantReferrals(participantId)
val rewards = growsurf.getParticipantRewards(participantId)
```

{% endtab %}
{% endtabs %}

These methods give you the participant's referral link, referral counts, referral statuses, and rewards.

## Trigger referral credit

Only trigger referral credit after the referred friend completes your qualifying action.

For low-risk client-side milestones, the SDK provides `triggerReferral`:

{% tabs %}
{% tab title="Swift" %}

```swift
try await growsurf.triggerReferral(participantId: participantId)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
growsurf.triggerReferral(participantId)
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
For purchases, subscriptions, completed bookings, or events that determine whether rewards should be issued, trigger referral credit from your backend with the [REST API](/developer-tools/rest-api.md).
{% endhint %}

## Legacy web fallback

If your team is not ready to use the native SDKs, you can still use a web-first flow:

1. Send referred friends to a mobile web page that captures their email address.
2. Redirect them to the App Store or Google Play.
3. Add or update the GrowSurf participant from your backend when they sign up.

This works, but the native SDK flow gives users a smoother app install path and lets your app show referral data directly.

## Next steps

{% content-ref url="/pages/UD9v0rnKjJzEapAEkEY8" %}
[iOS SDK (Beta)](/developer-tools/ios-sdk.md)
{% endcontent-ref %}

{% content-ref url="/pages/upxU6CKkGvjfZGvvKtGW" %}
[Android SDK (Beta)](/developer-tools/android-sdk.md)
{% endcontent-ref %}

{% content-ref url="/pages/-Lekn\_\_QrV\_9D0VpyIrH" %}
[REST API](/developer-tools/rest-api.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://docs.growsurf.com/getting-started-for-native-mobile.md?ask=<question>
```

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

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