Getting started

The Ada React Native SDK embeds your Ada AI Agent in a React Native app through react-native-webview. This guide takes you from installation to a working integration, including identity tokens and headless mode.

You need an active Ada handle to use the SDK. To gain access, reach out to an Ada Account Manager.

This guide covers the new Ada React Native SDK (@ada-cx/messaging-react-native). If you are migrating from the existing SDK (@ada-support/react-native-sdk), see Upgrade from the existing React Native SDK below.

Compatibility

RequirementMinimum version
react18.0.0
react-native0.73.0
react-native-webview13.0.0

The SDK does not ship a native module of its own. It builds on react-native-webview, so complete that package’s standard native installation for your app first. Your minimum iOS and Android OS versions follow the versions your app and react-native-webview support. The SDK adds no separate deployment-target requirement.

Install the React Native SDK

Install the package and its peer dependency:

$npm install @ada-cx/messaging-react-native react-native-webview

If your app does not already include compatible react and react-native versions, upgrade those first. No Podfile changes are required for the Ada package. Run pod install only if adding react-native-webview for the first time.

Launch Ada

Import the AdaMessagingView component and render it. You must pass a valid handle for the Agent to load.

TSX
1import { useRef } from "react";
2import {
3 AdaMessagingView,
4 type AdaMessagingViewHandle,
5} from "@ada-cx/messaging-react-native";
6
7export function SupportScreen() {
8 const adaRef = useRef<AdaMessagingViewHandle>(null);
9
10 return (
11 <AdaMessagingView
12 ref={adaRef}
13 handle="my-company"
14 webSdk="messaging"
15 language="en"
16 metaFields={{ plan: "pro", signedIn: true }}
17 onReady={() => {
18 adaRef.current?.setSensitiveMetaFields({
19 authToken: "secure-session-token",
20 });
21 }}
22 onEvent={(key, data) => {
23 console.log("[Ada]", key, data);
24 }}
25 style={{ flex: 1 }}
26 />
27 );
28}

The webSdk prop defaults to "legacy" so that package upgrades do not change end-user behavior before you intentionally cut over. Set webSdk="messaging" explicitly to run the Messaging runtime. The identity token and headless features below require the Messaging runtime.

Most apps only need handle. Leave cluster unset unless Ada tells you your AI Agent is hosted on a non-default production region. If it is, pass the exact cluster value that Ada gives you:

TSX
1<AdaMessagingView handle="my-company" webSdk="messaging" cluster="maple" />

Control the Agent at runtime

Call actions on the component ref. Commands sent before the runtime is ready are queued, then flushed automatically.

TSX
1adaRef.current?.sendMessage("Where is my order?");
2adaRef.current?.setLanguage("fr");
3adaRef.current?.setMetaFields({ tier: "gold" });
4adaRef.current?.reset();

The SDK reference covers every action, setting, and event.

Secure identity tokens

Use identityToken to start the session as a known user.

  1. Mint a token from your backend with POST /v2/auth/tokens/. The token is short-lived and single-use.
  2. Fetch the token in your app, then pass it to the view before you mount it.
TSX
1const token = await fetchAdaIdentityToken(); // your backend call
2
3<AdaMessagingView handle="my-company" webSdk="messaging" identityToken={token} />

The SDK injects the token into the WebView document before content loads. The token never appears in a URL. The runtime reads it once per document load and then deletes it. A token set after mount only applies when the WebView reloads.

Fetch a fresh token before each mount. Because tokens are single-use, a remount needs a newly minted token.

Headless mode

Set headless to run the Ada runtime without its chat UI. The WebView stays mounted, but it is hidden and non-interactive. onEvent, onStateCache, and every imperative handle method keep working. Use them to build a fully native experience, such as an unread badge driven by message events:

TSX
1const adaRef = useRef<AdaMessagingViewHandle>(null);
2const [unread, setUnread] = useState(0);
3
4<AdaMessagingView
5 ref={adaRef}
6 handle="my-company"
7 webSdk="messaging"
8 headless
9 onEvent={(key) => {
10 if (key === "ada:message:received") {
11 setUnread((count) => count + 1); // drive your own red-dot badge
12 }
13 }}
14/>
15
16// Later, from your own composer UI:
17adaRef.current?.sendMessage("Where is my order?");

The ada:message:sent and ada:message:received events include full message bodies, including any personal information end users type. Do not forward these payloads to analytics or logging tools unless your product and security teams have accepted that exposure.

Headless sessions run with no visual indicator, and a session starts as soon as the view mounts. Mount a headless view only when you intend to start or resume a session.

Headless requires the Messaging runtime (webSdk="messaging"). The remote legacy host page ignores it.

Unlike the iOS and Android SDKs, the React Native SDK has no enableProgrammaticControl setting. Programmatic control is always on for the Messaging runtime, so sendMessage and the message events work without any opt-in.

Session lifecycle and state restoration

Keep the component mounted while you need the live session. Unmounting the component ends the session.

To restore the UI instantly after process recreation:

  1. Use onStateCache to persist the latest state snapshot.
  2. Pass that snapshot as initialState the next time the view mounts.

This removes the loading spinner on WebView restart flows.

Your app owns this persistence, and the SDK writes nothing to disk itself. Before onStateCache runs, the SDK reduces every snapshot to an allowlist of non-sensitive keys and stamps it with __ada_cached_at__. Session credentials and conversation content never reach your callback, so the delivered snapshot is safe to persist as is. On the next mount, the SDK filters initialState again and discards snapshots whose __ada_cached_at__ stamp is older than 10 minutes.

The package exports the pieces of this contract: PERSISTABLE_STATE_KEYS (the allowlist), STATE_CACHE_TTL_MS (the expiry), and toPersistableStateSnapshot() (the filter itself). See State persistence exports.

Snapshots persisted by earlier package versions were unfiltered, and can contain session credentials. Run stored snapshots through toPersistableStateSnapshot() once before you pass them as initialState, and overwrite the stored copy with the filtered result.

Upload and media permissions

If your Agent flow lets end users upload files or capture media, include the platform permissions that react-native-webview and the device features require.

For iOS, add usage descriptions to ios/[project]/Info.plist:

KeyWhen required
NSCameraUsageDescriptionCamera capture uploads
NSPhotoLibraryUsageDescriptionPhoto library uploads
NSMicrophoneUsageDescriptionVideo capture with audio

For Android, add any permissions your upload or capture flow requires in AndroidManifest.xml.

Upgrade from the existing React Native SDK

If you are migrating from @ada-support/react-native-sdk, the new package is designed as a low-friction replacement. The recommended path is:

  1. Replace the npm package.
  2. Keep the runtime on legacy first (webSdk defaults to "legacy").
  3. Use the deprecated AdaEmbedView alias as a temporary bridge if that reduces churn.
  4. Move to AdaMessagingView and the new prop patterns once the package upgrade is stable.
  5. Set webSdk="messaging" when you are ready to cut over to the Messaging runtime.

Side-by-side mapping

ExistingMessaging SDK
@ada-support/react-native-sdk@ada-cx/messaging-react-native
AdaEmbedViewAdaMessagingView (a deprecated AdaEmbedView alias is also exported)
require_relative '../node_modules/@ada-support/react-native-sdk/react_native_pods' in PodfileRemove it
use_ada!() in PodfileRemove it

The new package relies on the standard React Native and react-native-webview native setup only. Remove any Ada-specific Podfile helpers from the old package.

Before / after: package

$# Before
$npm install @ada-support/react-native-sdk
$
$# After
$npm install @ada-cx/messaging-react-native

Before / after: imports

Smallest possible migration:

TSX
1import { AdaEmbedView } from "@ada-cx/messaging-react-native";

Recommended end state:

TSX
1import { AdaMessagingView } from "@ada-cx/messaging-react-native";

Prop differences to watch for

Some legacy patterns still work for compatibility, but they are no longer the preferred integration pattern.

Legacy prop / patternStatus in the new packageRecommended approach
deviceToken propSupported but deprecatedCall ref.setDeviceToken() in onReady
endConversationCallbackSupported but deprecatedUse onEvent and check for the ada:end_conversation key
eventCallbacksSupported but deprecatedUse onEvent
sensitiveMetaFields propSupported but deprecatedCall ref.setSensitiveMetaFields() in onReady
stylesSupportedPass a theme-token object on the Messaging runtime, or a CSS string on the legacy runtime. See styles
thirdPartyCookiesEnabledSupported but deprecated; Android onlyNormally omit it
zdChatterAuthCallbackSupportedKeep using it when you need Zendesk chat auth

Release checklist

Before shipping your integration or migration to production:

  • Verify your real production handle launches successfully on both iOS and Android
  • Confirm onReady fires
  • Confirm your event logging still receives SDK events
  • If you use push notifications, call setDeviceToken() in onReady and verify registration
  • Test reset() and deleteHistory() if your app exposes those actions
  • Test background / foreground transitions and process restart behavior