Documentation
SDK integration guides and ad platform recipes, same content as each app's Docs tab.
React Native SDK
Track events, resolve deep links, and identify users in React Native and Expo apps.
Requirements
| Platform | Minimum Version |
|---|---|
| iOS | 13.0+ |
| Android | 5.0+ (API 21) |
| React Native | 0.72+ |
| Expo SDK | 49+ (development build) |
| Node.js | 16+ |
Both Old Architecture (Bridge) and New Architecture (TurboModules) are supported.
Installation : Expo
Use a development build for full native signal fidelity. Expo Go can use the JS fallback with reduced native signals.
npx expo install @appcat/react-native-sdk
npx expo prebuild
npx expo run:ios
npx expo run:androidTo update native modules after upgrading:
npx expo prebuild --clean
npx expo run:ios # or run:androidInstallation : Bare React Native
npm install @appcat/react-native-sdk
cd ios && pod installThen rebuild:
npx react-native run-ios
npx react-native run-androidAndroid autolinking handles native setup. iOS CocoaPods dependencies resolve automatically via the bundled podspec.
Initialization
Call once at app startup before any other SDK method.
import AppCat from '@appcat/react-native-sdk';
await AppCat.init({
appId: 'your-app-id',
apiKey: 'YOUR_API_KEY',
});App.tsx or a bootstrap function).API Keys
Every request the SDK makes is authenticated with an API key. You can have as many keys as you need, one per environment (production, staging, CI, local) is the recommended pattern so you can revoke a single environment without rotating everyone.
Generate a key
- Open your app in the AppCat dashboard and expand the SDK Guides section in the sidebar.
- Click API Key Management.
- Click New API key, give it a descriptive name (e.g.
Production iOS), and copy the value shown in the reveal modal.
The raw key is shown exactly once. Store it in your secrets manager or CI environment immediately, it cannot be retrieved later. Every app is auto-provisioned with a Default key the first time you land on API Key Management, so you always have a usable key to bootstrap from.
Multiple keys
All keys for an app point at the same project and have the same permissions. The SDK does not care which key you use; the dashboard only tracks last used at to help you identify which key is active in each environment.
Rotating a key
- Generate a new key and deploy it to the target environment.
- Once traffic is flowing on the new key, revoke the old one from the dashboard.
Revoking a key
Click Revoke next to a key and type DELETE API into the confirmation field. Revocation is immediate, the cache invalidates within a few seconds and subsequent SDK requests using that key receive a 401 INVALID_API_KEY.
Every app must always have at least one active key. The dashboard blocks revocation of the last remaining active key so you cannot accidentally lock your app out.
Security notes
- Only the last 4 characters of a key are ever shown after creation.
- Keys are stored hashed, even AppCat staff cannot recover a lost key.
- Treat API keys like passwords: never commit them to source control, never log them, and rotate if they leak.
Event Tracking
Track standard or custom events. Never throws.
// Standard event
AppCat.sendEvent('ViewContent', { page: 'home' });
// Revenue event
AppCat.sendEvent('Purchase', {
item: 'premium',
value: 9.99,
currency: 'USD',
});
// Custom event
AppCat.sendEvent('LevelComplete', { level: 5, score: 2400 });Deferred Deep Links
init() returns the deep link params from the matched ad click URL. Use this to route users to the right screen on first open — there is no separate resolve() call.
const { deepLinkParams } = await AppCat.init({
appId: process.env.EXPO_PUBLIC_APPCAT_APP_ID,
apiKey: process.env.EXPO_PUBLIC_APPCAT_API_KEY,
});
// e.g. { screen: 'Promo', promoCode: 'SUMMER25' }
if (deepLinkParams) {
navigation.navigate(deepLinkParams.screen, {
promoCode: deepLinkParams.promoCode,
});
}User Identification
Call after login or signup to link attribution data to a user.
const profile = await AppCat.identify({
userId: 'user_123',
email: 'user@example.com',
name: 'Jane Smith',
});Utility Methods
const deviceId = await AppCat.getAppCatId();
const attribution = await AppCat.getAttribution();
const context = await AppCat.getDeviceContext();
if (AppCat.isInitialized()) {
AppCat.sendEvent('ViewContent');
}API Reference
AppCat.init(config)
| Parameter | Type | Required | Description |
|---|---|---|---|
| appId | string | No | Application ID, resolved from API key if omitted |
| apiKey | string | Yes | API key |
| isDebug | boolean | No | Enable debug logging |
| logLevel | LogLevel | No | DEBUG, INFO, WARN, ERROR |
| customerUserId | string | No | User ID for session |
AppCat.sendEvent(name, params?)
| Parameter | Type | Required | Description |
|---|---|---|---|
| eventName | string | Yes | Event name |
| params | Record<string, unknown> | No | Custom data plus reserved keys: eventId, value, currency, testEventCode |
InitResponse (returned from AppCat.init)
| Field | Type | Description |
|---|---|---|
| deepLinkParams | Record<string, string> | null | Query params from the matched ad click URL, or null if no match. |
| geo | { city, country, state } | null | Geo resolved from device IP, or null. |
AppCat.identify(data)
Accepts userId, email, phone, name, geo, customAttributes. Returns Promise<IdentifyResponse | null>.
AppCat.setTrackingConsent(granted)
Records the user's tracking-consent choice after ATT, GDPR, or an in-app privacy setting. Returns Promise<void>.
Available Event Types
| Event Name | Description |
|---|---|
| MobileAppInstall | App installed |
| ViewContent | User viewed content |
| AddToCart | Item added to cart |
| InitiateCheckout | Checkout started |
| StartTrial | Free trial started |
| Subscribe | Subscription started |
| Purchase | Purchase completed |
| CompleteRegistration | Registration completed |
| Search | Search performed |
Custom event names are also supported.