# Mobile apps (iOS, Android, React Native)

> Use PostHog's open-source mobile SDK and point it at Sequential with your PostHog ingest key and API URL. Events and session replay both arrive.

Sequential has no mobile SDK of its own. It serves the protocol PostHog’s mobile SDKs speak. The key is the project’s **PostHog** ingest key, the same one the web SDK uses. If the app already uses PostHog, change `apiKey` and `host` in its existing setup call and add the replay options. Do not add a second setup call.

## iOS (Swift)

Add the `posthog-ios` package (Swift Package Manager or CocoaPods), then set it up once at launch:

```swift
import PostHog

let config = PostHogConfig(apiKey: "YOUR_POSTHOG_INGEST_KEY", host: "https://api.usesequential.com")
config.sessionReplay = true
config.sessionReplayConfig.screenshotMode = true // required for SwiftUI screens
PostHogSDK.shared.setup(config)
```

- **SwiftUI: name your screens.** Automatic screen capture reports the same hosting-controller class for every SwiftUI screen, so add `.postHogScreenView("Checkout")` to each screen, or call `PostHogSDK.shared.screen("Checkout")`.
- **Masking happens on the device.** Text inputs and images are masked by default. In screenshot mode every SwiftUI `Text` is masked. Opt a view out with `.postHogNoMask()` only where that is safe. Mask custom secure views (a PIN pad, for example) yourself. The project’s masking settings in Sequential do not apply to mobile.

## Android (Kotlin)

Add the `com.posthog:posthog-android` dependency, then set it up in `Application.onCreate()`:

```kotlin
import com.posthog.android.PostHogAndroid
import com.posthog.android.PostHogAndroidConfig

val config = PostHogAndroidConfig(apiKey = "YOUR_POSTHOG_INGEST_KEY", host = "https://api.usesequential.com")
config.sessionReplay = true
config.sessionReplayConfig.screenshot = true // required for Jetpack Compose screens
PostHogAndroid.setup(this, config) // in Application.onCreate()
```

**Android session replay is not tested with a real app yet.** Sequential accepts and plays the recordings of PostHog’s Android SDK, but we have not run it with a real Android app. iOS replay is tested with a real app on the iOS simulator.

## React Native

Add `posthog-react-native` and wrap the app. **React Native (and Flutter, via `posthog_flutter`) are accepted but not yet verified** against Sequential. Check the Setup page after installing.

```tsx
import { PostHogProvider } from 'posthog-react-native';

<PostHogProvider
  apiKey="YOUR_POSTHOG_INGEST_KEY"
  options={{ host: "https://api.usesequential.com", enableSessionReplay: true }}
>
  {/* your app */}
</PostHogProvider>
```

## What is supported

Recording is switched on per platform in Sequential (Settings → Projects → Session replay), along with sampling and minimum duration. The SDK caches that config and picks up a change on its next launch with network. Revoking the PostHog key stops events and replay on the next launch.

What Sequential does with PostHog (mobile) traffic:

| Capability | Support | Notes |
|---|---|---|
| Custom events | Yes | Same wire protocol as web (`/batch`, gzipped). |
| Page / screen views | Yes | `$screen` events. |
| Autocaptured clicks & forms | Partial | Whatever the SDK's own autocapture sends as `$autocapture` is classified; mobile autocapture varies by platform. |
| Identify (user id) | Yes | Top-level `distinct_id`. |
| User properties | Partial | As on web: kept on the event, not stored as user properties. |
| Groups / accounts | No | As on web. |
| Errors | Partial | Manually captured `$exception` events only. |
| Session replay | Yes | PostHog's mobile session replay (iOS, Android) is stored as sent and played in Sequential. iOS replay is tested with a real app on the iOS simulator. Android replay is not tested with a real app yet. Masking is set in the SDK on the device. React Native and Flutter are accepted but unverified. |
| DevTools: errors, console, network, performance | Partial | No JavaScript errors or page performance. Console logs only when the project records message text and the app sets iOS `captureLogs` (Android logcat is on by default). Network timing: iOS URLSession by default, Android needs `PostHogOkHttpInterceptor`. Flutter: none. See [Mobile apps](/docs/mobile). |
| Feature flags, surveys, experiments | No | As on web. |
| Server-side SDKs | No | Browser and PostHog mobile SDKs only. Server-side SDK user agents are rejected as bots (403). |

## Enable DevTools on mobile (optional)

The replay’s DevTools drawer can show a mobile app’s console logs and network timing. Both need a setting in the app that the setup above deliberately leaves out. **Add them only if the user asks for them.**

- **Logs**: Sequential asks the app for logs only when the project turns on *Record message text* (Settings → Projects → your project → Session replay → DevTools). On iOS the app must also opt in:

```swift
config.sessionReplayConfig.captureLogs = true // optional: console logs for DevTools
```

Android sends logcat by default. The mobile SDK always sends message text; Sequential keeps it only because that setting is on.
- **Network**: timing, status and size per request, following the project’s *Network requests* switch. iOS records URLSession requests by default. Android needs PostHog’s interceptor on the OkHttp client:

```kotlin
import com.posthog.android.PostHogOkHttpInterceptor

// optional: network timing for DevTools, on the OkHttp client your app already builds
val client = OkHttpClient.Builder()
  .addInterceptor(PostHogOkHttpInterceptor())
  .build()
```

Mobile network rows are metrics only: method, URL with query values redacted, status, duration and size. PostHog’s SDKs never send headers or bodies. JavaScript errors and page performance are web only. React Native: `captureLog` (on by default) maps to iOS `captureLogs`, and network telemetry is iOS only. Flutter sends neither.

Only PostHog’s mobile SDKs are supported on mobile. Mixpanel and Amplitude native SDKs are not supported, and neither are Smartlook’s. Server-side SDKs are rejected.

## Check it works

1. Build and run the app on a device or simulator and move through a few screens.
2. In Sequential, Settings → Projects → Setup shows PostHog as receiving within about a minute of the first event. The first recording appears under Sessions once the app has been in the foreground for the minimum duration, and up to about 6 minutes later.
3. Nothing arriving: check the key is the PostHog one and `host` has no trailing path. Recording starts only when the app is active with no system alert on top.
