Architecture
There is no native library to add to your app. Your app opens a WebView pointing at the agent’s widget URL.region, the widget uses the default region, which loads the wrong backend for an organization in any other region. An unknown region value stops the widget from loading.
The app and the widget then exchange JSON messages. Every message is an object with a type field prefixed tars:, so foreign messages are ignored.
The full field-level contract is in the bridge events reference.
How each direction travels
App to widget messages are posted into the page withwindow.postMessage, which every platform snippet does through its script injection call.
Widget to app messages take a different path. The widget sends them with window.parent.postMessage, the same call it uses inside the web embed iframe. In a top-level WebView window.parent is the page itself, so the message stays in the page. Your app must listen for message on window and relay every tars:-prefixed message to its own native channel.
Enabling the bridge
The bridge is gated per agent. Open Distribute → Mobile App on the agent and turn on Enable Bridge Events. The toggle also reveals ready-made snippets for React Native, Swift/UIKit, and Kotlin/Android, plus a bridge events reference. With the toggle on, gambit editors gain bridge event configuration.The capabilities handshake
The widget poststars:ready twice, and the two messages mean different things. The widget page posts a bare tars:ready as soon as it mounts, with no other fields. That message only says the page is loaded and listening.
The app starts the session by posting tars:init, carrying its platform, chrome preferences, and optional end user data. The bridge answers with a second tars:ready, declaring its protocol version and capabilities: navigate, data, and close. Only the first tars:init takes effect, later ones are ignored.
The widget answers only a tars:init that arrives after it mounts. An init posted before that is dropped and never answered. Post tars:init when the bare tars:ready arrives, or resend it until a tars:ready with capabilities comes back. A repeat init after the handshake is ignored, so a resend is safe.
After the handshake, the widget emits events as the conversation reaches gambits with configured bridge events, and the app can inject data or send commands at any time.
Chrome control
tars:init can hide parts of the widget chrome so the conversation sits flush inside a native screen. showHeader and showCloseButton both default to true.
