The contract is tiny
The SDK keeps all of its state internal and private. Your app’s state management (Riverpod, Bloc, Provider, Redux, Zustand, Context, MobX) is never involved. There are only ever a handful of calls from your app into the SDK:init(apiKey)once at app start.identify({ externalId, email, traits })when the user logs in or changes.handlePushPayload(...)/openTicketFromPush(...)when a push fires.reset()on logout or user switch.
That’s the entire contract. Your app sends identity and push events in; reads
come back to you as live streams (Flutter), subscriptions/hooks (React
Native), or AsyncStreams (Swift), not as state you have to wire.
Headless vs prebuilt
Headless
Public methods + live reads only. You build the UI in your own design
system. This is the primary integration mode.
Prebuilt screens
Inbox, ticket detail, new ticket, and bug report, presented in a
self-owned modal. Limited theming (colors + app bar). Minutes to integrate.
Routing: the sandbox model
The prebuilt UI never touches your router (GoRouter, Navigator 2.0, React Navigation, Expo Router). Your app pushes one route (a full-screen modal), and the SDK owns a private nested navigator inside it for all internal navigation (inbox → ticket detail → compose → image viewer). Control returns to your app when the user dismisses the modal.Data model
Three objects you’ll touch:Where to go next
Authentication
Why there are no JWTs and the publishable key is safe to ship.
Identity & lifecycle
The four host events that touch the SDK: login, launch, logout, switch.