React Native SDK

One integration for iOS + Android. Pure JS/TS over fetch — no native modules to link.

Set this up with your AI coding agent
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

Shell
npm i @myappaffiliate/sdk-react-native @react-native-async-storage/async-storage

1. Start it

TypeScript
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.

TypeScript
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:

TypeScript
await myAppAffiliate.applyCode("LUMI");

Handle links yourself instead of passing linking:

TypeScript
await myAppAffiliate.attribute(url);  // claim_token | ct | via | ref | code

Read the attribution for your own UI or analytics:

TypeScript
const affiliateId = await myAppAffiliate.attributedAffiliateId();  // string | null

Staging or self-hosted API, and debug logging:

TypeScript
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

CallPurpose
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.