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
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 Messaging runtime inside the WebView requires iOS 15.4 or later and Android System WebView 99 or later. The react, react-native, and react-native-webview minimum versions are unchanged.
Install the React Native SDK
Install the package and its peer dependency:
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.
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.
The quickstart above does not persist session state. Without the sessionStorageAdapter prop, the SDK behaves as in earlier versions. To keep a session across an app force-quit, add the prop. It is available from version 1.2.0. It persists session state in storage that your app owns. See Session persistence.
The session state contains session tokens, so it must stay on the device that wrote it. On Android, Auto Backup and device transfer copy the adapter’s storage onto a different device. Exclude the adapter’s storage from Auto Backup and device transfer.
On iOS, AsyncStorage marks its own directory NSURLIsExcludedFromBackupKey, so it stays out of iCloud and encrypted backups. AsyncStorage still holds the session token in plaintext in the app container. Use a Keychain-backed adapter with a ThisDeviceOnly accessibility class to protect the token at rest. Keychain items survive an app uninstall, so a reinstall can restore the previous session. See Session persistence for how to wipe them on first run.
If you pass sessionStorageAdapter and an end user signs out of your app, call reset(). Otherwise the next user of the device can resume the previous user’s conversation.
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:
Control the Agent at runtime
Call actions on the component ref. Commands sent before the runtime is ready are queued, then flushed automatically.
The SDK reference covers every action, setting, and event.
Secure identity tokens
Use identityToken to start the session as a known user.
- Mint a token from your backend with
POST /v2/auth/tokens/. The token is short-lived and single-use. - Fetch the token in your app, then pass it to the view before you mount it.
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:
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.
The React Native SDK exposes an enableProgrammaticControl prop that defaults to true. The iOS and Android SDKs default it to false. At the default, sendMessage, the getConversation and getMessages reads, and the ada:message:sent / ada:message:received events all work. Set it to false to disable them.
Session lifecycle and state restoration
Keep the component mounted while you need the live session. Unmounting the component ends the session.
State restoration removes the loading state only. To persist the session itself across a force-quit, pass the sessionStorageAdapter prop. See Session persistence.
To restore the UI instantly after process recreation:
- Use
onStateCacheto persist the latest state snapshot. - Pass that snapshot as
initialStatethe 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:
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:
- Replace the npm package.
- Keep the runtime on legacy first (
webSdkdefaults to"legacy"). - Use the deprecated
AdaEmbedViewalias as a temporary bridge if that reduces churn. - Move to
AdaMessagingViewand the new prop patterns once the package upgrade is stable. - Set
webSdk="messaging"when you are ready to cut over to the Messaging runtime.
Side-by-side mapping
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 / after: imports
Smallest possible migration:
Recommended end state:
Prop differences to watch for
Some legacy patterns still work for compatibility, but they are no longer the preferred integration pattern.
Release checklist
Before shipping your integration or migration to production:
- Verify your real production handle launches successfully on both iOS and Android
- Confirm
onReadyfires - Confirm your event logging still receives SDK events
- If you use push notifications, call
setDeviceToken()inonReadyand verify registration - Test
reset()anddeleteHistory()if your app exposes those actions - If you pass
sessionStorageAdapter, verify that your sign-out flow callsreset(),deleteHistory(), orclearPersistedState() - Test background / foreground transitions and process restart behavior