Skip to main content
The Tappd Mobile SDK exposes a small, focused surface of methods that cover every use case — from identifying users and tracking events to managing push tokens and displaying in-app messages. This page documents every method, its parameters, return types, and example usage.

Constructor

new TappdSDK(config)

Create a new SDK instance. You typically do this once — at your app root or inside a context provider — and share it throughout your application. Signature: new TappdSDK(config: TappdConfig)
import TappdSDK from '@tappd/mobile-sdk';

const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  debug: __DEV__
});
See the TypeScript Types section below for the full TappdConfig interface.

Core Methods

identify(attributes)

Identify or update a customer using one or more identifiers. When you call identify(), the SDK automatically merges any events or sessions that were tracked anonymously before identification. The SDK generates its own internal identifier; you never need to manage one yourself. Signature: tappd.identify(attributes: CustomerAttributes): Promise<void> TypeScript interface:
interface CustomerAttributes {
  external_id?: string;
  email?: string;
  phone?: string;
  alias?: { type: string; value: string; };
  name?: string;
  attributes?: { [key: string]: any; };
  [key: string]: any;
}
You must include at least one identifier — external_id, email, phone, or alias — in the attributes object. The call will fail if none are provided.
Identification methods: Identifier behaviour:
IdentifierNotes
external_idYour database user ID — used as the primary identifier. Generates an internal userId automatically.
emailAuto-normalized (lowercased and trimmed). Can be the sole identifier.
phoneCan be the sole identifier.
aliasUseful for legacy or custom identification schemes. Custom alias types are stored as 'custom'.
Lookup priority: When the SDK searches for an existing customer it tries external_idemailphonealias. How identification works:
1

Provide at least one identifier

Pass external_id, email, phone, or alias inside attributes.
2

Customer matching

The SDK finds an existing customer record or creates a new one.
3

Event association

All future track() calls are automatically associated with this user.
4

Session linking

All current and future sessions are linked to the identified user.
5

Anonymous data merge

Any events tracked before identify() are merged into the customer profile.

track(eventName, properties?)

Track a custom event with optional properties. After you call identify(), the SDK automatically associates every subsequent track() call with the identified user — you don’t need to repeat identifier fields. You can, however, pass identifiers explicitly in properties if you need to associate an event with a specific user without a prior identify() call. Signature: tappd.track(eventName: string, properties?: EventProperties): Promise<void> EventProperties interface:
interface EventProperties {
  userId?: string;        // Internal user ID from identify response
  user_id?: string;       // Alternative field name
  external_id?: string;   // External user identifier
  externalId?: string;    // Alternative camelCase field name
  email?: string;
  phone?: string;
  alias?: {
    type: string;
    value: string;
  };
  sessionId?: string;     // Link event to a specific session
  [key: string]: any;     // Any additional event properties
}
Event tracking examples:
await tappd.identify({
  external_id: 'user_123',
  email: 'john@example.com'
});

// No identifier needed — SDK associates this automatically
await tappd.track('purchase', {
  amount: 99.99,
  currency: 'USD',
  productId: 'prod_123'
});
Event lookup priority: userId / user_idexternal_id / externalIdemailphonealias.

trackScreen(screenName, properties?)

Track a screen view, equivalent to a page view in web analytics. Signature: tappd.trackScreen(screenName: string, properties?: EventProperties): Promise<void>
await tappd.trackScreen('HomeScreen', {
  category: 'main',
  section: 'dashboard'
});
Use useFocusEffect from React Navigation instead of useEffect to ensure screen views fire every time a screen comes into focus, not just on mount.

setExternalId(externalId)

Set the external ID for the currently identified user. Signature: tappd.setExternalId(externalId: string): Promise<void>
await tappd.setExternalId('ext_user_123');
Throws an error if no user has been identified yet. Always call identify() first.

setUserAttributes(attributes)

Update attributes for the currently identified user. Pass any fields from CustomerAttributes to overwrite existing values. Signature: tappd.setUserAttributes(attributes: CustomerAttributes): Promise<void>
await tappd.setUserAttributes({
  plan: 'enterprise',
  lastLogin: new Date().toISOString(),
  status: 'active'
});
Throws an error if no user has been identified yet.

setCustomAttributes(attributes)

Set free-form custom attributes on the currently identified user. Signature: tappd.setCustomAttributes(attributes: Record<string, any>): Promise<void>
await tappd.setCustomAttributes({
  preferences: {
    theme: 'dark',
    language: 'en'
  },
  customField: 'value'
});
Throws an error if no user has been identified yet.

Push Notification Methods

registerPushToken(token, platform)

Register a Firebase Cloud Messaging (FCM) push token for the current user so they can receive push notifications. Signature: tappd.registerPushToken(token: string, platform: 'ios' | 'android'): Promise<void>
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';

const token = await messaging().getToken();
await tappd.registerPushToken(
  token,
  Platform.OS === 'ios' ? 'ios' : 'android'
);
Throws an error if the user is not identified. Call identify() before registerPushToken().

checkPushSubscription()

Check the push notification subscription status for the current user. Signature: tappd.checkPushSubscription(): Promise<{ subscribed: boolean; status: string; deviceCount: number }>
subscribed
boolean
Whether the user has an active push subscription.
status
string
One of 'subscribed', 'opted_in', or 'unsubscribed'.
deviceCount
number
Number of registered devices for this user.
const status = await tappd.checkPushSubscription();
console.log('Subscribed:', status.subscribed);
console.log('Status:', status.status);
console.log('Device Count:', status.deviceCount);
Throws an error if the user is not identified.

trackPushOpen(remoteMessage)

Track a push notification tap event. Call this inside your notification-opened handler to record that the user opened the app from a push notification. Signature: tappd.trackPushOpen(remoteMessage: object): Promise<void>
messaging().onNotificationOpenedApp(async (remoteMessage) => {
  await tappd.trackPushOpen(remoteMessage);
});

// Also handle cold-start opens (app launched from a notification)
const initialMessage = await messaging().getInitialNotification();
if (initialMessage) {
  await tappd.trackPushOpen(initialMessage);
}

Utility Methods

getSessionId()

Return the current session ID. Signature: tappd.getSessionId(): string | null
const sessionId = tappd.getSessionId();
console.log('Session ID:', sessionId);
// e.g., sess_abc123def456

getAnonymousId()

Return the anonymous ID assigned before the user is identified. This value persists across app launches (via AsyncStorage) until the user is identified. Signature: tappd.getAnonymousId(): string
const anonymousId = tappd.getAnonymousId();
console.log('Anonymous ID:', anonymousId);
// e.g., anon_xyz789ghi012

reset()

Clear all user data and start a new anonymous session. Call this on user logout so subsequent events are not attributed to the previous user. Signature: tappd.reset(): void
function handleLogout() {
  tappd.reset();
  // User is now anonymous again
}

cleanup()

Flush final events, remove listeners, and cleanly shut down the SDK. Call this when your app moves to the background or closes. Signature: tappd.cleanup(): void
import { AppState } from 'react-native';

AppState.addEventListener('change', (nextAppState) => {
  if (nextAppState === 'background') {
    tappd.cleanup();
  }
});

In-App Message Methods

setMessageRenderCallback(callback)

Register the function the SDK calls when it needs to render a message. This step is required in React Native — without it, messages are fetched but never displayed. Signature: tappd.setMessageRenderCallback(callback: (message: InAppMessage) => void): void
import { MessageRenderer } from '@tappd/mobile-sdk/src/renderers/MessageRenderer';

const [currentMessage, setCurrentMessage] = useState(null);

tappd.setMessageRenderCallback((message) => {
  setCurrentMessage(message);
});

// In your JSX:
{currentMessage && (
  <MessageRenderer
    message={currentMessage}
    onDismiss={(id) => {
      tappd.dismissMessage(id);
      setCurrentMessage(null);
    }}
  />
)}

getInAppMessages()

Fetch all pending in-app messages for the current user. Signature: tappd.getInAppMessages(): Promise<InAppMessage[]>
const messages = await tappd.getInAppMessages();
messages.forEach((message) => {
  console.log(`Type: ${message.config.messageType}`);
  console.log(`Status: ${message.status}`);
});

displayInAppMessage(message)

Display a specific message by passing the full InAppMessage object. This triggers the render callback you registered with setMessageRenderCallback(). Signature: tappd.displayInAppMessage(message: InAppMessage): Promise<void>
const messages = await tappd.getInAppMessages();
if (messages.length > 0) {
  await tappd.displayInAppMessage(messages[0]);
}

displayPendingMessages()

Fetch and display all messages that are ready to be shown in one call. Signature: tappd.displayPendingMessages(): Promise<void>
await tappd.displayPendingMessages();

dismissMessage(messageId)

Dismiss a message and automatically track the dismissal event. Signature: tappd.dismissMessage(messageId: string): Promise<void>
await tappd.dismissMessage('message_id_123');

trackMessageEvent(messageId, eventType, metadata?)

Track a custom interaction with an in-app message — for example, a button click inside the message. Signature: tappd.trackMessageEvent(messageId: string, eventType: string, metadata?: object): Promise<void>
await tappd.trackMessageEvent('message_id_123', 'clicked', {
  buttonText: 'Get Started',
  buttonLink: '/signup'
});

getBanners(selector, options?)

Fetch banners for a given placement selector. Signature: tappd.getBanners(selector: string, options?: { forceRefresh?: boolean }): Promise<Banner[]>
const banners = await tappd.getBanners('home-hero', { forceRefresh: false });

banners.display(bannerId, variantId, selector)

Display a banner variant in a named placement. Returns a displayId you use for subsequent click and dismiss calls. Signature: tappd.banners.display(bannerId: string, variantId: string, selector: string): Promise<string>
const displayId = await tappd.banners.display('banner_abc', 'variant_1', 'home-hero');

banners.click(bannerId, displayId)

Track a banner click event. Signature: tappd.banners.click(bannerId: string, displayId: string): Promise<void>
await tappd.banners.click('banner_abc', displayId);

banners.dismiss(bannerId, displayId)

Track a banner dismissal event. Signature: tappd.banners.dismiss(bannerId: string, displayId: string): Promise<void>
await tappd.banners.dismiss('banner_abc', displayId);

TypeScript Types

Use these interfaces to keep your integration fully type-safe.
interface TappdConfig {
  appId: string;                      // Required
  apiUrl?: string;                    // Optional — defaults to Tappd's hosted endpoint
  autoTrack?: boolean;                // default: true
  sessionTimeout?: number;            // default: 30 (minutes)
  enableAutoScreenTracking?: boolean; // default: true
  debug?: boolean;                    // default: false
  enableInAppMessages?: boolean;      // default: true
  autoDisplayMessages?: boolean;      // default: true
  messagePollingInterval?: number;    // default: 30 (seconds)
}
interface CustomerAttributes {
  external_id?: string;
  email?: string;
  phone?: string;
  alias?: {
    type: string;
    value: string;
  };
  name?: string;
  attributes?: {
    [key: string]: any;
  };
  [key: string]: any; // Additional flat custom attributes
}
At least one identifier (external_id, email, phone, or alias) is required. Store custom attributes either in the attributes object or as top-level properties.
interface EventProperties {
  userId?: string;
  user_id?: string;
  external_id?: string;
  externalId?: string;
  email?: string;
  phone?: string;
  alias?: {
    type: string;
    value: string;
  };
  sessionId?: string;
  [key: string]: any;
}
interface InAppMessage {
  id: string;
  status: string;
  config: {
    messageType: string;
    [key: string]: any;
  };
  [key: string]: any;
}

Error Handling

All async SDK methods return promises and can throw. Wrap every call in a try-catch block to handle failures gracefully without crashing your app.
try {
  await tappd.identify({
    external_id: 'user_123',
    email: 'john@example.com'
  });
} catch (error) {
  console.error('Identification failed:', error);
}

try {
  await tappd.track('purchase', { amount: 99.99 });
} catch (error) {
  console.error('Tracking failed:', error);
}
Common errors:
Error messageCauseFix
"App ID is required"appId is missing or emptyCopy your App ID from the Tappd dashboard
"User must be identified first"Called a method that requires identification before identify()Call identify() first
"Request failed: ..."Network or API errorCheck your apiUrl and network connectivity
"AsyncStorage error"@react-native-async-storage/async-storage not installedInstall the package and run pod install