# In-app AI support for iOS and Android | Busymate AI

Source: https://busymate.ai/es/docs/guides/mobile-in-app-support
Last modified: 2026-09-04T13:24:41+03:00
Your app gets Busymate AI support by showing your assistant's chat inside a WKWebView (iOS) or a WebView (Android) with `channel=ios` or `channel=android`. Your own API vouches for signed-in customers through a small bridge, so they are recognized. If your app runs a proxy or VPN, keep the chat host out of it. There is no SDK binary — two source files you copy.

## 1. Load the hosted chat

1. The app loads the hosted chat: `https://<your-host>/?channel=ios` (or `channel=android`). Your own address is the entry point; the platform keeps `/support/<slug>` as a fallback.
2. The page asks the native side for identity through a small bridge. A signed-in customer gets an identified session; a signed-out one is anonymous.
3. External links open outside the WebView; the chat stays inside your app.

**Loading the bare address is not enough.** A WebView that opens `https://<your-host>/` with no
`channel` and no bridge gets an anonymous session on every open, for every customer — the page has
nobody to ask. Your customers then see an assistant that cannot read their account, however
thoroughly they are signed in to your app. Pin the channel and install the bridge in the same
change; identity is what makes the assistant theirs.

## 2. Bridge on iOS

Load the URL in a `WKWebView` and add a script message handler named `BusymateAI`. The page posts `busymate.ai.v1.identity_request`; you answer with `busymate.ai.v1.identity` carrying `{ token, nonce }`. `busymate.ai.v1.open_url` asks you to open a link in Safari; `busymate.ai.v1.close` asks you to dismiss the sheet. The reference source is served at `/sdk/v1/ios/BusymateAI.swift`.

{{snippet:ios-bridge}}

## 3. Bridge on Android

Load the URL in a `WebView`, enable JavaScript, and register the bridge as `BusymateAINative`. Same message types, same identity answer. The reference source is served at `/sdk/v1/android/BusymateAI.kt`.

{{snippet:android-bridge}}

## 4. Mint identity

- The token is a short-lived sign-in proof (an ES256 launch token) your API mints for the signed-in customer — see [Recognize signed-in customers](https://busymate.ai/es/docs/guides/identified-visitors).
- It lives at most 120 seconds and carries a one-time nonce and `jti`. Mint a fresh pair for every request; never cache one.
- The signing key stays on your server. The app calls your authenticated API; it never holds a key.
- Signed out: answer with no identity. The session stays anonymous, with guest access if you allow it.

## 5. Signed out, or not wired yet

Anonymous is a supported state, not a broken one — with guest access on, the assistant answers
product questions for anyone. What it will NOT do in your app is send your customer to a web login
page: inside an app, sign-in is handed to the chat by the app, so there is no page for them to use.
It says plainly that this chat has not been given their account yet and that the app has to pass
their sign-in through, then helps with everything that does not need an account. The in-chat
**Sign in** control appears only where it can finish — a browser, an iframe embed, or an app that
installed the bridge — so your customers are never pointed at a control that goes nowhere.

## 6. Match your app

The hosted chat follows the device's light or dark setting and the customer's language. The name, colors and welcome copy come from your workspace branding, so the sheet reads as part of your app.

## 7. Keep it out of your proxy

Exclude your own process — or at least the chat host — from the tunnel. Otherwise the WebView's traffic loops through your own capture and the sheet stalls.

## Real example

Our own DevTools iOS and Android apps show their own workspace this way: a Support tab, a WebView, the bridge above, identity minted by the DevTools API for signed-in customers. It is **Rolling out** through TestFlight and the internal Play track — [follow the changelog](https://busymate.ai/changelog). The integration is written up as a public page: [DevTools integration](https://busymate.ai/artifact/bmdev-integration).

## Verify

On a device, not a simulator:

1. Signed out, open Support. Guest chat answers.
2. Sign in and reopen. The greeting identifies the customer; history is theirs.
3. Tap an external link. It opens in the system browser.
4. Log out. The next identity request returns nothing; the session is anonymous again.
5. Write "talk to a human". The request reaches the Inbox.

<!-- qa:start -->
### Do I need a native SDK?
No. A WebView plus the bridge source file for your platform. Both files are served from the platform and versioned under `/sdk/v1/`.

### Where does the identity token come from?
From your own API, for your own signed-in customer. The app never holds a signing key; it forwards what your API minted.

### Does the chat match my app's look?
Branding is your workspace's — name, colors, welcome copy. Light and dark follow the device.

### Can I ship this before identity is wired?
Yes. Without a bridge answer the chat runs anonymously. Add identity when your API is ready; the page starts asking for it on the next open.
<!-- qa:end -->

## Next

- **[Recognize signed-in customers](https://busymate.ai/es/docs/guides/identified-visitors)** — mint the sign-in proof your bridge returns.
- **[Embed an AI copilot in your SaaS](https://busymate.ai/es/solutions/in-product-copilot)** — the same identity on web, iOS, Android and desktop.
- **[White-label SDK](https://busymate.ai/es/developers#ios)** — the full iOS and Android reference.
