Skip to main content

Flutter SDK

See how easy it is to integrate high-performance ads into your Flutter app using our lightweight SDK.

Requirements

Getting started

WebView prerequisites (flutter_inappwebview)

This SDK renders ads inside a WebView using flutter_inappwebview. To avoid initialization issues, add this to your app entry point:
import 'package:flutter/widgets.dart';

void main() {
  // Must be first so plugins are ready.
  WidgetsFlutterBinding.ensureInitialized();

  runApp(const MyApp());
}

1. Installation

To get started, you will need to set up a publisher account to get a publisherToken and code
Add the package to your pubspec.yaml:
dependencies:
  kontext_flutter_sdk: ^<latest_version>
Then install:
flutter pub get
Make sure your project meets the Android min/compile SDK and iOS/Xcode requirements listed above. If you run into other issues, verify your project meets the plugin’s platform requirements: https://inappwebview.dev/docs/intro/

2. Set up the Character object

First, provide information about the assistant’s character:
final character = Character(
  id: 'id-123', 
  name: 'Ava', 
  avatarUrl: 'https://example.com/avatar.png', 
  isNsfw: false, 
  greeting: 'Hi there! How can I help you today?', 
  persona: 'Friendly and supportive virtual assistant who enjoys chatting about technology, travel, and fitness.', 
  tags: ['friendly', 'helpful', 'tech-savvy'], 
);

3. Set up the Regulatory object

Next, provide information about regulations:
final regulatory = Regulatory(
  gdpr: 1, // 1 = subject to GDPR
  gdprConsent: 'CPXxRfAPXxRfAAHABBENC5CsAP_AAH_AAAwIHNX9fb2vj-_59__t0eY1f9_7_v-f7z3e7_-___w2BgiA',
  coppa: 0, // 0 = not subject to COPPA
  gpp: 'DBABTA~CPXxRfAPXxRfAAHABBENC5CsAP_AAH_AAAwIHNX9f',
  gppSid: [2, 7], // sections of GPP string applied
  usPrivacy: '1YNN', // CCPA string example
);

4. Set up AdsProvider

Wrap your app (or the subtree that contains ad placements) with AdsProvider.
AdsProvider fetches ads and needs access to the current chat messages.
import 'package:kontext_flutter_sdk/kontext_flutter_sdk.dart';

// Messages between user and assistant
final messages = [
  Message(
    id: "msg-001",
    role: MessageRole.assistant,
    content: "Hello! How can I help you today?",
    createdAt: DateTime.parse("2025-08-31T10:00:00Z"),
  ),
  Message(
    id: "msg-002",
    role: MessageRole.user,
    content: "Show me today's workout plan.",
    createdAt: DateTime.parse("2025-08-31T10:00:05Z"),
  ),
  Message(
    id: "msg-003",
    role: MessageRole.assistant,
    content: "Here's a 30-minute routine to start with.",
    createdAt: DateTime.parse("2025-08-31T10:00:10Z"),
  ),
];

Widget build(BuildContext context) {
  return AdsProvider(
    publisherToken: 'your-publisher-token',
    userId: 'user-1234',                 // Stable per user (for retargeting / rewards)
    conversationId: 'conv-5678',         // Unique per conversation
    enabledPlacementCodes: ['inlineAd'], // Example placement code(s)
    messages: messages,
    character: character,                // From section 1
    regulatory: regulatory,              // From section 2
    advertisingId: '<IDFA-or-GAID>',     // IDFA (iOS) / GAID (Android)
    vendorId: '<IDFV>',                  // iOS vendor identifier
    variantId: 'ab-test-v1',
    otherParams: {
      'theme': 'dark',
    },
    child: YourChatWidget(),
  );
}

5. Display your first ad

An ad slot is a place in your UI where an ad is rendered. In most cases, this will be under a chat message. During onboarding, you receive a code for each ad slot or ad format you want to show. Example using the InlineAd format:
ListView.builder(
  itemCount: messages.length,
  itemBuilder: (context, index) {
    final message = messages[index];
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(message.content),
        InlineAd(
          code: 'your_code',
          messageId: message.id,
        ),
      ],
    );
  },
)
💡 Note: InlineAd does not always display an ad - whether an ad is shown depends on the context of the ongoing conversation. If there is no ad to display, InlineAd automatically returns a const SizedBox.shrink(), so it won’t take up any extra space in your layout.

API documentation

AdsProvider properties

publisherToken
String
required
Your unique publisher token.
messages
List<Message>
required
List of messages between the assistant and the user.
userId
String
required
Unique identifier that remains the same for the user’s lifetime (used for retargeting and rewarded ads).
conversationId
String
required
Unique ID of the conversation.
enabledPlacementCodes
List<String>
required
Placement codes enabled for the conversation. Example: ['inlineAd'].
character
Character
The character object used in a conversation.
regulatory
Regulatory
Regulatory compliance information.
advertisingId
String
Device-specific identifier (IDFA on iOS, GAID on Android).
vendorId
String
Vendor identifier (IDFV on iOS).
variantId
String
Publisher-provided identifier for the user cohort (for A/B testing).
iosAppStoreId
String
iOS App Store ID for the app, used for better ad matching and reporting.
logLevel
enum
The log level for the SDK: LogLevel.debug, LogLevel.info, LogLevel.log, LogLevel.warn, LogLevel.error, or LogLevel.silent.
otherParams
Map<String, dynamic>
Used to pass publisher-specific information to Kontext. Contents will be discussed with your account manager if needed.
isDisabled
bool
Flag indicating if the ads are disabled.
adServerUrl
String
The URL of the ad server. Defaults to the default ad server URL if not provided.
onEvent
void Function(AdEvent event)
Callback triggered when an event occurs.

InlineAd properties

code
String
required
The ad format code that identifies the ad to be displayed.
messageId
String
required
A unique identifier for the message associated with this ad.

AdEvent types

ad.clicked

The user has clicked the ad.

ad.viewed

The user has viewed the ad.

ad.filled

Ad is available.

ad.no-fill

Ad is not available.

ad.render-started

Triggered before the first token is received.

ad.render-completed

Triggered after the last token is received.

ad.error

Triggered when an error occurs.

reward.granted

Triggered when the user receives a reward.

video.started

Triggered when the video playback starts.

video.completed

Triggered when the video playback finishes.

Guides

  • Place AdsProvider high enough in the widget tree to cover all screens/areas that can show ads.
  • Keep the messages list up to date so the SDK can determine when and where to render ads.

Controlling when ads load

You can fine-tune ad frequency by controlling when new messages are passed into AdsProvider. This allows you to adjust the ratio of ads to messages dynamically.

Handling no-fill events

You can notify when the ad is not available by using the onEvent callback and listening for the ad.no-fill event.

Troubleshooting

Missing plugin warnings

If you see warnings like MissingPluginException or errors about a plugin not being registered, try the following:
flutter clean
flutter pub get
This clears cached build artifacts and ensures plugins are re-registered. If the problem persists, try rebuilding your app flutter run or restarting your IDE.

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.
I