Skip to main content
The Tappd Web SDK exposes a set of async methods that let you identify users, track events, manage sessions, render banners, display in-app messages, and handle push notifications. Every async method returns a Promise, so wrap calls in try/catch or chain .catch() to handle errors gracefully.

Constructor

new TappdSDK()

Create and initialize an SDK instance. Call this once — typically at the top level of your app — and reuse the returned instance everywhere.
new TappdSDK(config: TappdConfig)
config
TappdConfig
required
SDK configuration object. appId is the only required field.
Returns: TappdSDK instance.
import { TappdSDK } from '@tappd/web-sdk';

const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  autoTrack: true,
  debug: false
});

Core Methods

identify()

Identify or update a customer using one or more identifiers. When you call identify(), the SDK automatically merges any anonymous events tracked in the current session with the resolved customer profile.
attributes
CustomerAttributes
required
User attributes object. Must include at least one of external_id, email, phone, or alias.
Returns: Promise<void> Lookup priority: external_idemailphonealias
Use external_id whenever possible — it’s the most stable and reliable identifier. Include multiple identifiers to improve match accuracy across devices and sessions.
CustomerAttributes interface:
interface CustomerAttributes {
  external_id?: string;       // Your internal user ID (recommended)
  email?: string;             // User email — auto-normalized (lowercased, trimmed)
  phone?: string;             // User phone number
  alias?: {                   // Custom alias identifier
    type: string;             // e.g. 'session_id', 'legacy_user_id'
    value: string;
  };
  name?: string;
  attributes?: {              // Nested custom attributes object
    [key: string]: any;
  };
  [key: string]: any;         // Top-level custom attributes (flat)
}
Identification examples:
// Use your database user ID as the primary identifier
await tappd.identify({
  external_id: 'user_123',
  name: 'Jane Smith',
  email: 'jane@example.com',
  phone: '+1234567890',
  plan: 'premium',
  company: 'Acme Corp'
});
How identification works:
1

Find or create customer

The SDK searches for an existing customer using the lookup priority order. If no match is found, it creates a new profile.
2

Associate events

All future track() calls are automatically linked to this customer — no need to pass identifiers again.
3

Merge anonymous data

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

Link sessions

The current session and all future sessions are attached to the identified user.

track()

Track a custom event with an optional properties payload. If the user is already identified, the SDK automatically associates the event — you don’t need to repeat identifiers in the properties.
track(eventName: string, properties?: EventProperties): Promise<void>
eventName
string
required
The name of the event to track (e.g. 'purchase', 'button_clicked').
properties
EventProperties
Optional event properties. Can include identifiers to associate the event with a specific customer.
Returns: Promise<void> Identifier lookup order in properties: userId/user_idexternal_id/externalIdemailphonealias
// Once identified, all events are linked automatically
await tappd.identify({
  external_id: 'user_123',
  email: 'jane@example.com'
});

await tappd.track('purchase', {
  amount: 99.99,
  currency: 'USD',
  productId: 'prod_123',
  productName: 'Pro Plan'
});

trackPageView()

Manually track a page view. If you set autoTrack: true during initialization, the SDK handles this automatically on every navigation. Use this method when you need finer control — for example, in custom SPA routers.
trackPageView(url?: string, properties?: EventProperties): Promise<void>
url
string
The URL to record. Defaults to window.location.href if omitted.
properties
EventProperties
Optional additional properties to attach to the page view event.
Returns: Promise<void>
// Records window.location.href automatically
await tappd.trackPageView();

setExternalId()

Set or update the external_id for the currently identified user. The user must already be identified — call identify() first.
setExternalId(externalId: string): Promise<void>
externalId
string
required
Your internal user identifier.
Returns: Promise<void> Throws: Error"User must be identified first" if identify() has not been called.
await tappd.setExternalId('ext_user_123');

setUserAttributes()

Update attributes for the currently identified user. The user must already be identified.
setUserAttributes(attributes: CustomerAttributes): Promise<void>
attributes
CustomerAttributes
required
Attributes to update on the customer profile.
Returns: Promise<void> Throws: Error"User must be identified first"
await tappd.setUserAttributes({
  plan: 'enterprise',
  lastLogin: new Date().toISOString(),
  status: 'active'
});

setCustomAttributes()

Set or overwrite custom attributes on the currently identified user’s profile.
setCustomAttributes(attributes: Record<string, any>): Promise<void>
attributes
Record<string, any>
required
Key-value map of custom attributes to apply.
Returns: Promise<void> Throws: Error"User must be identified first"
await tappd.setCustomAttributes({
  preferences: {
    theme: 'dark',
    language: 'en'
  },
  betaFeatures: true
});

Utility Methods

getSessionId()

Return the active session ID. Sessions are created automatically on initialization and resume when a hidden tab becomes visible again.
getSessionId(): string | null
Returns: string | null — the current session ID, or null if no session is active.
const sessionId = tappd.getSessionId();
console.log('Session ID:', sessionId);
// e.g. sess_abc123def456

getAnonymousId()

Return the anonymous ID for the current browser context. This ID persists in localStorage across page loads and sessions until identify() is called.
getAnonymousId(): string
Returns: string — the anonymous ID.
const anonymousId = tappd.getAnonymousId();
console.log('Anonymous ID:', anonymousId);
// e.g. anon_xyz789ghi012

reset()

Clear all user data and start a fresh session. Call this on logout to prevent the next user on the same device from inheriting the previous session’s identity.
reset(): void
Returns: void
function handleLogout() {
  tappd.reset();
  // The SDK is now anonymous — ready for the next user
}

Banners

getBanners()

Fetch banners targeted to the current user for a given CSS selector. By default the SDK renders the returned banners automatically into the matched element.
getBanners(
  selector: string,
  options?: { autoRender?: boolean; forceRefresh?: boolean }
): Promise<Banner[]>
selector
string
required
A CSS selector string that identifies the DOM element(s) where banners should be rendered (e.g. '#hero-banner', '.promo-slot').
options
object
Optional rendering options.
  • autoRender — automatically inject the banner HTML into the matched element. Defaults to true.
  • forceRefresh — bypass the local cache and fetch fresh banners from the API. Defaults to false.
Returns: Promise<Banner[]>
// Fetch and auto-render banners into #hero-banner
const banners = await tappd.getBanners('#hero-banner');

// Fetch without auto-rendering so you can handle HTML yourself
const banners = await tappd.getBanners('.promo-slot', { autoRender: false });
banners.forEach(banner => {
  document.querySelector('.promo-slot').innerHTML = banner.html;
});

// Force a fresh fetch, ignoring any cached results
const banners = await tappd.getBanners('#sidebar-banner', { forceRefresh: true });

banners.display()

Manually record a banner display impression and return a unique display ID. Use this when autoRender is false and you render the banner HTML yourself.
tappd.banners.display(
  bannerId: string,
  variantId: string,
  selector: string
): Promise<string>
bannerId
string
required
The ID of the banner to record a display for.
variantId
string
required
The ID of the specific banner variant being shown.
selector
string
required
The CSS selector of the container element where the banner is displayed.
Returns: Promise<string> — a unique display ID used for subsequent click and dismiss calls.
const displayId = await tappd.banners.display('banner_123', 'variant_abc', '#hero-banner');
console.log('Display recorded:', displayId);

banners.click()

Track a click interaction on a displayed banner. Call this when the user clicks on the banner or a CTA within it.
tappd.banners.click(bannerId: string, displayId: string): Promise<void>
bannerId
string
required
The ID of the banner that was clicked.
displayId
string
required
The display ID returned by banners.display().
Returns: Promise<void>
bannerElement.addEventListener('click', async () => {
  await tappd.banners.click('banner_123', displayId);
});

banners.dismiss()

Record that the user dismissed a banner. Call this when the user closes or hides the banner without clicking through.
tappd.banners.dismiss(bannerId: string, displayId: string): Promise<void>
bannerId
string
required
The ID of the banner being dismissed.
displayId
string
required
The display ID returned by banners.display().
Returns: Promise<void>
closeButton.addEventListener('click', async () => {
  await tappd.banners.dismiss('banner_123', displayId);
});

In-App Messages

getInAppMessages()

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

displayInAppMessage()

Display a specific in-app message object.
displayInAppMessage(message: InAppMessage): Promise<void>
message
InAppMessage
required
The message object returned by getInAppMessages().
Returns: Promise<void>
const messages = await tappd.getInAppMessages();
if (messages.length > 0) {
  await tappd.displayInAppMessage(messages[0]);
}

displayPendingMessages()

Fetch and display all messages that are currently ready to show. Use this as a shortcut instead of calling getInAppMessages() and displayInAppMessage() separately.
displayPendingMessages(): Promise<void>
Returns: Promise<void>
await tappd.displayPendingMessages();

dismissMessage()

Dismiss a specific message and record the dismissal event in the Tappd dashboard.
dismissMessage(messageId: string): Promise<void>
messageId
string
required
The ID of the message to dismiss.
Returns: Promise<void>
await tappd.dismissMessage('msg_abc123');

trackMessageEvent()

Track a custom interaction event for a specific in-app message — for example, a button click or a custom CTA action.
trackMessageEvent(
  messageId: string,
  eventType: string,
  metadata?: object
): Promise<void>
messageId
string
required
The ID of the message.
eventType
string
required
Event type string — e.g. 'viewed', 'clicked', 'dismissed'.
metadata
object
Optional metadata to attach to the event.
Returns: Promise<void>
await tappd.trackMessageEvent('msg_abc123', 'clicked', {
  buttonText: 'Get Started',
  buttonLink: '/signup'
});

Push Notifications

getVapidPublicKey()

Retrieve the VAPID public key required for setting up web push subscriptions manually.
getVapidPublicKey(): Promise<string>
Returns: Promise<string> — the VAPID public key.
const publicKey = await tappd.getVapidPublicKey();
console.log('VAPID Public Key:', publicKey);

isSubscribed()

Check whether the current user is already subscribed to push notifications.
isSubscribed(): Promise<boolean>
Returns: Promise<boolean>true if subscribed, false otherwise.
const subscribed = await tappd.isSubscribed();
if (subscribed) {
  console.log('User is subscribed to push notifications.');
} else {
  console.log('User is not yet subscribed.');
}

subscribeToPush()

Subscribe the currently identified user to push notifications. You must call identify() before subscribing.
subscribeToPush(options?: PushSubscriptionOptions): Promise<PushSubscription>
options
PushSubscriptionOptions
Optional subscription configuration passed to the browser’s Push API.
Returns: Promise<PushSubscription> Throws: Error if:
  • Push notifications are not supported in the current browser
  • The user has denied notification permission
  • identify() has not been called
// Always identify the user before subscribing
await tappd.identify({
  external_id: 'user_123',
  email: 'jane@example.com'
});

try {
  const subscription = await tappd.subscribeToPush();
  console.log('Subscribed:', subscription.endpoint);
} catch (error) {
  console.error('Subscription failed:', error.message);
}

unsubscribeFromPush()

Remove the current user’s push notification subscription.
unsubscribeFromPush(): Promise<void>
Returns: Promise<void>
try {
  await tappd.unsubscribeFromPush();
  console.log('Successfully unsubscribed.');
} catch (error) {
  console.error('Unsubscribe failed:', error.message);
}

showPermissionPrompt()

Display a push notification permission prompt. Choose the style that best fits your UI.
showPermissionPrompt(type: 'slidedown' | 'bell' | 'native'): Promise<void>
type
'slidedown' | 'bell' | 'native'
required
The prompt style to display. Use 'native' for the browser’s built-in dialog, 'slidedown' for a banner, or 'bell' for an icon-triggered prompt.
Returns: Promise<void>
After showing the prompt, call subscribeToPush() when the user grants permission to complete the subscription flow.
// Show a slidedown banner
await tappd.showPermissionPrompt('slidedown');

// Or use the native browser dialog
await tappd.showPermissionPrompt('native');

hidePermissionPrompt()

Programmatically hide any active permission prompt.
hidePermissionPrompt(): Promise<void>
Returns: Promise<void>
await tappd.hidePermissionPrompt();

TypeScript Types

Use these interfaces to get full type safety throughout your project.

TappdConfig

interface TappdConfig {
  appId: string;                    // Required — your Tappd app identifier
  apiUrl?: string;                  // Optional — custom API endpoint
  autoTrack?: boolean;              // Optional — default: true
  sessionTimeout?: number;          // Optional — minutes, default: 30
  enableAutoCapture?: boolean;      // Optional — default: false
  debug?: boolean;                  // Optional — default: false
  enableInAppMessages?: boolean;    // Optional — default: true
  autoDisplayMessages?: boolean;    // Optional — default: true
  messagePollingInterval?: number;  // Optional — seconds, default: 30
  messageContainerId?: string;      // Optional — custom DOM container ID
}

CustomerAttributes

interface CustomerAttributes {
  external_id?: string;   // Your internal user ID (recommended)
  email?: string;         // Auto-normalized (lowercased, trimmed)
  phone?: string;
  alias?: {
    type: string;         // e.g. 'session_id', 'legacy_user_id'
    value: string;
  };
  name?: string;
  attributes?: {          // Nested custom attributes
    [key: string]: any;
  };
  [key: string]: any;     // Top-level custom attributes (flat)
}

EventProperties

interface EventProperties {
  userId?: string;        // Internal user ID from identify response
  user_id?: string;       // Alternative (snake_case)
  external_id?: string;   // External user identifier
  externalId?: string;    // Alternative (camelCase)
  email?: string;
  phone?: string;
  alias?: {
    type: string;
    value: string;
  };
  sessionId?: string;     // Links the event to a specific session
  [key: string]: any;     // Any additional event properties
}

Error Handling

All async methods can throw. Always wrap calls in try/catch to handle errors without breaking your application.
try {
  await tappd.identify({
    external_id: 'user_123',
    email: 'jane@example.com'
  });
} catch (error) {
  console.error('Identification failed:', error.message);
}

try {
  await tappd.track('purchase', { amount: 99.99, currency: 'USD' });
} catch (error) {
  console.error('Event tracking failed:', error.message);
}
Common error messages:
Error MessageCauseFix
"App ID is required"appId is missing or empty in the configProvide a valid appId from your Tappd dashboard
"User must be identified first"Called a method that requires identification before identify()Call identify() with at least one valid identifier first
"Request failed: ..."Network failure or API errorCheck your apiUrl, network connection, and CORS configuration