iOS SDK reference
Use the iOS SDK settings, events, and actions to customize the behavior of your AI Agent. This page covers the public API of AdaWebHost in the AdaMessaging framework.
Settings
Configure AdaWebHost with input parameters at initialization. The SDK builds the WebView and its URL inside init, so all settings must be set at initialization. To change values later, use the actions.
appScheme
appScheme: String = ""
Use this setting to pass the scheme name of the host app. This allows for more robust handling of universal links.
appUrl
appUrl: String = ""
Overrides the app frame URL that the Messaging runtime mounts.
Your handle’s Allowed websites list controls custom apps. In your Ada dashboard, go to Channels > Chat and add your app’s origin. If the list does not allow the origin, the runtime drops the URL with a logged warning and mounts the default app.
The value must be an absolute https: URL. The runtime drops invalid values with a logged warning and mounts the default app instead. If the custom app fails to load or complete its handshake, the runtime falls back to the default app.
For local development against a simulator, expose your development server through an https: tunnel, and add the tunnel origin to Allowed websites. The dashboard accepts only https:// entries. On the production and pre-production environments, the WebView’s host page is an Ada asset origin, not a loopback page. The web SDK’s implicit loopback allowance therefore does not apply there.
The exception is the local asset-server environment (.local), used for SDK development. Its WebView host page is https://localhost:4900, a loopback origin, so the implicit loopback allowance applies and a loopback appUrl such as http://localhost:5173 needs no entry.
The value is delivered to the web runtime through an injected configuration object, not through the WebView URL. It applies only when webSdk is .messaging. The legacy runtime ignores it.
cluster
cluster: String = ""
Specifies the cluster your AI Agent runs on.
Set this only if your Agent is hosted on a non-default cluster (for example, us2, maple, eu).
If the Agent is on the default cluster, leave this unset.
deviceToken
deviceToken: String = ""
The APNs device token for push notifications. The SDK sends it to the runtime when the runtime becomes ready. To set or rotate the token after initialization, use setDeviceToken.
domain
domain: String = ""
The Ada domain your AI Agent is served from.
embedVersion
embedVersion: String = ""
Pins the legacy runtime’s host page to a specific embed build. Used for pre-release verification with your Ada team. Leave blank for the stable rollout. Ignored when webSdk is not .legacy.
enableProgrammaticControl
enableProgrammaticControl: Bool = false
Opts this host into the Messaging runtime’s programmatic-control API. When set to true, your app can:
- Call
sendMessage. - Receive the
ada:message:sentandada:message:receivedevents ineventCallbacks.
While the flag is false (the default), sendMessage is rejected with ProgrammaticControlNotEnabled and those events are not delivered.
With this flag on, full message bodies flow into your app code through eventCallbacks, including any PII your end users type. Do not write message bodies to logs, analytics, or crash reports. Have your product and security teams accept that exposure explicitly before turning this on.
This setting applies only when webSdk is .messaging. The legacy runtime ignores it.
environment
environment: AdaEnvironment? = nil
The deployment environment that hosts the WebView entry page and SDK assets. See AdaEnvironment. Most production apps set .production.
The Messaging runtime requires an explicit environment. If you set webSdk: .messaging but leave environment unset, the host falls back to the legacy path.
eventCallbacks
eventCallbacks: [String: (_ event: [String: Any]) -> Void]? = nil
A dictionary of callbacks keyed by event name. See Events for the delivery contract and the list of event keys.
greeting
greeting: String = ""
Use this setting to customize the greeting messages that new end users see. This is useful for setting view-specific greetings across your app. The greeting should correspond to the ID of the Answer you would like to use, which you can find in the URL of the corresponding Answer in the dashboard.
Example

This setting is only applicable if you’re using a scripted AI Agent.
handle
handle: String
The handle for your AI Agent. This is a required field.
headless
headless: Bool = false
When set to true, the Messaging runtime connects to your AI Agent without rendering its default chat UI. Use this when your app renders its own conversation UI with native components and drives the conversation through sendMessage and eventCallbacks.
Headless hosts are typically paired with enableProgrammaticControl: true. Without it, the methods and events needed to drive a custom UI are rejected at runtime.
headless suppresses only the runtime’s UI. To run the WebView without presenting it, launch with launchHeadlessWebSupport. That action forces this setting to true, and rebuilds the WebView when the host was created without it, so set headless: true at initialization to avoid the extra load. See Headless session lifecycle for the constraints.
Headless sessions run with no visual indicator. The runtime creates and persists session state inside the WebView the same way as a visible session. Treat enabling headless as a meaningful trust decision.
This setting applies only when webSdk is .messaging. The legacy runtime ignores it.
identityToken
identityToken: String = ""
A short-lived identity token that authenticates the end user before the session starts. Your backend mints the token with the Ada Platform API, then your app passes it here. See Authenticate end users for the setup flow.
Token handling rules:
- Tokens are single use and expire after 15 minutes. Mint a fresh token for each new
AdaWebHost. - The SDK delivers the token to the web runtime through a one-time injected configuration object at document start. The token never appears in a URL, so it stays out of request logs.
- The SDK holds the token in memory only. It is never persisted to disk.
- The SDK remembers when the runtime has consumed the token. If the host rebuilds or reloads its WebView, the spent token is not delivered again. Create a new host with a newly minted token to re-authenticate.
- Exchange failures surface as the
ada:identity_token:errorandada:identity_token:expiredevents.
Never log the identity token. Never store it in UserDefaults, files, or analytics payloads.
This setting applies only when webSdk is .messaging. The legacy runtime ignores it.
language
language: String = ""
Takes in a language code to programmatically set the AI Agent language. You must first turn languages on in your Ada dashboard. Go to Customization > Languages. See Support multiple languages in the same AI Agent for more information.
Language codes use the ISO 639-1 language format.
metafields
metafields: [String: Any] = [:]
Use metafields to pass information about a user to Ada at initialization. This can be useful for tracking information about your customers, as well as personalizing their experience.
To change these values after initialization, use the setMetaFields action.
navigationBarOpaqueBackground
navigationBarOpaqueBackground: Bool = false
When set to true, the modal presentation uses a full-screen style with an opaque, light-gray navigation bar and status bar. Applies to launchModalWebSupport only.
openWebLinksInSafari
openWebLinksInSafari: Bool = false
External web links open by default in-app, via SFSafariViewController. To open external links in the Safari browser, pass openWebLinksInSafari: true.
preprodDemoToken
preprodDemoToken: String = ""
A time-bound access token for Messaging pre-production assets. Applied only when environment is .preprod and webSdk is .messaging. Used for pre-release testing with your Ada team; leave blank otherwise.
sensitiveMetafields
sensitiveMetafields: [String: Any] = [:]
Use this parameter to pass sensitive meta information about an end user. This works like metafields but provides an added layer of security. To change these values after initialization, use the setSensitiveMetaFields action.
styles
styles: String = ""
Passes style overrides to the web runtime. The value’s meaning depends on webSdk:
.legacy: a CSS style override string..messaging: a JSON object of string style tokens, for example"{\"tintColor\": \"#520497\"}". The runtime honorstintColoronly today, and ignores unsupported keys. A value that is not a JSON object of string values is dropped with a debug log.
version
version: String = ""
Pins the legacy runtime’s chat bundle to a specific build. Used for pre-release verification with your Ada team. Leave blank for the stable rollout. Ignored when webSdk is not .legacy.
webSdk
webSdk: AdaWebSdk = .legacy
Selects which web runtime the WebView mounts. See AdaWebSdk.
.legacy(the default) keeps the runtime the previousAdaEmbedFrameworkSDK loaded, so migrating apps see no behavior change..messagingmounts the Messaging runtime.headless,identityToken,enableProgrammaticControl, andsendMessagerequire it.
Set an explicit environment when you select .messaging.
webViewLoadingErrorCallback
webViewLoadingErrorCallback: ((Error) -> Void)? = nil
Called when the WebView fails to load. Receives an AdaWebHostError: .webViewTimeout when loading exceeds webViewTimeout, or .webViewFailedToLoad for navigation failures.
webViewTimeout
webViewTimeout: Double = 30.0
The number of seconds the SDK waits for the WebView to load before it stops loading and calls webViewLoadingErrorCallback with .webViewTimeout.
zdChatterAuthCallback
zdChatterAuthCallback: ((@escaping (_ token: String) -> Void) -> Void)? = nil
Use the zdChatterAuthCallback to request a JWT token from your API, then pass it to Ada. This creates shared trust between Ada and Zendesk, and in turn allows for verifiable end user identity.
zdChatterAuthCallback is available only for Zendesk Chat. It is not available for Zendesk Messaging.
Session persistence
The SDK stores session state inside the WebView’s web storage. The native side caches only a small allowlist of cosmetic state, with a 10 minute expiry, to smooth the next launch.
On iOS, WebView storage persistence across app restarts is not guaranteed. Session state may or may not survive depending on OS storage management, and should not be relied upon for maintaining live agent handoff state.
The SDK never persists tokens or credentials to platform-native storage such as Keychain or UserDefaults. If your app requires guaranteed session continuity across app restarts, you need to implement your own native storage management. See the Apple developer documentation on Keychain Services.
Events
Pass an eventCallbacks dictionary at initialization to receive runtime events.
The delivery contract:
- Each callback receives one
[String: Any]dictionary. event["event_name"]is the event key as aString.event["data"]carries the event payload when the runtime sends one.- The callback registered under the exact event key fires first, then the callback registered under
"*"fires with the same event. - The
"*"callback receives every event the runtime emits, including keys not listed below.
The dictionary holds one closure per key. To register several subscribers for the same key, or to add and remove subscribers after initialization, use addEventCallback and addSdkEventCallback instead. Subscribers registered that way also receive the ada.bridge.error and ada.webview.* events under their own keys, not only under "*".
The ada:message:sent and ada:message:received events are delivered only when the host was created with enableProgrammaticControl: true.
Common event keys, in alphabetical order:
Headless session lifecycle
A headless host is an offscreen integration, not a background service. The following constraints are firm:
- No background execution. iOS suspends the WebView’s content process when the app is suspended. Events do not arrive while the app is not running. Use push notifications through
setDeviceTokenfor delivery outside the app lifecycle. - App termination ends the runtime. When the app terminates, the WebView and its in-memory state are gone. On the next launch, the session rehydrates from the runtime’s own web persistence inside the new WebView.
- Tokens are never persisted natively.
identityTokenis held in memory and consumed once by the runtime. Mint a fresh token for each new host. - One WebView per host. Each
AdaWebHostowns one WebView. Retain the host for as long as you need the session. Releasing it stops event delivery. - Keep the container out of user interaction. A hidden or zero-sized container is fine. WebKit can throttle rendering for offscreen views; command dispatch and event delivery still work.
To show the Ada UI later, create a new AdaWebHost without headless and present it with one of the launch actions. The conversation continues because the runtime persists session state in web storage.
Actions
Use the actions below in conjunction with settings to customize the behavior of your AI Agent in an iOS app. On the Messaging runtime, actions called before the runtime is ready are queued and dispatched when sdk.ready fires.
addEventCallback
addEventCallback(_ eventName: String = "*", callback: @escaping (_ event: [String: Any]) -> Void) -> AdaEventSubscription
Registers a callback for one event key, or for every event with the default "*" key. Unlike the eventCallbacks dictionary, which holds one closure per key, any number of callbacks can subscribe to the same event, and you can subscribe after initialization. Returns an AdaEventSubscription token. Pass the token to removeEventCallback to unsubscribe.
Subscribers registered this way also receive the ada.bridge.error and ada.webview.* events under their own keys.
addSdkEventCallback
addSdkEventCallback(_ callback: @escaping (_ key: String, _ data: String?) -> Void) -> AdaEventSubscription
Registers a raw sink that receives every event as its key plus its JSON-encoded data. Use it to forward events without knowing the keys in advance. Returns an AdaEventSubscription token for removeSdkEventCallback.
clearPersistedState
clearPersistedState()
Removes the natively persisted state cache: the allowlisted, non-sensitive startup and branding state in UserDefaults. Call it when an end user signs out. The next WebView session starts without rehydrated state. See Session persistence.
The call does not touch the web runtime’s own storage. To clear the conversation itself, use deleteHistory or reset.
deleteHistory
deleteHistory()
Deletes the record used to fetch conversation logs for an end user from local storage. When the user opens a new chat window, a new user record will be created.
launchHeadlessWebSupport
launchHeadlessWebSupport(in hostView: UIView? = nil)
Runs the web runtime without presenting any Ada UI. Attaches the WebView to hostView when one is supplied (keep it hidden or zero-sized), or to an internal hidden zero-sized container otherwise.
Requirements and behavior:
- Requires
webSdk: .messaging. Calling it on a legacy host stops the program with a precondition failure, matching the Android SDK’s headless factory. - Forces
headlesstotrue. When the host was created withheadless: false, the SDK rebuilds the WebView so the runtime loads in headless mode. Setheadless: trueat initialization to avoid the extra load.
Drive the conversation natively through eventCallbacks and sendMessage. See Headless session lifecycle.
launchInjectingWebSupport
launchInjectingWebSupport(into view: UIView)
Launches Ada chat into a specified subview.
launchModalWebSupport
launchModalWebSupport(from viewController: UIViewController)
Launches Ada chat in a modal view over top of your current view.
launchNavWebSupport
launchNavWebSupport(from navController: UINavigationController)
Pushes a view containing Ada chat to the top of your navigation stack.
removeEventCallback
removeEventCallback(_ subscription: AdaEventSubscription)
Removes exactly the callback that addEventCallback returned the subscription for. Unknown subscriptions are a no-op.
removeEventCallbacks
removeEventCallbacks(_ eventName: String = "*")
Removes every callback registered through addEventCallback for one event key, or for "*" by default.
removeSdkEventCallback
removeSdkEventCallback(_ subscription: AdaEventSubscription)
Removes the raw sink that addSdkEventCallback returned the subscription for.
reset
Creates a new end user and refreshes the chat, optionally with a new language, greeting, and metadata. Overloads exist with only metaFields, only sensitiveMetaFields, or neither.
resetChatHistory is tri-state: true and false are sent to the runtime explicitly, while nil omits the value so the runtime’s own default applies. The parameter defaults to true.
A reset overload that takes plain dictionaries still exists for backward compatibility but is deprecated. Use the MetaFields.Builder overloads for all new code.
sendMessage
sendMessage(_ body: String)
Sends a message from the end user into the conversation. Use this to drive the conversation from your own native UI.
Requirements and behavior:
- Requires
webSdk: .messaging. On the legacy runtime the call is dropped with a debug log. - Requires
enableProgrammaticControl: true. Without it, the runtime rejects the command withProgrammaticControlNotEnabled. - Calls made before the runtime is ready are queued and dispatched when
sdk.readyfires.
setDeviceToken
setDeviceToken(deviceToken: String)
Sets or rotates the APNs device token used for push notifications. Safe to call before the runtime is ready; the SDK delivers the latest token once the runtime signals sdk.ready.
setLanguage
setLanguage(language: String)
Changes the language in chat programmatically. Use this action, rather than the language setting, to change the chat language without clearing the chat history. Language codes must use a lowercase, two-letter code, in ISO 639-1 language format.
Before using setLanguage, you must turn languages on in your Ada dashboard. Go to Customization > Languages. See Support multiple languages in the same AI Agent for more information.
setMetaFields
setMetaFields(builder: MetaFields.Builder)
Sets metadata for an end user after initialization. This is useful if you need to update user data after Ada has already launched. See also metafields.
A setMetaFields(_:) overload that takes a plain dictionary still exists for backward compatibility but is deprecated. Use MetaFields.Builder for all new code.
setSensitiveMetaFields
setSensitiveMetaFields(builder: MetaFields.Builder)
Sets sensitive metadata for an end user after initialization. This works like setMetaFields and is useful for passing more private and sensitive information. See also sensitiveMetafields.
A setSensitiveMetaFields(_:) overload that takes a plain dictionary still exists for backward compatibility but is deprecated. Use MetaFields.Builder for all new code.
Types
AdaEnvironment
AdaEnvironment selects the deployment environment that hosts the WebView entry page and SDK assets.
AdaEventSubscription
An opaque token returned by addEventCallback and addSdkEventCallback. Keep it to remove the subscription later with removeEventCallback or removeSdkEventCallback.
AdaWebHostError
AdaWebHost.AdaWebHostError is the error type passed to webViewLoadingErrorCallback.
AdaWebSdk
AdaWebSdk selects which web runtime the WebView mounts. See webSdk.
MetaFields.Builder
MetaFields.Builder builds the metadata payload for setMetaFields, setSensitiveMetaFields, and reset. setField(key:value:) accepts String, Bool, Int, Float, and Double values and returns the builder for chaining.