Kerabie
SDKs

Flutter SDK

Add Kerabie live chat to your iOS or Android app built with Flutter.

The kerabie_helpdesk_flutter package adds live chat to a Flutter app, with photos and files, a help centre, tickets, a store and proactive campaigns. Messages arrive in your Kerabie inbox.

Install

flutter pub add kerabie_helpdesk_flutter

It needs Flutter 3.27 or later and Dart 3.6 or later. Get your widget key from Settings, Widget in the dashboard.

On iOS, add the reason for the photo library to ios/Runner/Info.plist, so customers can attach photos:

<key>NSPhotoLibraryUsageDescription</key>
<string>Attach a photo to your message to support.</string>

Quick start

Put KerabieProvider above your MaterialApp, and add the launcher over your screens.

import 'package:flutter/material.dart';
import 'package:kerabie_helpdesk_flutter/kerabie_helpdesk_flutter.dart';

final navigatorKey = GlobalKey<NavigatorState>();

void main() {
  runApp(
    KerabieProvider(
      navigatorKey: navigatorKey,
      config: const KerabieConfig(
        widgetKey: 'wk_yourorg_123',
        appName: 'My App',
        appVersion: '1.0.0',
        user: KerabieUser(name: 'Jane', email: 'jane@example.com'),
      ),
      child: MaterialApp(
        navigatorKey: navigatorKey,
        navigatorObservers: [KerabieNavigatorObserver()],
        home: const Scaffold(
          body: Stack(children: [HomeScreen(), KerabieLauncher()]),
        ),
      ),
    ),
  );
}

KerabieLauncher shows the floating button or the search bar, whichever the dashboard picked. To open the chat from your own button, use KerabieChat.show(context).

Configuration

FieldRequiredDescription
widgetKeyYesYour widget key from Settings, Widget
appName, appVersionYesYour app's name and version, sent when the chat connects
appBuildNoBuild number, sent with them
userNoKerabieUser with id, name, email, phone, role and customAttributes
themeNoKerabieTheme overrides: primaryColor, secondaryColor, gradient, cornerRadius, mode (light, dark or auto), backgroundColor, textColor, agentBubbleColor, userBubbleColor, bubbleColor, bubbleIcon, bubbleSize, bubbleIconSize, fontFamily, chatbotAvatarUrl
chatSettingsNoKerabieChatSettings overrides for the dashboard: name, welcomeMessage, offlineMessage, showBranding, typingIndicator, enableFileAttachments, chatbotEnabled, layout, showMenu, launcherType, searchbarPlaceholder, customerEnrichmentEnabled, customerEnrichmentForm
openModeNomodal (a full-screen page, the default), sheet (a bottom sheet) or push (your own navigator opens it)
positionNoWhere the launcher sits: bottomRight (default), bottomLeft, topRight, topLeft
defaultOpenNoOpen the chat as soon as the app has built
hideFloatingButtonNoMake KerabieLauncher draw nothing; open the chat from your own button
deepLinkSchemeNoYour app's URL scheme, so only myapp://conversation/123 links open the chat

Colours, the widget name, the welcome message, the offline message and branding come from Settings, Widget in the dashboard. Anything you set in theme or chatSettings wins over the dashboard. Light or dark comes from the dashboard's Theme setting: auto follows the device, and the chat is light when nothing is set. Text on a coloured background is dark or white depending on the colour's luminance, so it stays readable on any brand colour. The welcome message can use {{name}}, which becomes the signed-in user's first name.

KerabieProvider also takes onOpenChat, onCloseChat, onNavigate and onOpenKnowledgeBase.

Open modes

With openMode: KerabieOpenMode.push the SDK does not touch your navigator. It calls onNavigate and your app shows a KerabieChatScreen in its own route:

KerabieProvider(
  config: const KerabieConfig(widgetKey: '...', appName: '...', appVersion: '...', openMode: KerabieOpenMode.push),
  onNavigate: (route) => router.push(route.type == KerabieRouteType.conversation ? '/chat/${route.conversationId}' : '/chat'),
  child: ...,
)

// In your /chat route:
KerabieChatScreen(onClose: () => router.pop())

Without onNavigate the chat opens as a full-screen page.

Reading the chat state

final kerabie = KerabieProvider.of(context); // rebuilds when the chat changes

Badge(label: Text('${kerabie.unreadCount}'), child: const Icon(Icons.support_agent));
MemberDescription
messagesThe conversation, oldest first
unreadCountReplies that arrived while the chat was closed
isConnectedWhether the live connection is up
isTyping, isAiTypingAn agent, or the AI assistant, is writing
agentsOnlineHow many agents are online, once the server has said
settings, chatWhat the dashboard saved, and the chat settings in force
sendMessage(text), retry(message)Sends a message, and sends a failed one again
showChat(), dismissChat(), toggle()Open and close the chat
setUser(user), clearUser(), updateAttribute(key, value)Who the customer is, see below
setAppVersion(version)The app's version changed; it is sent with the next connection
openWithContext(context)Opens the chat with context, see below

Who the customer is

Call setUser after login so agents see who they are talking to, updateAttribute to add a detail, and clearUser after logout. clearUser empties the chat on screen and the next visitor starts a fresh anonymous session.

final kerabie = KerabieProvider.of(context, listen: false);

await kerabie.setUser(const KerabieUser(id: 'u_123', name: 'Ada Obi', email: 'ada@example.com'));
await kerabie.updateAttribute('plan', 'pro');
await kerabie.clearUser();

Opening the chat with context

Tell the agent what the customer was looking at, so they do not have to explain it:

kerabie.openWithContext(const KerabieChatContext(
  type: 'order', // order, product, transaction, ride, errand, booking or custom
  id: 'ORD-2024-001',
  title: 'Order #2024-001',
  data: {'status': 'shipped', 'total': '45.50'},
));

Pass openChat: false to only record it and open the chat later.

Screens

KerabieNavigatorObserver tells Kerabie which screen the customer is on, from your routes' names. Campaigns can be limited to certain screens ("On pages" in the dashboard). Dialogs, sheets and routes without a name are ignored. With a router that has no route names, such as go_router, report screens yourself with kerabie.trackScreen('/checkout').

Help centre, store and tickets

Ready-made screens you can push anywhere in your app. Each follows your theme and the dashboard settings.

Navigator.of(context).push(MaterialPageRoute(builder: (_) => const KerabieKnowledgeBaseScreen()));
Navigator.of(context).push(MaterialPageRoute(builder: (_) => const KerabieStoreScreen()));
Navigator.of(context).push(MaterialPageRoute(builder: (_) => const KerabieTicketsScreen()));

kerabie.settings.ticketsEnabled says whether tickets are on in the dashboard, so you can show an entry point only when they are. For your own design use the data classes behind the screens: KerabieKnowledgeBase, KerabieStore and KerabieTickets.

Campaigns

Proactive messages you create in the dashboard (Campaigns) also appear in your app, above the launcher, with their button. They load once per app launch and need the same navigatorKey on KerabieProvider and MaterialApp.

Dashboard settingIn the app
Trigger Page loadShown about 1.5 seconds after a screen appears
Trigger Time on pageShown after N seconds in the app
Trigger Scroll depth, Exit intentWebsite only; not shown in apps
On pagesMatched against the current screen. Without a screen, only campaigns for every screen show
AudienceNew and returning mean the first and a later launch on this device; "hasn't chatted" checks this device's conversations; country is decided by the server
FrequencyRemembered on the device: once per visitor, once per day, or once per app launch
Button Open chat / Open a linkOpens the chat / the link in the browser
Button Open Knowledge BaseCalls your onOpenKnowledgeBase; opens the chat if you do not pass it

Results (shown, opened, clicked, replied) are counted in the dashboard like they are for the website widget. Nothing pops up while the chat is open.

Calls

Customers can call your team from the app: voice, and video if you turn it on. Calls are a separate, optional package, so apps that only want chat do not carry the call code.

flutter pub add kerabie_helpdesk_flutter_calls

Turn calls on in the dashboard under Settings, Calls. Your plan decides how many call minutes you get each month, and calls the AI voice agent answers are counted separately.

The app needs permission to use the microphone, and the camera for video. On iOS add NSMicrophoneUsageDescription and NSCameraUsageDescription to Info.plist. On Android add the CAMERA, RECORD_AUDIO, ACCESS_NETWORK_STATE, CHANGE_NETWORK_STATE and MODIFY_AUDIO_SETTINGS permissions to the manifest, plus BLUETOOTH and BLUETOOTH_ADMIN limited to maxSdkVersion="30". The package README has the exact lines.

import 'package:kerabie_helpdesk_flutter_calls/kerabie_helpdesk_flutter_calls.dart';

// Anywhere under KerabieProvider. It shows nothing when calls are off or the plan has no minutes left.
const KerabieCallButton(label: 'Call us'),
const KerabieCallButton(label: 'Video call', video: true),

To put call buttons in the chat header itself, pass the icon variant to the provider. It is a widget you pass in, so the main package never carries the call code:

KerabieProvider(config: ..., callActions: const KerabieCallButton.icon(), child: ...)

The button opens a call screen with the queue position, ringing, the call (mute, camera, end) and how it ended. For your own design, create a KerabieCallController and read its phase.

phaseMeaning
startingAsking Kerabie to start the call
waitingEvery agent is busy; queuePosition is the place in line
ringingFree agents are being rung
connectedAnswered by a person or the AI (handler)
endedOver; endReason says why

If you ask customers for their details before a chat (the pre-chat form in the dashboard), the call asks the same questions first, once. Pass user in KerabieConfig, or call setUser after login, and a customer you have identified is never asked. On a video call the customer sees the agent, with their own camera as a small picture in the corner.

A call goes to every free agent at once and the first to answer wins. When nobody is free, the AI voice agent answers if you turned it on. Otherwise the customer waits in the queue, and the call is marked missed after two minutes.

AI agent for your app

A voice agent inside your app that uses your tools as the signed-in customer, shows screens instead of reading lists, and hands over to your team with a summary. Read AI agent for your app for how tools, secure routes and screens work. It needs the same setup as calls: calls and the AI voice agent turned on in the dashboard, and the microphone permission.

import 'package:kerabie_helpdesk_flutter_calls/kerabie_helpdesk_flutter_calls.dart';

// Anywhere under KerabieProvider. It shows nothing when calls are off.
KerabieAgentButton(
  name: 'Kerabie Agent', // optional, shown on the button and the call screen
  getUserToken: () async => auth.currentToken, // null when nobody is signed in
  screens: {
    // Screens that need your data or your design. A list, a confirmation and an address box are built in.
    'pick_saved_address': (payload) async => pickAddress(payload['purpose']),  // the address id, or 'none' to type a new one
    'pick_schedule': (payload) async => pickDateTime(),                        // ISO 8601 date and time
    'open_screen': (payload) async { openScreen(payload['screen']); return 'opened'; },
  },
)

To let the agent do things in the app itself, such as adding to its own cart, pass actions: {'add_to_cart': KerabieAgentAction(description: ..., parameters: {...}, run: (args) async => ...)}. Each becomes a tool named action_<name>.

Each handler shows your screen and returns the customer's answer, which the agent reads back. Throw if the customer closes it. The agent only uses the screens you list. Addresses are never taken by voice. For your own design pass KerabieAgentOptions(getUserToken:, screens:) as agent: to KerabieCallController.

Push notifications

Kerabie keeps one push token per customer, so use one push service in your app. The SDK does not depend on a push package. You get the token from your service and pass it in, with the provider that issued it.

final kerabie = KerabieProvider.of(context, listen: false);
await kerabie.registerPushToken(token, provider: KerabiePushProvider.fcm);

The providers are fcm and expo, the two values the Kerabie API accepts. fcm takes the token from FirebaseMessaging.getToken(), and it also covers iOS because Firebase delivers through Apple's service for you.

Using Firebase (fcm)? Connect your Firebase project once in the dashboard under Settings, Integrations, App push, so Kerabie can send to your app's customers. Without it, replies are not pushed to your app.

Opening the chat when a notification is tapped

Kerabie notifications carry conversationId and orgId in their data. Pass the data to the SDK when the user taps. With Firebase Cloud Messaging, handle both cases FCM documents: the tap that launches the app (getInitialMessage) and the tap from the background (onMessageOpenedApp).

final messaging = FirebaseMessaging.instance;

final initial = await messaging.getInitialMessage();
if (initial != null) kerabie.handleNotificationData(initial.data);

FirebaseMessaging.onMessageOpenedApp.listen((m) => kerabie.handleNotificationData(m.data));
messaging.onTokenRefresh.listen((t) => kerabie.registerPushToken(t, provider: KerabiePushProvider.fcm));

The chat can only open from a tap if you gave KerabieProvider the same navigatorKey as your MaterialApp. With go_router, pass the same key as GoRouter(navigatorKey: navigatorKey).

Links use the same format in every Kerabie SDK: <your-scheme>://conversation/<id>.

Flutter handles incoming deep links itself, so the SDK does not listen for them. Hand the link to the SDK where your app receives it, for example in onGenerateRoute or your router's redirect.

if (kerabie.handleDeepLink(Uri.parse('myapp://conversation/123'))) return;

KerabieDeepLink.conversationUri(123, 'myapp') builds a link you can put in a notification.

Use with an AI assistant

The Kerabie MCP server can read this SDK's documentation, so a coding assistant can add it to your app.