iOS referral quickstart
Add referrals to an iOS app: install SDK 1.2.0, show the paste button, claim the install with claimReferral, and receive a signed webhook for the reward.
An iPhone install carries no data from the App Store, so the first launch asks the new person to paste the invitation. This quickstart adds that paste button, claims the install when the person signs up, and receives the webhook that tells your backend to grant the reward. It takes four code changes: install the SDK, show the button, call claimReferral, and handle the event.
For the whole path, including the dashboard setup, read the referrals guide.
What you need
- An iOS app registered in WarpLink with its App Store URL. Without it, Offer referral handoff on iOS will not turn on.
- An SDK key from Keys, then SDK keys. If your organization has several apps, create the key for this app.
- iOS 16 or later for the paste button. The SDK itself runs on iOS 15 and later.
- A webhook endpoint, added under Referral handoff, then Webhook. See Receive referral webhooks.
Install SDK 1.2.0
Add the package in Xcode with File, then Add Package Dependencies, and enter https://github.com/WarpLinkApp/warplink-ios-sdk. In Package.swift:
dependencies: [
.package(url: "https://github.com/WarpLinkApp/warplink-ios-sdk", from: "1.2.0")
]
SDK 1.1.x cannot read an invitation. Call WarpLink.configure(apiKey:options:) once at launch, as shown in the iOS SDK setup.
Mark a link as a referral link
Open a link in the dashboard and turn on Referral link, or send is_referral over REST:
curl -X POST https://api.warplink.app/v1/links \
-H "Authorization: Bearer wl_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"app_id": "YOUR_APP_ID",
"slug": "invite-ana",
"destination_url": "https://example.com/invite",
"is_referral": true
}'
Store the returned link id with the user who shares it. The webhook names that link, and the id tells you whose invitation earned the credit. Create referral links covers converting existing links in bulk.
Read the invitation
A friend taps the link on an iPhone without your app. They see the invitation page, which copies an invitation, then the App Store. On first launch, your app shows the paste button.
import SwiftUI
import WarpLink
@available(iOS 16.0, *)
struct WelcomeView: View {
@State private var message: String?
var body: some View {
VStack(spacing: 16) {
Text("Did a friend invite you?")
WarpLinkPasteButton { result in
switch result {
case .success(let link):
// nil means nothing was confirmed.
if link != nil { message = "Invitation applied." }
case .failure(let error):
message = error.localizedDescription
}
}
if let message { Text(message) }
Button("Skip") { continueOnboarding() }
}
}
}import UIKit
import WarpLink
@available(iOS 16.0, *)
final class WelcomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let paste = WarpLinkUIPasteButton { [weak self] result in
switch result {
case .success(let link):
if link != nil { self?.showApplied() }
case .failure(let error):
self?.showMessage(error.localizedDescription)
}
}
paste.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(paste)
NSLayoutConstraint.activate([
paste.centerXAnchor.constraint(equalTo: view.centerXAnchor),
paste.centerYAnchor.constraint(equalTo: view.centerYAnchor),
paste.widthAnchor.constraint(equalToConstant: 200),
paste.heightAnchor.constraint(equalToConstant: 44),
])
}
}// Use this when you collect the invitation text yourself.
WarpLink.redeemInvitation(text: pastedText) { result in
switch result {
case .success(let link):
if link != nil { showApplied() } // nil: not an invitation, or no match
case .failure(let error):
showMessage(error.localizedDescription)
}
}WarpLinkPasteButton (SwiftUI) and WarpLinkUIPasteButton (UIKit) use the system paste control. The person pastes with one tap and no prompt, and the SDK sees only the text the button hands over. The SDK never reads the pasteboard on its own. Both buttons need iOS 16. On iOS 15, show a text field and use the Your own text tab.
The paste step is an offer, not a gate. Keep a Skip button, and show the invitation as applied only when you get a link back. A failure carries a message that tells the person to open the invitation link again, so you can show it as it is.
Claim the install
When the friend signs up, call claimReferral with an installer id: a dedicated random id for the new user, up to 128 characters. Do not use a primary key, an email address or a phone number.
WarpLink.claimReferral(installerId: user.warplinkId) { result in
switch result {
case .success(let claim):
handle(claim)
case .failure(let error):
// Unreachable server, refused key, or an empty or too long installer id.
log(error)
}
}
claimReferral(installerId:completion:) is safe to repeat. The first valid claim for an app and installer id wins, and the same call again returns the same claim.
Handle each status
claim.status is a ReferralClaimResult.Status:
func handle(_ claim: ReferralClaimResult) {
switch claim.status {
case .claimed:
break // credited inside the window. Your webhook grants the reward.
case .flagged:
break // credited after the window closed: claim.flags holds "outside_window"
case .ignored:
break // this installer already holds a credit: see claim.duplicateOf
case .none:
break // no referral link brought this install. Not an error.
}
}
status | What to do in the app |
|---|---|
.claimed | Nothing more. The webhook is on its way |
.flagged | Nothing more. Your backend decides from the referral.flagged event |
.ignored | Nothing. A reward is never granted twice from our side |
.none | Carry on. The install did not come from a referral link |
The result also carries referralId, linkId, linkUrl, matchMethod, isExact, matchConfidence, flags, duplicateOf, updated and replayState. A match from the pasted invitation reads install_token with isExact true.
For rewards of value, claim from your backend with POST /v1/referrals/claims and let your own rules decide when a sign-up has earned one. See Claim from the SDK or from your backend.
Receive the webhook
Your endpoint receives referral.claimed within seconds of the claim. Verify the signature on the raw body, skip an event id you have seen, then grant the reward in your own system:
if (event.type === 'referral.claimed') {
await grantReward({
inviterLinkId: event.data.link.id,
newUserId: event.data.installer_id,
exact: event.data.match.exact,
});
}
Receive referral webhooks has the signature code for Node.js and Python, and Reward recipes shows how to turn an event into a reward.
Test it
Test on a real iPhone: delete the app, tap the link, install from TestFlight or the App Store, tap the paste button, sign up with a fresh installer id, and claim. Test referrals lists the steps and the checks.
Next
- Referrals guide for setup, credit windows and the report
- Test referrals and Reward recipes
- iOS attribution for match types and evidence fields
- Android quickstart, React Native quickstart, Flutter quickstart
Referrals
Credit an install to the invitation link that brought it. Set up the iPhone paste step, claim from your app or backend, and receive a signed webhook.
Android referral quickstart
Add referrals to an Android app: install SDK 1.2.0, let the Play install referrer carry the invitation, call claimReferral, and receive a signed webhook.