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)

The Flutter SDK renders ads inside a WebView using flutter_inappwebview. To prevent WebView initialization errors, 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>
Install dependencies:
flutter pub get
Ensure your project meets the Android min/compile SDK and iOS/Xcode requirements listed above. If you run into issues, verify that your project meets the plugin’s platform requirements: https://inappwebview.dev/docs/intro/

2. Set up the Character object

Define the assistant’s character information:
final character = Character(
  id: 'id-123',
  name: 'Ava',
  avatarUrl: 'https://example.com/avatar.png',
  greeting: 'Hi there! How can I help you today?'
);

3. Set up the Regulatory object

Next, define the user’s regulatory context:
final regulatory = Regulatory(
  gdpr: 1, 
  // ... other regulatory properties
);

4. Set up the AdsProvider

Wrap your app (or the part of it that contains ad placements) with the AdsProvider. The AdsProvider is responsible for fetching and managing ads, and it requires 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',                 
    conversationId: 'conv-5678', 
    enabledPlacementCodes: ['inlineAd'],
    messages: messages,
    character: character, // From section 1
    regulatory: regulatory, // From section 2
    advertisingId: '<IDFA-or-GAID>',
    vendorId: '<IDFV>',
    otherParams: {
      'theme': 'dark',
    },
    child: YourChatWidget(),
  );
}

5. Display your first ad

An ad slot is a designated area in your UI where an ad can be rendered. In most cases, it appears below a chat message. During onboarding, you’ll receive a unique code for each ad slot you plan to use. 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 no ad is available, 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).
userEmail
String
Email of the user.
conversationId
String
required
Unique ID of the conversation.
enabledPlacementCodes
List<String>
required
Placement codes enabled for the conversation. Example: ['inlineAd'].
character
Character
required
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).
otherParams
Map<String, dynamic>
Used to pass publisher-specific information to Kontext.
isDisabled
bool
Flag indicating if the ads are disabled.
onEvent
void Function(AdEvent event)
Callback triggered when an event occurs. See Supported events for more details.

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

Controlling when ads load

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

Handling no-fill events

You can detect when no ad is 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.