> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appstack.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native API reference

Every public export of the `react-native-appstack-sdk` package. For installation
and integration guidance, see the [React Native SDK guide](/SDKs/react-native).

Current stable release: **3.5.0**, published 16 September 2026. See the [changelog](/changelog/react-native) for everything that changed.

## AppstackSDK

The default export is a ready-made singleton, so import it directly. Every method
returns a promise.

```typescript theme={null}
import AppstackSDK, { EventType } from 'react-native-appstack-sdk';
```

<Note>
  A promise resolving does not mean the event reached Appstack. It means the call
  reached native. The native SDKs still drop events when disabled, offline, or
  buffering.
</Note>

### configure()

```typescript theme={null}
configure(apiKey: string, options?: AppstackConfigureOptions | null): Promise<boolean>
```

Starts the SDK. Call once, as early in app startup as possible. A repeat call is a
no-op, and its `customerUserId` is ignored, so it cannot change the ID later.
Use [`setCustomerUserId()`](#setcustomeruserid) for that.

<ParamField path="apiKey" type="string" required>
  Your app's Appstack API key, from the dashboard under app settings.
</ParamField>

<ParamField path="options" type="AppstackConfigureOptions | null" default="null">
  Optional `logLevel` and `customerUserId`. See
  [AppstackConfigureOptions](#appstackconfigureoptions).
</ParamField>

<ResponseField name="returns" type="Promise<boolean>">
  Resolves once configuration succeeds.
</ResponseField>

```typescript theme={null}
// Minimum
await AppstackSDK.configure('your_api_key');

// With options
await AppstackSDK.configure('your_api_key', {
  logLevel: 1,                  // 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR
  customerUserId: 'user_123',
});
```

### setCustomerUserId()

```typescript theme={null}
setCustomerUserId(customerUserId?: string | null): Promise<void>
```

Sets your identifier for the signed-in user, after `configure()`.

<ParamField path="customerUserId" type="string" required>
  Your identifier for the signed-in user. Set it as soon as it is known, and at
  least one event has to follow for it to take effect.
</ParamField>

<ResponseField name="returns" type="Promise<void>">
  Resolves once native has stored the ID.
</ResponseField>

```typescript theme={null}
await AppstackSDK.setCustomerUserId('user_123');  // once login reveals it
```

### sendEvent()

```typescript theme={null}
sendEvent(event: EventType | string, parameters?: AppstackEventParameters | null): Promise<void>
```

Sends a standard or custom event.

<ParamField path="event" type="EventType | string" required>
  A standard [EventType](#eventtype), whose string name also works
  case-insensitively, or any other string to send a custom event by that name.
</ParamField>

<ParamField path="parameters" type="AppstackEventParameters | null" default="null">
  Event properties. Keys valued `null` or `undefined` are stripped before the call
  reaches native, so both platforms observe the same map. For revenue events send
  `revenue` and `currency`. Matching parameters (`email`, `name`, `phone_number`,
  `date_of_birth`, `gender`) are encrypted before being used for attribution
  matching — on device on iOS 17+ and Android, and server-side on iOS 15–16. Names
  that must stay readable, such as `currency` and `revenue`, are excluded. See
  [enhanced app campaigns](/enhanced-app-campaigns).
</ParamField>

<ResponseField name="returns" type="Promise<void>">
  Resolves once the call reaches native. See the note above: this is not delivery
  confirmation.
</ResponseField>

```typescript theme={null}
// Standard event
await AppstackSDK.sendEvent(EventType.LOGIN);

// Revenue event
await AppstackSDK.sendEvent(EventType.PURCHASE, {
  revenue: 29.99,
  currency: 'USD',
});

// Custom event, pass any string as the name
await AppstackSDK.sendEvent('onboarding_finished', { variant: 'b' });
```

<Warning>
  `EventType.INSTALL` is dropped by the wrapper before it reaches native. The SDK
  tracks installs itself; sending it by hand would double-count.
</Warning>

### getAppstackId()

```typescript theme={null}
getAppstackId(): Promise<string>
```

Returns the stable local Appstack identity for this install.

<ResponseField name="returns" type="Promise<string>">
  The install's Appstack ID.
</ResponseField>

```typescript theme={null}
const appstackId = await AppstackSDK.getAppstackId();
```

### isSdkDisabled()

```typescript theme={null}
isSdkDisabled(): Promise<boolean>
```

Whether the SDK is currently disabled and sending nothing.

<ResponseField name="returns" type="Promise<boolean>">
  `true` when the SDK is disabled.
</ResponseField>

### getAttributionParams()

```typescript theme={null}
getAttributionParams(): Promise<Record<string, any>>
```

Waits for the initial attribution match to finish, then resolves with the
parameters. The match runs at most once per install, at configure time. Prefer this
over a fixed delay after startup.

<ResponseField name="returns" type="Promise<Record<string, any>>">
  Attribution parameters, always carrying the reserved `appstack_match_status` key.
</ResponseField>

| `appstack_match_status` | Meaning                                                                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `matched`               | The install is attributed and parameters are present.                                                                                        |
| `matched_no_params`     | A click matched, but the link carried no recognised tracking parameters.                                                                     |
| `organic`               | Confirmed no attribution.                                                                                                                    |
| `skipped`               | No match was attempted for this launch. Terminal for the life of the install.                                                                |
| `failed`                | Attempted but unresolved (offline, timeout, or a server error). Retried in-session and next launch, so re-read rather than assuming organic. |
| `not_configured`        | Read before `configure()` completed, or the SDK is disabled.                                                                                 |

```typescript theme={null}
const params = await AppstackSDK.getAttributionParams();
if (params.appstack_match_status === 'matched') {
  // …
}
```

### handleUniversalLink()

```typescript theme={null}
handleUniversalLink(url: string, options?: AppstackLinkOptions | null): Promise<AppstackLinkResult | null>
```

Parses an Appstack standard Universal Link or App Link delivered by React Native's
`Linking` API. No network round trip, because the URL carries everything.

<ParamField path="url" type="string" required>
  The tapped link, as handed to you by `Linking.getInitialURL()` or the `Linking`
  `'url'` event.
</ParamField>

<ParamField path="options" type="AppstackLinkOptions | null" default="null">
  Optional host filtering. See [AppstackLinkOptions](#appstacklinkoptions).
</ParamField>

<ResponseField name="returns" type="Promise<AppstackLinkResult | null>">
  The parsed link, or `null` when the URL is not a recognised Appstack link.
</ResponseField>

```typescript theme={null}
import { Linking } from 'react-native';

useEffect(() => {
  const handle = async (url: string) => {
    const link = await AppstackSDK.handleUniversalLink(url);
    if (link) navigate(link.deeplinkId, link.queryParams);
  };

  Linking.getInitialURL().then((url) => url && handle(url));
  const sub = Linking.addEventListener('url', ({ url }) => handle(url));
  return () => sub.remove();
}, []);
```

### enableAppleAdsAttribution()

```typescript theme={null}
enableAppleAdsAttribution(): Promise<boolean>
```

Starts Apple Search Ads attribution. iOS 15.0+ only; a no-op on Android. Call it
after the App Tracking Transparency prompt resolves.

<ResponseField name="returns" type="Promise<boolean>">
  Resolves once configuration succeeds.
</ResponseField>

```typescript theme={null}
import { Platform } from 'react-native';

if (Platform.OS === 'ios') {
  await AppstackSDK.enableAppleAdsAttribution();
}
```

### deleteUserData()

```typescript theme={null}
deleteUserData(): Promise<void>
```

Permanently deletes this install's Appstack data, for GDPR and privacy requests.

<ResponseField name="returns" type="Promise<void>">
  Resolves when deletion completes.
</ResponseField>

### AppstackSDK.getInstance()

```typescript theme={null}
static getInstance(): AppstackSDK
```

Returns the singleton. The default export is already that instance, so you rarely
need this. It exists for advanced use where the class itself is imported.

```typescript theme={null}
import { AppstackSDK } from 'react-native-appstack-sdk';

const sdk = AppstackSDK.getInstance();
```

## Types

### AppstackConfigureOptions

```typescript theme={null}
export interface AppstackConfigureOptions {
  logLevel?: number;
  customerUserId?: string | null;
}
```

<ResponseField name="logLevel" type="number" default="1">
  Console verbosity, descending: `0` DEBUG, `1` INFO, `2` WARN, `3` ERROR. iOS has
  no dedicated WARN tier, so `2` folds to the same level as `3` there.
</ResponseField>

<ResponseField name="customerUserId" type="string | null">
  Your identifier for the signed-in user, when known at startup.
</ResponseField>

<Note>
  This numbering is the inverse of the native Swift `LogLevel` enum, where `0` is
  `.off` and higher means more verbose. The wrapper translates, so use the JS
  numbering above in React Native and ignore the native values.
</Note>

### AppstackLinkOptions

```typescript theme={null}
export interface AppstackLinkOptions {
  allowedHosts?: readonly string[];
}
```

<ResponseField name="allowedHosts" type="readonly string[]">
  Exact branded hostnames to accept. When omitted, any non-shared branded host is
  accepted. Passing an empty array throws, because it matches no host and would turn
  every link into `null`. Omit the option instead.
</ResponseField>

### AppstackLinkResult

```typescript theme={null}
export interface AppstackLinkResult {
  deeplinkId: string;
  queryParams: Record<string, string>;
  url: string;
}
```

<ResponseField name="deeplinkId" type="string">
  The Appstack deep link ID.
</ResponseField>

<ResponseField name="queryParams" type="Record<string, string>">
  Query parameters parsed off the tapped URL.
</ResponseField>

<ResponseField name="url" type="string">
  The URL that was handled.
</ResponseField>

### EventType

```typescript theme={null}
export declare enum EventType
```

Standard attribution events. Values follow the SNAKE\_CASE convention used by mobile
measurement partners, and the value sent over the wire is the name itself, so
`EventType.ADD_TO_CART` is `"ADD_TO_CART"`. Where two names are synonymous, both are
provided for compatibility with existing integrations.

| Group        | Cases                                                                                         |
| ------------ | --------------------------------------------------------------------------------------------- |
| Lifecycle    | `INSTALL`                                                                                     |
| Auth         | `LOGIN`, `SIGN_UP`, `REGISTER`                                                                |
| Monetization | `PURCHASE`, `ADD_TO_CART`, `ADD_TO_WISHLIST`, `INITIATE_CHECKOUT`, `START_TRIAL`, `SUBSCRIBE` |
| Games        | `LEVEL_START`, `LEVEL_COMPLETE`                                                               |
| Engagement   | `TUTORIAL_COMPLETE`, `SEARCH`, `VIEW_ITEM`, `VIEW_CONTENT`, `SHARE`                           |

There is no `CUSTOM` case. Pass any string to
[`sendEvent()`](#sendevent) to send a custom event by that name.

### AppstackEventParameters

```typescript theme={null}
export type AppstackEventParameters = Record<string, JsonValue | undefined>;
```

Parameters accepted by `sendEvent()`. Keys valued `null` or `undefined` are stripped
before the call reaches native, so both platforms observe the same map.

### JsonValue

```typescript theme={null}
export type JsonValue =
  | string
  | number
  | boolean
  | null
  | JsonValue[]
  | { [key: string]: JsonValue };
```

Any value that survives the React Native bridge intact. Event parameters are
serialised to JSON on the way to native, so anything outside this set (a `Date`, a
class instance, a function, an `undefined` nested inside an array) either arrives
mangled or is dropped silently. Typing against `JsonValue` catches that at compile
time.

### AppstackSDKInterface

```typescript theme={null}
export interface AppstackSDKInterface
```

The interface `AppstackSDK` implements. Exported so you can type a mock or a wrapper
of your own against the same surface.
