·6 min read·Sam Wild

How to Set Up Purchase Attribution with RevenueCat

RevenueCat handles your purchases. LinkOwl tracks where those purchases came from. Here's how to wire them together in about 15 minutes.

RevenueCat is genuinely excellent for managing in-app purchases. It abstracts away StoreKit pain, handles entitlements, and gives you clean purchase data without much effort.

What it doesn't do is tell you where those purchases came from. A purchase shows up in your RevenueCat dashboard with a price and a timestamp, but not the Instagram post or Reddit thread that led to it.

That gap is where attribution comes in. This guide walks through connecting RevenueCat to LinkOwl so you can see, per purchase, which marketing link drove it.

How the integration works

When a user taps a LinkOwl link, their device is marked with that link's attribution data. If they install your app and make a purchase, LinkOwl's SDK sends the attribution data alongside the purchase event.

When you also have RevenueCat set up, there are two ways the data flows:

  1. SDK-based: LinkOwl's SDK runs alongside RevenueCat's SDK in your app. After a successful purchase, you call a LinkOwl method to record it. LinkOwl attaches the attribution from the original link tap.

  2. Webhook-based: RevenueCat sends a webhook event to LinkOwl when a purchase completes. LinkOwl matches the appUserId to any stored attribution and marks the purchase.

The webhook approach is simpler if you don't want another SDK in your app. The SDK approach gives you a bit more control and works even if the user was offline when they tapped the link. For most apps I'd start with the webhook.

Setting up the RevenueCat webhook

In your LinkOwl dashboard:

Go to your app's settings page. You'll see a "RevenueCat Webhook" section with a webhook URL that looks like:

https://api.linkowl.app/v1/webhooks/revenuecat/YOUR_APP_ID

Copy that URL. You'll also see a webhook secret — copy that too.

In RevenueCat:

  1. Go to your project in the RevenueCat dashboard
  2. Navigate to Integrations in the left sidebar
  3. Click Webhooks
  4. Click Add webhook
  5. Paste your LinkOwl webhook URL into the URL field
  6. Set the authentication type to Bearer token and paste your webhook secret
  7. Under "Events to send", enable at minimum: INITIAL_PURCHASE, RENEWAL, NON_SUBSCRIPTION_PURCHASE
  8. Save

RevenueCat will now POST to your LinkOwl endpoint whenever a purchase happens.

Test it:

In RevenueCat, there's a "Send test event" button on the webhook configuration page. Hit it and you should see a test purchase appear in your LinkOwl dashboard within a few seconds. If nothing shows up after 30 seconds, double-check the webhook URL and that the secret is correct.

Setting up the Swift SDK (optional, but recommended)

The webhook handles purchases automatically. The SDK helps with the attribution side: making sure the link tap is recorded before the purchase event arrives.

Install the SDK with Swift Package Manager. In Xcode, go to File > Add Package Dependencies, then add:

https://github.com/linkowl/linkowl-swift

In your app's entry point (usually @main App or AppDelegate):

import LinkOwl

@main
struct MyApp: App {
    init() {
        LinkOwl.configure(apiKey: "lo_live_YOUR_KEY_HERE")
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

That's the SDK set up. When your app is opened via a LinkOwl link, the attribution is recorded automatically. You don't need to do anything else for the link-to-purchase matching to work.

If you want to explicitly track a purchase from the SDK side (bypassing the webhook for that event):

LinkOwl.shared.trackPurchase(
    amount: 4.99,
    currency: "GBP",
    productId: "com.yourapp.monthly"
)

Call this after a confirmed StoreKit transaction. Don't call it if you're using the webhook — you'll double-count purchases.

Matching users across SDK and RevenueCat

The main thing to get right is the user ID. RevenueCat uses an appUserId to identify users. LinkOwl needs to know this ID to match attribution data to purchase webhooks.

If you're using RevenueCat's anonymous user IDs, that's fine. Just make sure the same user hitting a LinkOwl link ends up with the same RevenueCat user ID when they purchase. RevenueCat handles this automatically in most cases.

If you use your own user IDs (logged-in users with accounts), set the LinkOwl user ID to match:

// After user logs in:
LinkOwl.shared.identify(userId: "user_abc123")

And in RevenueCat:

Purchases.shared.logIn("user_abc123") { customerInfo, created, error in
    // handle result
}

Same ID in both systems means the webhook match will work reliably.

What you'll see in LinkOwl

Once this is running, your LinkOwl dashboard shows each link you've created with:

  • Total taps
  • Attributed installs
  • Attributed purchases
  • Revenue from those purchases

So if you created a link for your Product Hunt launch, you'll see something like: 847 taps, 92 installs, 14 purchases, £69.86 revenue. That's the real value of a Product Hunt launch, not the upvote count.

You can also filter by date range to see attribution within specific windows. This is useful for campaigns where you want to know what a specific promotion drove.

A few things that trip people up

Duplicate events. If you use both the SDK's trackPurchase and the RevenueCat webhook, you'll see every purchase twice. Pick one method and stick to it.

Attribution window. By default, purchases are attributed to a link tap within 30 days. A user who taps your link and buys 31 days later won't be attributed. This window is what most attribution tools use as a standard. You can see it in your app settings.

Renewals. By default, only the first purchase from a user is attributed to a link. Renewals are counted as revenue on the original link but listed separately so you can see lifetime value. This behaviour can be changed in settings if you want to attribute every renewal.

RevenueCat sandbox purchases. RevenueCat sandbox events will hit your webhook too. LinkOwl ignores events where environment is SANDBOX, so they won't pollute your real data.

The whole setup should take under 20 minutes. After that you've got purchase attribution running without touching your existing RevenueCat or StoreKit code. The data starts being genuinely useful after a week or two once you have enough volume to see patterns.

If you get stuck on the webhook setup, the webhook logs in your LinkOwl settings page show every incoming event and whether it was matched successfully, which usually makes debugging straightforward.

Track your marketing links with LinkOwl

5p per sale, no subscription. Know exactly which post, influencer, or campaign drove each purchase.

Start tracking free →

Related articles

← Back to all articles