> 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/attribution-providers.md).

# Attribution Providers

On Android, GrowSurf can capture referral attribution from direct deep links, Google Play Install Referrer, or provider callback payloads. Capture attribution before calling `addReferredParticipant()`.

***

## Direct deep links

Use `handleDeepLink(uri)` when the installed app opens from a link that already contains `grsf`, which contains the referral code.

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

{% hint style="info" %}
**Example accepted links:**

* `your-app://open?grsf=referrer_id`
* `https://example.com/app?grsf=referrer_id`
  {% endhint %}

{% hint style="info" %}
**Already support deep links?** If you use an attribution provider (Branch, AppsFlyer, Adjust, Singular) or otherwise open your app from links, this is already set up — just forward the opened `Intent`'s URI to `handleDeepLink(uri)`.

**Starting from scratch?** Add a custom-scheme `<intent-filter>` (`android:scheme`) to your launch Activity in `AndroidManifest.xml` — the quickest path, no domain needed — and/or set up Android App Links (`android:autoVerify="true"` plus an `assetlinks.json` hosted on a domain you control) for verified `https` links. Then read `intent.data` in `onCreate`/`onNewIntent` and call `handleDeepLink(uri)` inside a coroutine scope.

GrowSurf-hosted share links live on `grow.surf` (not your domain), so they can't open your app via App Links — use a custom scheme, your own domain with `grsf` appended, or an attribution provider.
{% endhint %}

***

## Google Play Install Referrer

When Android referral clicks route to Google Play with a Play Install Referrer payload, `addReferredParticipant(...)` checks the install referrer once when no explicit or pending attribution exists. You can also call `handleDeferredDeepLink()` yourself before signup when you want to inspect the attribution result.

```kotlin
lifecycleScope.launch {
    growsurf.handleDeferredDeepLink()
    val created = growsurf.addReferredParticipant(
        GrowSurfParticipantInput(email = "person@example.com")
    )
}
```

By default, the SDK checks the install referrer only once. Pass `forceRefresh = true` while testing if you need to query it again:

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

***

## Adapters

GrowSurf provides adapters for popular attribution providers. Choose your provider below, or use **Other** to pass a dictionary of attribution values from any other provider.

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

## Adjust adapter

Add the adapter artifact:

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

```kotlin
dependencies {
    implementation("com.growsurf:growsurf-android-sdk-attribution-adjust:0.3.0")
}
```

{% endtab %}

{% tab title="Groovy" %}

```groovy
dependencies {
    implementation 'com.growsurf:growsurf-android-sdk-attribution-adjust:0.3.0'
}
```

{% endtab %}
{% endtabs %}

Then pass the Adjust deferred deep link into GrowSurf:

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

GrowSurfAdjustAttribution.handle(adjustDeferredDeepLinkUri, growsurf)
```

The adapter accepts `Uri` and `String` deep link values.
{% endtab %}

{% tab title="AppsFlyer" %}

## AppsFlyer adapter

Add the adapter artifact:

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

```kotlin
dependencies {
    implementation("com.growsurf:growsurf-android-sdk-attribution-appsflyer:0.3.0")
}
```

{% endtab %}

{% tab title="Groovy" %}

```groovy
dependencies {
    implementation 'com.growsurf:growsurf-android-sdk-attribution-appsflyer:0.3.0'
}
```

{% endtab %}
{% endtabs %}

Then pass AppsFlyer conversion data into GrowSurf:

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

GrowSurfAppsFlyerAttribution.handle(appsFlyerConversionData, growsurf)
```

The adapter accepts `Map<String, *>` and `JSONObject` payloads.
{% endtab %}

{% tab title="Branch" %}

## Branch adapter

Add the adapter artifact:

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

```kotlin
dependencies {
    implementation("com.growsurf:growsurf-android-sdk-attribution-branch:0.3.0")
}
```

{% endtab %}

{% tab title="Groovy" %}

```groovy
dependencies {
    implementation 'com.growsurf:growsurf-android-sdk-attribution-branch:0.3.0'
}
```

{% endtab %}
{% endtabs %}

Then pass Branch callback data into GrowSurf:

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

GrowSurfBranchAttribution.handle(branchParams, growsurf)
```

The adapter accepts `Map<String, *>` and `JSONObject` payloads.
{% endtab %}

{% tab title="Singular" %}

## Singular adapter

Add the adapter artifact:

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

```kotlin
dependencies {
    implementation("com.growsurf:growsurf-android-sdk-attribution-singular:0.3.0")
}
```

{% endtab %}

{% tab title="Groovy" %}

```groovy
dependencies {
    implementation 'com.growsurf:growsurf-android-sdk-attribution-singular:0.3.0'
}
```

{% endtab %}
{% endtabs %}

Then pass Singular callback data into GrowSurf:

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

GrowSurfSingularAttribution.handle(singularParams, growsurf)
```

The adapter accepts `Map<String, *>`, `JSONObject`, `Uri`, and `String` payloads. It parses GrowSurf referral keys from Singular deep link, deferred deep link, and passthrough fields such as `_dl`, `_ddl`, and `_p`.
{% endtab %}

{% tab title="Other" %}

## Manual attribution parameters

Use `handleAttributionParameters(parameters, provider)` for any other provider that can return a dictionary of attribution values. No extra adapter install is required.

```kotlin
growsurf.handleAttributionParameters(
    mapOf(
        "grsf" to "referrer_id",
        "click_id" to "click_123",
    ),
    provider = "your-provider-name",
)
```

{% endtab %}
{% endtabs %}

***

## Accepted attribution keys

| Key          | Description                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------ |
| `grsf`       | Preferred GrowSurf referrer ID.                                                                  |
| `ref`        | Alternate referrer ID.                                                                           |
| `referredBy` | Alternate referrer ID.                                                                           |
| `provider`   | Attribution provider name. Ignored when the SDK method receives an explicit `provider` argument. |
| `clickId`    | Provider click ID metadata.                                                                      |
| `click_id`   | Provider click ID metadata.                                                                      |
| `unique`     | Optional boolean string: `true` or `false`.                                                      |

The SDK also parses values nested inside URL-like payload fields. For example, a provider value of `https://example.com/?grsf=referrer_id&click_id=click_123` can still produce GrowSurf attribution. If a provider returns a GrowSurf-hosted share URL such as `https://grow.surf/share/:campaignId/:referrerId`, the SDK uses the participant value from the path.


---

# 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/attribution-providers.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.
