Skip to content
2 changes: 1 addition & 1 deletion api-reference/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ https://api.dub.co

## Authentication

Authentication to Dub's API is performed via the Authorization header with a Bearer token. To authenticate, you need to include the Authorization header with the word `Bearer` followed by your API key in your requests like so:
Authentication to Dub's API is performed via the Authorization header with a Bearer token. To authenticate, you need to include the Authorization header with the word `Bearer` followed by your [API key](/api-reference/tokens) in your requests like so:

```bash Terminal
Authorization: Bearer dub_xxxxxx
Expand Down
32 changes: 32 additions & 0 deletions api-reference/publishable-keys.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: "Publishable keys"
description: "Learn how publishable keys work on Dub."
---

import GeneratePublishableKeyStep from "/snippets/steps/generate-publishable-key.mdx";
import AllowlistDomainsStep from "/snippets/steps/allowlist-domains.mdx";

Publishable keys on Dub allow you to safely embed authentication in client-side applications.
These keys are specifically designed to be used with [Dub's client-side SDKs](/sdks/client-side/introduction) for features like [conversion tracking](/sdks/client-side/features/conversion-tracking).

Unlike [API keys](/api-reference/tokens) which must be kept secret, publishable keys can be safely exposed in your frontend code since they have limited capabilities.

Publishable keys on Dub follow the format:

```bash .env
DUB_PUBLISHABLE_KEY=dub_pk_xxxxxxxxxxxxxxxxxxxxxxxx
```

## Create a publishable key

You can create a publishable key by following these steps:

<Steps>
<GeneratePublishableKeyStep />

<AllowlistDomainsStep />

<Step title="Use your publishable key">
You can now use your publishable key to authenticate client-side requests in your application. Usage will depend on the client-side SDK you are using.
</Step>
</Steps>
199 changes: 197 additions & 2 deletions concepts/deep-links/attribution.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,204 @@ og:title: "How to set up deep link attribution with Dub"
description: "Learn how to use deep link attribution to track conversions events with Dub."
---

import EnableConversionTracking from "/snippets/enable-conversion-tracking.mdx";
import GeneratePublishableKeyStep from "/snippets/steps/generate-publishable-key.mdx";
import AllowlistDomainsStep from "/snippets/steps/allowlist-domains.mdx";
import InstallationGuides from "/snippets/dub-client-mobile-installation-guides.mdx";
import InstallIosSdkStep from "/snippets/steps/install-ios-sdk.mdx";
import InitializeIosSdkStep from "/snippets/steps/initialize-ios-sdk.mdx";
import ViewConversions from "/snippets/view-conversions.mdx";

<Note>
This feature is coming soon. If you'd like early access, please [contact
Deep link attribution requires a [Business plan](https://dub.co/pricing)
subscription or higher.
</Note>

Dub's powerful [attribution platform](https://dub.co/analytics) lets you understand how well your deep links are translating to actual users and revenue dollars inside your app.

<Frame>
<img
src="https://assets.dub.co/blog/introducing-dub-conversions.webp"
alt="Conversion analytics"
/>
</Frame>

<Note>
This feature is currently only available for iOS (Swift). React Native and
Android support are coming soon. If you'd like early access, please [contact
us](https://dub.co/contact/support).
</Note>

With [Dub Conversions](/conversions/quickstart), you can easily track conversion events from your deep links.
## Prerequisites

<EnableConversionTracking />

Then, you'll need generate a [publishable key](/api-reference/publishable-keys) from your Dub workspace to track conversions on the client-side.

To do that, navigate to your [workspace's Analytics settings page](https://app.dub.co/settings/analytics) and generate a new publishable key under the **Publishable Key** section.

<Frame>
<img
src="/images/conversions/publishable-key.png"
alt="Enabling conversion tracking for a workspace"
/>
</Frame>

Once these are set up, we can start tracking conversion events for your deep links.

## Step 1: Install the client-side Mobile SDK

<Tabs>
<Tab title="iOS (SwiftUI)">

Install the [Dub iOS SDK](/sdks/client-side-mobile/installation-guides/swift) and initialize it with your publishable key and short link domain.

<Steps titleSize="h3">

<InstallIosSdkStep />

<InitializeIosSdkStep />

</Steps>
</Tab>
</Tabs>

## Step 2: Track deep link open events

Once the SDK has been initialized, you can start tracking deep link and deferred deep link events.

Call `trackOpen` on the `dub` instance to track deep link and deferred deep link open events. The `trackOpen` function should be called once without a `deepLink` parameter on first launch, and then again with the `deepLink` parameter whenever the app is opened from a deep link.

<CodeGroup>

```swift iOS (SwiftUI) expandable
// ContentView.swift
import SwiftUI
import Dub

struct ContentView: View {

@Environment(\.dub) var dub: Dub

@AppStorage("is_first_launch") private var isFirstLaunch = true

var body: some View {
NavigationStack {
VStack {
// Your app content
}
.onOpenURL { url in
trackOpen(deepLink: url)
}
.onAppear {
if isFirstLaunch {
trackOpen()
isFirstLaunch = false
}
}
}
}

private func trackOpen(deepLink: URL? = nil) {
Task {
do {
let response = try await dub.trackOpen(deepLink: deepLink)

// Obtain the destination URL from the response
guard let url = response.link?.url else {
return
}

// Navigate to the destination URL
} catch let error as DubError {
print(error.localizedDescription)
}
}
}
}
```

</CodeGroup>

If the deep link was successfully resolved and correlated to the original click, the `response` object will contain the destination URL, which you can use to navigate the user to the appropriate screen.

It will also contain the `clickId`, which the `dub` instance will persist internally.

## Step 3: Track conversion events

You may track conversion events directly in your app with the `trackLead` and `trackSale` methods.

<CodeGroup>

```swift iOS (SwiftUI) expandable
// ContentView.swift
import SwiftUI
import Dub

struct ContentView: View {

@Environment(\.dub) var dub: Dub

var body: some View {
// ... your app content ...
}

private func trackLead(customerExternalId: String, name: String, email: String) {
Task {
do {
let response = try await dub.trackLead(
eventName: "Sign Up",
customerExternalId: customerExternalId,
customerName: name,
customerEmail: email
)

print(response)
} catch let error as DubError {
print(error.localizedDescription)
}
}
}

private func trackSale(
customerExternalId: String,
amount: Int,
currency: String = "usd",
eventName: String? = "Purchase",
customerName: String? = nil,
customerEmail: String? = nil,
customerAvatar: String? = nil
) {
Task {
do {
let response = try await dub.trackSale(
customerExternalId: customerExternalId,
amount: amount,
currency: currency,
eventName: eventName,
customerName: customerName,
customerEmail: customerEmail,
customerAvatar: customerAvatar
)

print(response)
} catch let error as DubError {
print(error.localizedDescription)
}
}
}
}
```

</CodeGroup>

Alternatively, you can [track conversion events server-side](/conversions/quickstart#step-3%3A-install-the-dub-server-side-sdk-%2B-track-conversion-events) for [lead events](/conversions/leads/introduction) and [sale events](/conversions/sales/introduction) by sending the `clickId` resolved from the deep link to your backend and then calling off to either:

- [`POST /track/lead`](https://dub.co/docs/api-reference/endpoint/track-lead)
- [`POST /track/sale`](https://dub.co/docs/api-reference/endpoint/track-sale)

## Step 4: View your conversions

Once you've enabled conversion tracking for your links, all your tracked conversions will show up on your [Analytics dashboard](https://app.dub.co/analytics). We provide 3 different views to help you understand your conversions:

<ViewConversions />
10 changes: 5 additions & 5 deletions concepts/deep-links/deferred-deep-linking.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ Here is how it works in a nutshell:
2. Dub copies the deep link URL to the clipboard.
3. The user is redirected to the App Store to download your app.
4. After installation, your app reads the clipboard to retrieve the deep link.
5. Your app calls the [`/track/open` endpoint](/api-reference/endpoint/track-open) with the `deepLink` parameter in the request body.
5. Your app calls the [`/track/open` endpoint](/api-reference/endpoint/track-open) with the `deepLink` parameter in the request body either directly or via a supported [Dub Mobile SDK](/sdks/client-side-mobile/introduction).
6. Dub returns the destination URL, and your app navigates the user to the appropriate screen (see [deep links quickstart](/concepts/deep-links/quickstart) for more details).

#### 2. Probabilistic IP-based tracking
Expand All @@ -479,7 +479,7 @@ This method relies on matching the user’s device IP address from the initial c
1. User taps **Get the App without Copying** button on the landing page.
2. The user is redirected directly to the App Store to download your app.
3. Dub has already tracked the click and stored the IP address at the time of deep link click.
4. After installation, your app calls the [`/track/open` endpoint](/api-reference/endpoint/track-open) with the `dubDomain` parameter in the request body.
4. After installation, your app calls the [`/track/open` endpoint](/api-reference/endpoint/track-open) with the `dubDomain` parameter in the request body either directly or via a supported [Dub Mobile SDK](/sdks/client-side-mobile/introduction) .
5. Dub matches the user using IP-based tracking and returns the destination URL.
6. If a destination URL is returned, your app navigates the user to the appropriate screen (see [deep links quickstart](/concepts/deep-links/quickstart) for more details).

Expand All @@ -488,7 +488,7 @@ This method relies on matching the user’s device IP address from the initial c
The following logic determines whether to use clipboard-based tracking or IP-based tracking:

- **Clipboard-based tracking**: Used when a deep link is found in the clipboard (e.g., `acme.link`). The app sends the `deepLink` parameter in the request body.
- **IP-based tracking**: Used when no deep link is found in the clipboard. The app sends only the `dubDomain` parameter, allowing Dub to match the user based on their IP address.
- **IP-based tracking**: Used when no deep link is found in the clipboard or the user declined paste permissions. The app sends only the `dubDomain` parameter, allowing Dub to match the user based on their IP address.

This ensures the most reliable tracking method is chosen automatically.

Expand Down Expand Up @@ -555,7 +555,7 @@ async function trackOpen() {
}
```

```swift iOS expandable
```swift iOS (SwiftUI) expandable
import SwiftUI

@main
Expand Down Expand Up @@ -677,7 +677,7 @@ export default function App() {
}
```

```swift iOS expandable
```swift iOS (SwiftUI) expandable
import SwiftUI

struct ContentView: View {
Expand Down
Loading