React Native SDK
One integration for iOS + Android. Pure JS/TS over fetch — no native modules to link.
Integrate MyAppAffiliate into my project. Documentation (read these first, they are the source of truth): - Page: https://docs.myappaffiliate.com/sdk-react-native.md - Full docs index: https://docs.myappaffiliate.com/llms.txt Task: Add the MyAppAffiliate React Native SDK to my app: install the package, start it once at app startup passing AsyncStorage and Linking, and identify the user with the same id my billing provider reports. Tell me what changes if I'm on Expo. Rules: - Follow the documented API exactly — no invented method names, endpoints, parameters or field names. - Match the conventions already used in my codebase. - Ask me for my SDK key instead of guessing, and never hard-code it — read it from config/environment. - Do NOT set an API base URL anywhere. Every SDK compiles the production host in; a staging or self-hosted host belongs in a build setting, not in code. - Tell me afterwards which steps I still have to do by hand (dashboard settings, capabilities, webhook configuration).
Install
npm i @myappaffiliate/sdk-react-native @react-native-async-storage/async-storage1. Start it
import AsyncStorage from "@react-native-async-storage/async-storage";
import { Linking } from "react-native";
import { myAppAffiliate } from "@myappaffiliate/sdk-react-native";
await myAppAffiliate.start({
apiKey: "pk_live_…",
storage: AsyncStorage, // so attribution survives an app restart
linking: Linking, // hands us your deep links — cold start included
});You never pass an API URL — the host is compiled in.
storage and linking are the two things the SDK cannot get on its own, because this
package deliberately imports neither react-native nor AsyncStorage (that is what
makes it work identically in bare RN, Expo, and Expo Go). Pass them and everything
else is automatic: with linking, the SDK subscribes to deep links itself, so you
write no getInitialURL / addEventListener glue.
2. Identify the user
Call this once you know who the user is. The id must be the same string your
billing provider reports back to us — RevenueCat's logIn(...) id, Adapty's
customer user id, Superwall's app user id, or your Stripe/Paddle metadata value. See
Billing & Webhooks.
await myAppAffiliate.identify(user.id);That's the whole integration. There is no third step — in particular, you do not
need to set an affiliate_id subscriber attribute anywhere; attribution joins on the
user id.
Optional
Creator codes — a "Got a code?" field. Works with no deep-link setup at all:
await myAppAffiliate.applyCode("LUMI");Handle links yourself instead of passing linking:
await myAppAffiliate.attribute(url); // claim_token | ct | via | ref | codeRead the attribution for your own UI or analytics:
const affiliateId = await myAppAffiliate.attributedAffiliateId(); // string | nullStaging or self-hosted API, and debug logging:
await myAppAffiliate.start({
apiKey: "pk_live_…",
storage: AsyncStorage,
apiBaseUrl: "https://staging.example.com",
debug: true,
});On logout or a data-erasure request: await myAppAffiliate.reset();
What start does for you
- Generates and persists a device id.
- Claims the deep link the app was launched with, and every one that arrives later.
- Retries a referral an earlier launch captured but failed to send.
All calls resolve to false/null on failure — never a thrown error in your render
path.
Expo
Works in the managed workflow — the SDK is pure JS, and AsyncStorage has an Expo
build (npx expo install @react-native-async-storage/async-storage). For deep links,
pass expo-linking as linking; it exposes the same getInitialURL and
addEventListener("url", …) shape.
Universal/App Links need a dev build or EAS (associated domains can't be tested in Expo Go); the creator-code path works everywhere, Expo Go included.
API
| Call | Purpose |
|---|---|
myAppAffiliate.start({ apiKey, storage, linking }) | Start once at startup |
myAppAffiliate.identify(userId) | Bind your user id to the attribution |
myAppAffiliate.attribute(url) | Claim a referral from a link |
myAppAffiliate.applyCode(code) | Creator-code entry |
myAppAffiliate.attributedAffiliateId() | The attributed affiliate id (or null) |
myAppAffiliate.reset() | Clear all persisted SDK state |
Every function is also a named export (import { start, identify } from …) if you
prefer that to the namespace.