> For the complete documentation index, see [llms.txt](https://docs.growsurf.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.growsurf.com/developer-tools/android-sdk/api-reference.md).

# API Reference

{% hint style="info" %}
If you're using an AI tool such as Cursor, ChatGPT Codex, or Claude Code to help you implement GrowSurf, we recommend utilizing our [MCP server](https://docs.growsurf.com/build-with-ai).
{% endhint %}

Use this page to look up individual GrowSurf Android SDK methods. Most SDK methods are Kotlin coroutine methods. Java examples are included where the SDK exposes callback overloads or synchronous/static methods.

{% hint style="warning" %}
Use the Mobile SDK public key in your app. Do not embed your secret REST API key in an Android app.
{% endhint %}

## SDK LIFECYCLE ↓

### Configure

Call this once before using GrowSurf. It connects the SDK to your GrowSurf campaign, Mobile SDK public key, and Android context.

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

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

{% endtab %}

{% tab title="Java" %}

```java
GrowSurfSdk growsurf = GrowSurfSdk.configure(
    context,
    "abc123",
    "pk_mobile",
    "https://api.growsurf.com/mobile/v2"
);
```

{% endtab %}
{% endtabs %}

| Parameter        | Data Type | Description                                                                                                                                     |
| ---------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **`context`**    | `Context` | (Required) Android context used for encrypted token storage, attribution storage, mobile instance ID storage, and Play Install Referrer access. |
| **`campaignId`** | `String`  | (Required) Your GrowSurf program ID.                                                                                                            |
| **`publicKey`**  | `String`  | (Required) Your Mobile SDK public key.                                                                                                          |
| **`baseUrl`**    | `String`  | (Optional in Kotlin) Custom Mobile SDK API base URL. Defaults to `https://api.growsurf.com/mobile/v2`.                                          |

Returns a configured `GrowSurfSdk` instance.

Optionally, for advanced apps, initialize directly with explicit stores, transport, dispatcher, or install referrer client. Pass the production stores shown below (or your own conformances to the public store interfaces):

```kotlin
val growsurf = GrowSurfSdk(
    configuration = GrowSurfConfiguration(
        campaignId = "abc123",
        publicKey = "pk_mobile",
    ),
    tokenStore = EncryptedPreferencesGrowSurfTokenStore(context),
    attributionStore = PreferencesGrowSurfAttributionStore(context),
)
```

***

### Set participant token

Use this after your backend creates a mobile participant token for a signed-in user. It lets participant-scoped SDK calls load or update that participant's data.

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

| Parameter   | Data Type | Description                                                                                         |
| ----------- | --------- | --------------------------------------------------------------------------------------------------- |
| **`token`** | `String`  | (Required) A mobile participant token returned by your backend or by a participant creation method. |

Returns `Unit`.

#### **Example use**

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

{% hint style="info" %}
Use this method with tokens created by the REST API mobile participant token endpoint after a user is already signed in.
{% endhint %}

***

### Get participant token

Returns the participant token currently held by the SDK, or `null` if none is stored. Useful right after the GrowSurf window's `ParticipantFields` signup flow so your app can persist the freshly minted token for the user's next session.

```kotlin
growsurf.getParticipantToken()
```

Returns `String?`.

#### **Example use**

```kotlin
growsurf.getParticipantToken()?.let { token ->
    // Persist the token to your backend so the user stays signed in to GrowSurf.
}
```

{% hint style="info" %}
The default `EncryptedPreferencesGrowSurfTokenStore` can propagate KeyStore or EncryptedSharedPreferences errors. Wrap this call in `try`/`catch` and rethrow `CancellationException` to preserve structured concurrency.
{% endhint %}

***

### Get current participant ID

Returns the current participant's ID from the stored participant token, or `null` if none.

{% tabs %}
{% tab title="Kotlin coroutine" %}

```kotlin
val participantId = growsurf.getCurrentParticipantId()
```

{% endtab %}

{% tab title="Java callback" %}

```java
growsurf.getCurrentParticipantId(new GrowSurfCallback<String?>() {
    @Override
    public void onSuccess(String result) {
        Log.d("GrowSurf", "Current participant: " + result);
    }

    @Override
    public void onError(Throwable error) {
        Log.e("GrowSurf", "Current participant error", error);
    }
});
```

{% endtab %}
{% endtabs %}

Returns `String?`.

#### **Example use**

```kotlin
growsurf.getCurrentParticipantId()?.let { participantId ->
    Log.d("GrowSurf", "Current participant: $participantId")
}
```

***

### Get mobile instance ID

Returns the app-install ID the SDK sends with participant creation for mobile anti-fraud. You usually only need this if your backend creates mobile participant tokens and needs to pass the same ID to GrowSurf.

`getMobileInstanceId()` is a `suspend` function, so call it from a coroutine.

```kotlin
growsurf.getMobileInstanceId()
```

Returns a UUID `String`.

#### **Example use**

```kotlin
lifecycleScope.launch {
    val mobileInstanceId = growsurf.getMobileInstanceId()
}
```

{% hint style="info" %}
Participant creation methods send `mobileInstanceId` automatically. Read it manually only when your backend creates a mobile participant token and needs to pass `mobileInstanceId` to the REST API.
{% endhint %}

***

### Shutdown

Call this when a user signs out or you need to reset GrowSurf state on the device. It clears the stored session token, participant token, and pending attribution.

```kotlin
growsurf.shutdown()
```

Returns `Unit`.

#### **Example use**

```kotlin
growsurf.shutdown()
```

***

## CAMPAIGNS ↓

### Get campaign

Use this to read campaign details and rewards for the configured GrowSurf program. The SDK creates or uses a session token before calling GrowSurf.

```kotlin
growsurf.getCampaign()
```

Returns `GrowSurfCampaign`.

#### **Example use**

```kotlin
val campaign = growsurf.getCampaign()
Log.d("GrowSurf", campaign.id)
```

***

### Get leaderboard

Use this to show leaderboard rows in a custom referral screen. You can page through results with page or cursor parameters.

```kotlin
growsurf.getLeaderboard(
    limit = 20,
    page = 1,
    offsetKey = null,
    leaderboardType = null,
)
```

| Parameter             | Data Type | Description                                        |
| --------------------- | --------- | -------------------------------------------------- |
| **`limit`**           | `Int?`    | (Optional) Number of rows to return.               |
| **`page`**            | `Int?`    | (Optional) Page number.                            |
| **`offsetKey`**       | `String?` | (Optional) Cursor key for offset-based pagination. |
| **`leaderboardType`** | `String?` | (Optional) Leaderboard type filter.                |

Returns `GrowSurfLeaderboardResponse`.

#### **Example use**

```kotlin
val leaderboard = growsurf.getLeaderboard(limit = 10)
leaderboard.participants.forEach { row ->
    Log.d("GrowSurf", "Rank ${row.rank}: ${row.email}")
}
```

***

## GROWSURF WINDOW ↓

### Present GrowSurf window

Call this from your own button, menu item, or referral screen to open GrowSurf's native Compose referral window.

{% hint style="info" %}
The native GrowSurf window uses the GrowSurf window settings from your dashboard. This method is not a coroutine method.
{% endhint %}

```kotlin
growsurf.presentGrowSurfWindow(
    activity = activity,
    identity = GrowSurfWindowIdentity.ExistingParticipantToken(participantToken),
    theme = GrowSurfWindowTheme(),
    callbacks = GrowSurfWindowCallbacks(),
)
```

| Parameter       | Data Type                 | Description                                                                                                                                                          |
| --------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`activity`**  | `Activity`                | (Required) Activity that hosts the native window.                                                                                                                    |
| **`identity`**  | `GrowSurfWindowIdentity`  | (Optional) How the window should identify the current user. Defaults to `Anonymous`.                                                                                 |
| **`theme`**     | `GrowSurfWindowTheme`     | (Optional) Native presentation and theme overrides.                                                                                                                  |
| **`callbacks`** | `GrowSurfWindowCallbacks` | (Optional) Event callbacks for window open, close, participant creation (from the signup form), share tracking, invite sending, payout/settings actions, and errors. |

Returns `GrowSurfWindowController` — call `close()` on it to dismiss the window programmatically.

#### **Example use**

```kotlin
val controller = 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")
        },
        onParticipantCreated = { participant, participantToken ->
            Log.d("GrowSurf", "Participant: ${participant.id}")
        },
        onError = { error ->
            Log.e("GrowSurf", "GrowSurf window error", error)
        },
    ),
)
```

***

### Get GrowSurf window

Use this when you are building your own referral screen instead of showing the native GrowSurf window. It returns the campaign, participant, share, reward, leaderboard, and affiliate data used by the window.

```kotlin
growsurf.getGrowSurfWindow(identity = GrowSurfWindowIdentity.Anonymous)
```

| Parameter      | Data Type                | Description                                          |
| -------------- | ------------------------ | ---------------------------------------------------- |
| **`identity`** | `GrowSurfWindowIdentity` | (Optional) Window identity. Defaults to `Anonymous`. |

Returns `GrowSurfWindowResponse`.

#### **Example use**

```kotlin
val window = growsurf.getGrowSurfWindow(
    identity = GrowSurfWindowIdentity.ExistingParticipantToken(participantToken),
)

val shareUrl = window.participant?.shareUrl ?: window.share?.preferredUrl ?: window.share?.fallbackUrl
```

{% hint style="info" %}
Use `participant.shareUrl` as the customer-facing referral link when a participant is available. Fall back to `share.preferredUrl` or `share.fallbackUrl` only for rendering.
{% endhint %}

***

## ATTRIBUTION ↓

### Handle deep link

Call this when your app opens from a referral deep link. If the URI contains `grsf`, `ref`, or `referredBy`, the SDK saves the attribution so you can apply it when the user signs up.

```kotlin
growsurf.handleDeepLink(uri)
```

| Parameter | Data Type | Description                                      |
| --------- | --------- | ------------------------------------------------ |
| **`uri`** | `Uri`     | (Required) The deep link URI opened by your app. |

Returns `GrowSurfAttribution?`. Returns `null` when no GrowSurf referral value is found.

#### **Example use**

```kotlin
intent.data?.let { uri ->
    val attribution = growsurf.handleDeepLink(uri)
    Log.d("GrowSurf", "Referrer: ${attribution?.referredBy}")
}
```

***

### Handle deferred deep link

Call this if you want to read Google Play Install Referrer before signup. `addReferredParticipant(...)` checks it automatically when no explicit or pending attribution exists.

```kotlin
growsurf.handleDeferredDeepLink(forceRefresh = false)
```

| Parameter          | Data Type | Description                                                                                                          |
| ------------------ | --------- | -------------------------------------------------------------------------------------------------------------------- |
| **`forceRefresh`** | `Boolean` | (Optional) When `true`, queries Play Install Referrer again even if the SDK already checked it. Defaults to `false`. |

Returns `GrowSurfAttribution?`. Returns `null` when no GrowSurf referral value is found.

#### **Example use**

```kotlin
val attribution = growsurf.handleDeferredDeepLink()
```

{% hint style="info" %}
`addReferredParticipant(...)` checks Play Install Referrer automatically when no explicit or pending attribution exists. Call this manually only when you want to inspect attribution earlier.
{% endhint %}

***

### Handle attribution parameters

Call this from an attribution provider callback, such as Branch, Adjust, AppsFlyer, or Singular. If the parameters include `grsf`, `ref`, or `referredBy` directly or inside URL-like values, the SDK saves the attribution for signup.

```kotlin
growsurf.handleAttributionParameters(parameters, provider = "branch")
```

| Parameter        | Data Type             | Description                                                                                                                                     |
| ---------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **`parameters`** | `Map<String, String>` | (Required) Provider callback parameters. The SDK recognizes direct values and nested URL-like values containing `grsf`, `ref`, or `referredBy`. |
| **`provider`**   | `String?`             | (Optional) Attribution provider name, such as `branch`, `adjust`, `appsflyer`, or `singular`.                                                   |

Returns `GrowSurfAttribution?`. Returns `null` when no GrowSurf referral value is found.

#### **Example use**

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

***

### Get pending attribution

Use this to inspect referral attribution saved on this device before creating or signing in a participant.

```kotlin
growsurf.getPendingAttribution()
```

Returns `GrowSurfAttribution?`.

#### **Example use**

```kotlin
val attribution = growsurf.getPendingAttribution()
```

***

### Clear pending attribution

Clear saved referral attribution when it should no longer apply, such as after you handle it or when a different user signs in.

```kotlin
growsurf.clearPendingAttribution()
```

Returns `Unit`.

#### **Example use**

```kotlin
growsurf.clearPendingAttribution()
```

***

### Validate referrer

Use this to check whether a saved or supplied referrer is valid before you show a referred state or create a participant.

```kotlin
growsurf.validateReferrer(attribution)
```

| Parameter         | Data Type              | Description                                                                                           |
| ----------------- | ---------------------- | ----------------------------------------------------------------------------------------------------- |
| **`attribution`** | `GrowSurfAttribution?` | (Optional) Attribution to validate. If omitted, the SDK validates locally stored pending attribution. |

Returns `GrowSurfValidateReferrerResponse`.

#### **Example use**

{% tabs %}
{% tab title="Pending attribution" %}

```kotlin
val validation = growsurf.validateReferrer()

if (validation.valid) {
    Log.d("GrowSurf", "Valid referrer: ${validation.referredBy}")
}
```

{% endtab %}

{% tab title="Explicit referrer" %}

```kotlin
val validation = growsurf.validateReferrer("referrer_id")

if (validation.valid) {
    Log.d("GrowSurf", "Valid referrer")
}
```

{% endtab %}
{% endtabs %}

***

## PARTICIPANTS ↓

### Add referred participant

Use this for referred signups. The SDK looks for saved attribution, an explicit referrer, or Play Install Referrer attribution, validates it, and only creates the participant when the referral is valid.

{% tabs %}
{% tab title="Kotlin coroutine" %}

```kotlin
val result = growsurf.addReferredParticipant(
    GrowSurfParticipantInput(
        email = "person@example.com",
        firstName = "Ada",
        lastName = "Lovelace",
        metadata = mapOf("plan" to "pro"),
    ),
)

if (result.added) {
    Log.d("GrowSurf", "Referred participant: ${result.participant?.id}")
}
```

{% endtab %}

{% tab title="Java callback" %}

```java
Map<String, String> metadata = new HashMap<>();
metadata.put("plan", "pro");

GrowSurfParticipantInput input = new GrowSurfParticipantInput(
    "person@example.com",
    "Ada",
    "Lovelace",
    null,
    null,
    metadata
);

growsurf.addReferredParticipant(
    input,
    new GrowSurfCallback<GrowSurfAddReferredParticipantResponse>() {
        @Override
        public void onSuccess(GrowSurfAddReferredParticipantResponse result) {
            if (result.getAdded()) {
                GrowSurfParticipant participant = result.getParticipant();
            }
        }

        @Override
        public void onError(Throwable error) {
            Log.e("GrowSurf", "Add referred participant error", error);
        }
    }
);
```

{% endtab %}
{% endtabs %}

| Parameter      | Data Type                                                  | Description                                                                                                 |
| -------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **`input`**    | `GrowSurfParticipantInput`                                 | (Required) Participant fields, optional explicit `referredBy`, optional attribution, and optional metadata. |
| **`callback`** | `GrowSurfCallback<GrowSurfAddReferredParticipantResponse>` | (Optional) Java-friendly callback overload.                                                                 |

Returns `GrowSurfAddReferredParticipantResponse`.

{% hint style="info" %}
If no participant is added, `notAddedReason` will be `NO_REFERRER`, `INVALID_REFERRER`, or `PARTICIPANT_ALREADY_EXISTS`.
{% endhint %}

***

### Add participant

Use this for public signup flows where the SDK can create a participant even without a referral. It sends pending attribution when available, stores the returned participant token when present, and includes the SDK-generated mobile instance ID for anti-fraud.

{% tabs %}
{% tab title="Kotlin coroutine" %}

```kotlin
val response = growsurf.addParticipant(
    GrowSurfParticipantInput(
        email = "person@example.com",
        firstName = "Ada",
        lastName = "Lovelace",
        metadata = mapOf("plan" to "pro"),
    ),
)

response.participant?.let { participant ->
    Log.d("GrowSurf", "Created participant: ${participant.id}")
}
```

{% endtab %}

{% tab title="Java callback" %}

```java
Map<String, String> metadata = new HashMap<>();
metadata.put("plan", "pro");

GrowSurfParticipantInput input = new GrowSurfParticipantInput(
    "person@example.com",
    "Ada",
    "Lovelace",
    null,
    null,
    metadata
);

growsurf.addParticipant(
    input,
    new GrowSurfCallback<GrowSurfCreateParticipantResponse>() {
        @Override
        public void onSuccess(GrowSurfCreateParticipantResponse result) {
            GrowSurfParticipant participant = result.getParticipant();
            if (participant != null) {
                Log.d("GrowSurf", "Created participant: " + participant.getId());
            }
        }

        @Override
        public void onError(Throwable error) {
            Log.e("GrowSurf", "Create participant error", error);
        }
    }
);
```

{% endtab %}
{% endtabs %}

| Parameter      | Data Type                                             | Description                                                                 |
| -------------- | ----------------------------------------------------- | --------------------------------------------------------------------------- |
| **`input`**    | `GrowSurfParticipantInput`                            | (Required) Participant fields, optional attribution, and optional metadata. |
| **`callback`** | `GrowSurfCallback<GrowSurfCreateParticipantResponse>` | (Optional) Java-friendly callback overload.                                 |

Returns `GrowSurfCreateParticipantResponse`.

{% hint style="info" %}
Use this method for public signup flows where the SDK should create a new participant. If the email already belongs to an existing participant, GrowSurf returns `requiresParticipantToken: true` and does not return a participant token. For signed-in or existing users, use an SDK-issued participant token you already have, or create a mobile participant token from your backend, then pass it to `setParticipantToken(...)` or `GrowSurfWindowIdentity.ExistingParticipantToken(...)`.
{% endhint %}

***

### Get participant

Use this after you have a participant token to load the participant's referral data, including their referral link and counts.

```kotlin
growsurf.getParticipant()
```

Returns `GrowSurfParticipant`.

#### **Example use**

```kotlin
val participant = growsurf.getParticipant()
Log.d("GrowSurf", participant.shareUrl.orEmpty())
```

***

### Update participant

Use this when your app lets a participant update profile fields, such as first name, last name, or metadata.

```kotlin
growsurf.updateParticipant(input)
```

| Parameter   | Data Type                        | Description                                                                   |
| ----------- | -------------------------------- | ----------------------------------------------------------------------------- |
| **`input`** | `GrowSurfParticipantUpdateInput` | (Required) Fields to update, such as `firstName`, `lastName`, and `metadata`. |

Returns `GrowSurfParticipant`.

#### **Example use**

```kotlin
val participant = growsurf.updateParticipant(
    GrowSurfParticipantUpdateInput(
        firstName = "Ada",
        lastName = "Lovelace",
        metadata = mapOf("plan" to "enterprise"),
    ),
)
```

***

### Update vanity links

Use this when your app lets a participant manage multiple custom referral link keys at once.

```kotlin
growsurf.updateVanityLinks(vanityKeys)
```

| Parameter        | Data Type      | Description                                               |
| ---------------- | -------------- | --------------------------------------------------------- |
| **`vanityKeys`** | `List<String>` | (Required) Vanity keys to associate with the participant. |

Returns `GrowSurfParticipant`.

#### **Example use**

```kotlin
val participant = growsurf.updateVanityLinks(
    vanityKeys = listOf("ada", "ada-pro"),
)
```

***

## REFERRALS AND INVITES ↓

### Get participant referrals

Use this to show who a participant has referred and the status of each referral.

```kotlin
growsurf.getParticipantReferrals(
    limit = 20,
    offset = 0,
)
```

| Parameter    | Data Type | Description                               |
| ------------ | --------- | ----------------------------------------- |
| **`limit`**  | `Int?`    | (Optional) Number of referrals to return. |
| **`offset`** | `Int?`    | (Optional) Offset for pagination.         |

Returns `GrowSurfReferralsResponse`.

#### **Example use**

```kotlin
val response = growsurf.getParticipantReferrals(
    limit = 20,
)

response.referrals.forEach { referral ->
    Log.d("GrowSurf", "${referral.email}: ${referral.referralStatus}")
}
```

***

### Send invites

Use this to send referral invite emails from a participant's referral screen.

```kotlin
growsurf.sendInvites(
    emailAddresses = listOf("friend@example.com"),
    messageText = "Join me on GrowSurf",
    subjectText = "You're invited",
)
```

| Parameter            | Data Type      | Description                           |
| -------------------- | -------------- | ------------------------------------- |
| **`emailAddresses`** | `List<String>` | (Required) Email addresses to invite. |
| **`messageText`**    | `String`       | (Required) Invite message body.       |
| **`subjectText`**    | `String?`      | (Optional) Invite email subject.      |

Returns `GrowSurfInviteResponse`.

#### **Example use**

```kotlin
val response = growsurf.sendInvites(
    emailAddresses = listOf("friend@example.com"),
    messageText = "Try this app with my referral link.",
    subjectText = "Join me",
)
```

***

### Track share

Call this after a participant shares their referral link from your UI. GrowSurf records the share type, such as `copy`, `email`, `sms`, or a social channel.

```kotlin
growsurf.trackShare(type)
```

| Parameter  | Data Type | Description                                                                                                               |
| ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------- |
| **`type`** | `String`  | (Required) Share type, such as `copy`, `email`, `sms`, or a social channel type returned by the GrowSurf window response. |

Returns `GrowSurfSuccessResponse`.

#### **Example use**

```kotlin
growsurf.trackShare(
    type = "copy",
)
```

***

## REFERRAL PROGRAMS ↓

### Trigger referral

<mark style="color:orange;">Referral programs only</mark>

Use this when a referred participant completes the in-app action that should count as a referral conversion. For purchases or other high-trust events, trigger referral credit from your backend instead.

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

Returns `GrowSurfSuccessResponse`.

#### **Example use**

```kotlin
val response = growsurf.triggerReferral()
```

{% hint style="warning" %}
For server-verified purchases, subscriptions, or other high-trust reward events, trigger referral credit from your backend using the REST API or a GrowSurf integration instead of from the app.
{% endhint %}

***

### Get participant rewards

<mark style="color:orange;">Referral programs only</mark>

Use this to show the rewards a participant has earned or can track inside your app.

```kotlin
growsurf.getParticipantRewards(
    limit = 20,
    nextId = null,
)
```

| Parameter    | Data Type | Description                             |
| ------------ | --------- | --------------------------------------- |
| **`limit`**  | `Int?`    | (Optional) Number of rewards to return. |
| **`nextId`** | `String?` | (Optional) Cursor ID for the next page. |

Returns `GrowSurfRewardsResponse`.

#### **Example use**

```kotlin
val rewards = growsurf.getParticipantRewards(
    limit = 20,
)
```

***

### Mark participant rewards read

<mark style="color:orange;">Referral programs only</mark>

Call this after showing reward notifications so GrowSurf can clear the participant's unread reward state.

```kotlin
growsurf.markParticipantRewardsRead()
```

Returns `GrowSurfSuccessResponse`.

#### **Example use**

```kotlin
growsurf.markParticipantRewardsRead()
```

***

### Get participant referral summary

<mark style="color:orange;">Referral programs only</mark>

Use this for referral programs to show a participant's high-level referral stats (referrals, leads, expired referrals, clicks, rewards earned, pending rewards, invites sent).

```kotlin
growsurf.getParticipantReferralSummary()
```

Returns `GrowSurfReferralSummary`.

#### **Example use**

```kotlin
val summary = growsurf.getParticipantReferralSummary()
Log.d("GrowSurf", "Referrals: ${summary.referrals}")
```

***

## AFFILIATE PROGRAMS ↓

### Get participant commissions

<mark style="color:orange;">Affiliate programs only</mark>

Use this for affiliate programs to show a participant's commission history.

```kotlin
growsurf.getParticipantCommissions(
    limit = 20,
    nextId = null,
)
```

| Parameter    | Data Type | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| **`limit`**  | `Int?`    | (Optional) Number of commissions to return. |
| **`nextId`** | `String?` | (Optional) Cursor ID for the next page.     |

Returns `GrowSurfCommissionsResponse`.

#### **Example use**

```kotlin
val commissions = growsurf.getParticipantCommissions(
    limit = 20,
)
```

***

### Mark participant commissions read

<mark style="color:orange;">Affiliate programs only</mark>

Call this after showing commission notifications so GrowSurf can clear the participant's unread commission state.

```kotlin
growsurf.markParticipantCommissionsRead()
```

Returns `GrowSurfSuccessResponse`.

#### **Example use**

```kotlin
growsurf.markParticipantCommissionsRead()
```

***

### Get participant payouts

<mark style="color:orange;">Affiliate programs only</mark>

Use this for affiliate programs to show a participant's payout history.

```kotlin
growsurf.getParticipantPayouts(
    limit = 20,
    nextId = null,
)
```

| Parameter    | Data Type | Description                             |
| ------------ | --------- | --------------------------------------- |
| **`limit`**  | `Int?`    | (Optional) Number of payouts to return. |
| **`nextId`** | `String?` | (Optional) Cursor ID for the next page. |

Returns `GrowSurfPayoutsResponse`.

#### **Example use**

```kotlin
val payouts = growsurf.getParticipantPayouts(
    limit = 20,
)
```

***

### Mark participant payouts read

<mark style="color:orange;">Affiliate programs only</mark>

Call this after showing payout notifications so GrowSurf can clear the participant's unread payout state.

```kotlin
growsurf.markParticipantPayoutsRead()
```

Returns `GrowSurfSuccessResponse`.

#### **Example use**

```kotlin
growsurf.markParticipantPayoutsRead()
```

***

### Get participant affiliate summary

<mark style="color:orange;">Affiliate programs only</mark>

Use this for affiliate programs to show a participant's high-level affiliate stats, such as referral revenue, total paid out, and upcoming payout.

```kotlin
growsurf.getParticipantAffiliateSummary()
```

Returns `GrowSurfAffiliateSummary`.

#### **Example use**

```kotlin
val summary = growsurf.getParticipantAffiliateSummary()
Log.d("GrowSurf", "Upcoming payout: ${summary.upcomingPayout}")
```

***

### Request PayPal confirm email

<mark style="color:orange;">Affiliate programs only</mark>

Use this when your affiliate program needs the participant to confirm their PayPal email before payouts can continue.

```kotlin
growsurf.requestPaypalConfirmEmail()
```

Returns `GrowSurfSuccessResponse`.

#### **Example use**

```kotlin
val response = growsurf.requestPaypalConfirmEmail()
```

***

### Request tax info session

Use this when the campaign requires tax documentation and the participant needs to complete or resubmit their W-9 / W-8 form before rewards or payouts can continue. It starts a secure hosted tax-form session and returns the hosted URL to open (in a browser or Chrome Custom Tab) plus the participant's new tax status. The native GrowSurf window calls this automatically from its Tax Forms settings row; call it yourself only if you build a custom settings UI.

```kotlin
growsurf.requestTaxInfoSession()
```

Returns `GrowSurfTaxSessionResponse`.

#### **Example use**

```kotlin
val session = growsurf.requestTaxInfoSession()
session.hostedUrl?.let { url ->
    startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
}
```

{% hint style="info" %}
GrowSurf never stores participant tax IDs. The W-9 / W-8 is completed on a hosted page served by GrowSurf's IRS-authorized e-file partner.
{% endhint %}

***

## ATTRIBUTION ADAPTERS ↓

### Branch attribution adapter

Use this helper when Branch returns attribution data. It normalizes Branch payloads and can store the resulting GrowSurf attribution on the SDK.

```kotlin
GrowSurfBranchAttribution.normalize(parameters)
GrowSurfBranchAttribution.handle(parameters, growsurf)
```

| Method                                                     | Description                                                            |
| ---------------------------------------------------------- | ---------------------------------------------------------------------- |
| **`normalize(parameters: Map<String, *>)`**                | Converts a mixed map, then parses attribution without storing it.      |
| **`normalize(json: JSONObject)`**                          | Parses JSON attribution without storing it.                            |
| **`handle(parameters: Map<String, *>, sdk: GrowSurfSdk)`** | Converts, parses, and stores attribution on the provided SDK instance. |
| **`handle(json: JSONObject, sdk: GrowSurfSdk)`**           | Parses and stores attribution on the provided SDK instance.            |

#### **Example use**

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

```kotlin
import com.growsurf.sdk.attribution.branch.GrowSurfBranchAttribution

val attribution = GrowSurfBranchAttribution.handle(branchParams, growsurf)
```

{% endtab %}

{% tab title="Java normalize" %}

```java
GrowSurfAttribution attribution = GrowSurfBranchAttribution.normalize(branchJson);
```

{% endtab %}
{% endtabs %}

***

### Adjust attribution adapter

Use this helper when Adjust returns a deep link. It normalizes the URI or URL and can store the resulting GrowSurf attribution on the SDK.

```kotlin
GrowSurfAdjustAttribution.normalize(uri)
GrowSurfAdjustAttribution.handle(uri, growsurf)
```

| Method                                      | Description                                                         |
| ------------------------------------------- | ------------------------------------------------------------------- |
| **`normalize(uri: Uri)`**                   | Parses a URI and returns `GrowSurfAttribution?` without storing it. |
| **`normalize(url: String)`**                | Parses a URL string or encoded URL string without storing it.       |
| **`handle(uri: Uri, sdk: GrowSurfSdk)`**    | Parses and stores attribution on the provided SDK instance.         |
| **`handle(url: String, sdk: GrowSurfSdk)`** | Parses and stores attribution on the provided SDK instance.         |

#### **Example use**

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

```kotlin
import com.growsurf.sdk.attribution.adjust.GrowSurfAdjustAttribution

val attribution = GrowSurfAdjustAttribution.handle(adjustDeepLink, growsurf)
```

{% endtab %}

{% tab title="Java normalize" %}

```java
GrowSurfAttribution attribution = GrowSurfAdjustAttribution.normalize(adjustUri);
```

{% endtab %}
{% endtabs %}

***

### AppsFlyer attribution adapter

Use this helper when AppsFlyer returns conversion or deep link data. It normalizes the payload and can store the resulting GrowSurf attribution on the SDK.

```kotlin
GrowSurfAppsFlyerAttribution.normalize(parameters)
GrowSurfAppsFlyerAttribution.handle(parameters, growsurf)
```

| Method                                                     | Description                                                            |
| ---------------------------------------------------------- | ---------------------------------------------------------------------- |
| **`normalize(parameters: Map<String, *>)`**                | Converts a mixed map, then parses attribution without storing it.      |
| **`normalize(json: JSONObject)`**                          | Parses JSON attribution without storing it.                            |
| **`handle(parameters: Map<String, *>, sdk: GrowSurfSdk)`** | Converts, parses, and stores attribution on the provided SDK instance. |
| **`handle(json: JSONObject, sdk: GrowSurfSdk)`**           | Parses and stores attribution on the provided SDK instance.            |

#### **Example use**

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

```kotlin
import com.growsurf.sdk.attribution.appsflyer.GrowSurfAppsFlyerAttribution

val attribution = GrowSurfAppsFlyerAttribution.handle(conversionData, growsurf)
```

{% endtab %}

{% tab title="Java normalize" %}

```java
GrowSurfAttribution attribution = GrowSurfAppsFlyerAttribution.normalize(conversionJson);
```

{% endtab %}
{% endtabs %}

***

### Singular attribution adapter

Use this helper when Singular returns callback parameters or deep link values. It normalizes the payload and can store the resulting GrowSurf attribution on the SDK.

```kotlin
GrowSurfSingularAttribution.normalize(parameters)
GrowSurfSingularAttribution.handle(parameters, growsurf)
```

| Method                                                     | Description                                                            |
| ---------------------------------------------------------- | ---------------------------------------------------------------------- |
| **`normalize(parameters: Map<String, *>)`**                | Converts a mixed map, then parses attribution without storing it.      |
| **`normalize(json: JSONObject)`**                          | Parses JSON attribution without storing it.                            |
| **`normalize(uri: Uri)`**                                  | Parses a URI without storing it.                                       |
| **`normalize(url: String)`**                               | Parses a URL string or encoded URL string without storing it.          |
| **`handle(parameters: Map<String, *>, sdk: GrowSurfSdk)`** | Converts, parses, and stores attribution on the provided SDK instance. |
| **`handle(json: JSONObject, sdk: GrowSurfSdk)`**           | Parses and stores attribution on the provided SDK instance.            |
| **`handle(uri: Uri, sdk: GrowSurfSdk)`**                   | Parses and stores attribution on the provided SDK instance.            |
| **`handle(url: String, sdk: GrowSurfSdk)`**                | Parses and stores attribution on the provided SDK instance.            |

#### **Example use**

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

```kotlin
import com.growsurf.sdk.attribution.singular.GrowSurfSingularAttribution

val attribution = GrowSurfSingularAttribution.handle(singularPayload, growsurf)
```

{% endtab %}

{% tab title="Java normalize" %}

```java
GrowSurfAttribution attribution = GrowSurfSingularAttribution.normalize(singularJson);
```

{% endtab %}
{% endtabs %}

***

## UTILITIES ↓

### Normalize attribution parameters

Use this when you need to read GrowSurf attribution from raw provider parameters without storing it. It looks for `grsf`, `ref`, or `referredBy` directly and inside URL-like values.

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

```kotlin
val attribution = GrowSurfAttributionNormalizer.normalize(
    parameters = mapOf(
        "deep_link_value" to "https://example.com/signup?grsf=referrer_id",
        "click_id" to "click_123",
    ),
    provider = "appsflyer",
)
```

{% endtab %}

{% tab title="Java" %}

```java
Map<String, String> parameters = new HashMap<>();
parameters.put("deep_link_value", "https://example.com/signup?grsf=referrer_id");
parameters.put("click_id", "click_123");

GrowSurfAttribution attribution = GrowSurfAttributionNormalizer.normalize(
    parameters,
    "appsflyer"
);
```

{% endtab %}
{% endtabs %}

| Parameter        | Data Type             | Description                                                                                |
| ---------------- | --------------------- | ------------------------------------------------------------------------------------------ |
| **`parameters`** | `Map<String, String>` | (Required) Raw parameters. The normalizer checks direct fields and URL-like nested values. |
| **`provider`**   | `String?`             | (Optional) Provider name to attach to the attribution result.                              |

Returns `GrowSurfAttribution?`.

***

### Normalize attribution URI

Use this when you need to parse a URI for `grsf`, `ref`, or `referredBy` without storing attribution on the SDK.

```kotlin
GrowSurfAttributionNormalizer.normalize(uri, provider = "adjust")
```

| Parameter      | Data Type | Description                                                   |
| -------------- | --------- | ------------------------------------------------------------- |
| **`uri`**      | `Uri`     | (Required) URI to parse.                                      |
| **`provider`** | `String?` | (Optional) Provider name to attach to the attribution result. |

Returns `GrowSurfAttribution?`.

#### **Example use**

```kotlin
val attribution = GrowSurfAttributionNormalizer.normalize(
    Uri.parse("https://example.com/signup?grsf=referrer_id"),
    provider = "adjust",
)
```

***

### Normalize attribution JSON

Use this when a provider gives you a JSON payload and you need to find `grsf`, `ref`, or `referredBy` without storing attribution on the SDK.

```kotlin
GrowSurfAttributionNormalizer.normalize(json, provider = "branch")
```

| Parameter      | Data Type    | Description                                                   |
| -------------- | ------------ | ------------------------------------------------------------- |
| **`json`**     | `JSONObject` | (Required) JSON provider payload.                             |
| **`provider`** | `String?`    | (Optional) Provider name to attach to the attribution result. |

Returns `GrowSurfAttribution?`.

#### **Example use**

```kotlin
val attribution = GrowSurfAttributionNormalizer.normalize(
    JSONObject().put("~referring_link", "https://example.com?grsf=referrer_id"),
    provider = "branch",
)
```

***

### Convert attribution parameters to strings

Use this before passing mixed provider callback payloads to the normalizer or SDK attribution methods. It converts nested values into a `Map<String, String>` without storing attribution.

```kotlin
GrowSurfAttributionNormalizer.stringParameters(parameters)
```

| Parameter        | Data Type                        | Description                                                                           |
| ---------------- | -------------------------------- | ------------------------------------------------------------------------------------- |
| **`parameters`** | `Map<String, *>` or `JSONObject` | (Required) Provider callback payload. Nested values are flattened into string values. |

Returns `Map<String, String>`.

#### **Example use**

```kotlin
val stringParameters = GrowSurfAttributionNormalizer.stringParameters(providerPayload)

growsurf.handleAttributionParameters(
    stringParameters,
    provider = "branch",
)
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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/developer-tools/android-sdk/api-reference.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.
