Theaimart ADX Flutter SDK
The official Theaimart ADX Flutter SDK for integrating advertisements and monetizing Flutter applications across Android, iOS, web, Windows, macOS, and Linux.
Built for cross-platform Flutter developers, theaimart_adx provides a lightweight API for requesting, rendering, tracking, and managing advertisements through the Theaimart Ad Network.
The SDK implements version 1 of the Theaimart ADX wire contract.
dependencies:
theaimart_adx: ^1.0.0
Highlights
- Cross-platform Flutter ad SDK
- Android and iOS app monetization
- Flutter web advertising support
- Windows, macOS, and Linux support
- Drop-in
BannerAdwidget - Direct
AdxClientAPI - Automatic image-ad rendering
- Automatic click handling
- Automatic viewability tracking
- Custom HTML and OpenRTB creative rendering
- Fraud-safe platform User-Agent generation
- SQL-filter-safe request encoding
- Fail-closed response handling
- Typed ad-response models
- Testable HTTP client architecture
- Compatibility with the Theaimart ADX wire contract v1
Table of Contents
- What is Theaimart ADX?
- Supported Platforms
- Features
- Installation
- Quick Start
- Banner Ad Integration
- Image Ads
- HTML and OpenRTB Creatives
- Direct Client Usage
- Viewability Tracking
- Click Handling
- User-Agent and Device Classification
- Security and Request Encoding
- Error and No-Fill Handling
- Ad Response Model
- API Reference
- Application Lifecycle
- Production Integration
- Testing
- Frequently Asked Questions
- Wire Contract
- License
What is Theaimart ADX?
Theaimart ADX is an advertising and application-monetization platform for developers, publishers, and software businesses.
The Theaimart ADX Flutter SDK connects a Flutter application to the Theaimart advertising infrastructure. It allows an application to:
- Request an advertisement for a configured ad slot.
- Receive a filled ad or a safe no-fill response.
- Render image, HTML, or supported OpenRTB creatives.
- Track viewable impressions.
- Open registered advertisement click URLs.
- Identify the demand source behind an advertisement.
- Monetize application traffic across supported Flutter platforms.
The package is designed for applications that need a consistent advertising API across mobile, web, and desktop environments.
Supported Platforms
The SDK is designed for Flutter applications targeting:
| Platform | Support |
|---|---|
| Android | Supported |
| iOS | Supported |
| Web | Supported |
| Windows | Supported |
| macOS | Supported |
| Linux | Supported |
Platform-specific capabilities can vary.
For example:
- Image rendering uses Flutter's network-image support.
- External click navigation depends on the URL-launching implementation available for the target platform.
- HTML creatives require an application-provided
htmlBuilder. - WebView availability and configuration differ between mobile, web, and desktop platforms.
Applications should test their selected creative renderer on every platform they intend to release.
Features
Cross-platform Flutter integration
Use one SDK API across Android, iOS, web, and desktop Flutter applications.
Drop-in banner widget
The BannerAd widget manages the standard advertisement lifecycle:
- Sending the ad request
- Parsing the response
- Rendering supported image creatives
- Detecting ad viewability
- Reporting viewable impressions
- Handling clicks
- Reporting loaded and failed states
Direct API access
Applications that require custom interfaces can use AdxClient directly and render the returned advertisement themselves.
Automatic image rendering
Image creatives can be rendered through Flutter's Image.network.
Automatic click navigation
Supported banner creatives can open their registered click destination using the configured URL-launching implementation.
Automatic viewability measurement
The managed banner tracks viewability and reports the impression after the advertisement remains at least 50% visible for at least one second.
Custom HTML creative rendering
HTML and OpenRTB creatives can be rendered through an application-provided htmlBuilder.
This gives the host application control over:
- WebView selection
- WebView security policy
- Navigation behavior
- JavaScript configuration
- Cookie handling
- Platform-specific rendering
- Creative dimensions
Safe response parsing
The SDK handles the supported wire-response variants through typed union parsing.
Fail-closed behavior
Malformed responses, unsupported creatives, network failures, and rendering errors result in no-fill behavior instead of destabilizing the host application.
Platform-aware User-Agent
platformUserAgent() generates a User-Agent containing a recognizable platform token for backend device classification.
Request-value encoding
Free-text request parameters are encoded according to the Theaimart ADX wire contract before being sent to the backend.
Installation
Add theaimart_adx to your Flutter application's pubspec.yaml:
dependencies:
flutter:
sdk: flutter
theaimart_adx: ^1.0.0
Fetch the package:
flutter pub get
Import it into your Dart code:
import 'package:theaimart_adx/theaimart_adx.dart';
Depending on the creative types and platforms used by your application, you may also need packages for URL launching or WebView rendering.
For example:
dependencies:
url_launcher: ^6.0.0
webview_flutter: ^4.0.0
Use versions compatible with your application's current Flutter toolchain.
Quick Start
Add a drop-in banner advertisement to your widget tree:
import 'package:flutter/material.dart';
import 'package:theaimart_adx/theaimart_adx.dart';
class MonetizedScreen extends StatelessWidget {
const MonetizedScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('My App'),
),
body: Column(
children: [
const Expanded(
child: Center(
child: Text('Application content'),
),
),
BannerAd(
apiKey: 'pk_your_publisher_key',
slotId: '8b1f2c3d-0000-0000-0000-000000000000',
onAdLoaded: (ad) {
debugPrint('Ad filled from ${ad.source}');
},
onAdFailed: (reason) {
debugPrint('No fill: $reason');
},
),
],
),
);
}
}
Replace:
pk_your_publisher_keywith your public Theaimart ADX publisher key- The example UUID with the slot ID configured for your placement
Do not place private server credentials or administrative API keys inside a Flutter application.
Banner Ad Integration
BannerAd is the recommended integration for standard banner placements.
BannerAd(
apiKey: 'pk_your_publisher_key',
slotId: '8b1f2c3d-0000-0000-0000-000000000000',
onAdLoaded: (ad) {
debugPrint(
'Loaded ${ad.kind} advertisement from ${ad.source}',
);
},
onAdFailed: (reason) {
debugPrint('Advertisement unavailable: $reason');
},
)
The widget manages:
- Client creation
- Ad request execution
- Response parsing
- Filled/no-fill state
- Image creative rendering
- Impression viewability
- Viewability reporting
- Click handling
- Failure isolation
Placement inside a layout
Column(
children: [
const Expanded(
child: AppContent(),
),
SafeArea(
top: false,
child: BannerAd(
apiKey: 'pk_your_publisher_key',
slotId: 'footer-banner-slot-id',
),
),
],
)
Placement inside a scrollable screen
ListView(
children: [
const ContentSection(),
const SizedBox(height: 16),
BannerAd(
apiKey: 'pk_your_publisher_key',
slotId: 'content-banner-slot-id',
onAdFailed: (reason) {
debugPrint('Content banner returned no fill: $reason');
},
),
const SizedBox(height: 16),
const MoreContentSection(),
],
)
Ensure that the advertisement is not obscured, clipped unexpectedly, or placed in a layout that prevents viewability from being measured correctly.
Image Ads
Image creatives are rendered using Flutter's network-image support.
Conceptually, the managed widget performs behavior equivalent to:
Image.network(
imageUrl,
fit: BoxFit.contain,
)
When a user taps the advertisement, the SDK opens the registered click URL using the configured URL-launching behavior.
The managed banner is responsible for:
- Loading the creative
- Displaying the image
- Preserving the advertisement interaction
- Triggering the registered click
- Reporting the impression after the viewability threshold is met
Custom image rendering
Applications using AdxClient directly can render an image creative themselves:
final adx = AdxClient(
apiKey: 'pk_your_publisher_key',
userAgent: platformUserAgent(),
);
final ad = await adx.requestAd(
const AdRequest(
slotId: '8b1f2c3d-0000-0000-0000-000000000000',
),
);
if (ad.filled && ad.kind == AdKind.image) {
final creative = ad.creative;
// Extract and render the image URL according to the creative model.
}
Custom renderers are responsible for implementing correct click and viewability behavior.
HTML and OpenRTB Creatives
The SDK does not force a single WebView dependency on every Flutter application.
For HTML or OpenRTB creatives, provide an htmlBuilder that converts the creative into a widget appropriate for your supported platforms.
Example structure:
BannerAd(
apiKey: 'pk_your_publisher_key',
slotId: 'html-banner-slot-id',
htmlBuilder: (context, html, width, height) {
return MySecureHtmlAdRenderer(
html: html,
width: width,
height: height,
);
},
onAdLoaded: (ad) {
debugPrint('Loaded HTML advertisement');
},
onAdFailed: (reason) {
debugPrint('HTML advertisement unavailable: $reason');
},
)
A renderer can wrap a package such as webview_flutter on supported mobile platforms.
Example renderer outline
class MySecureHtmlAdRenderer extends StatelessWidget {
const MySecureHtmlAdRenderer({
required this.html,
super.key,
});
final String html;
@override
Widget build(BuildContext context) {
// Initialize and configure your selected WebView implementation.
//
// Recommended controls:
// - Restrict unexpected navigation
// - Validate external URLs
// - Configure JavaScript deliberately
// - Avoid exposing application bridges unnecessarily
// - Apply suitable size constraints
// - Prevent the creative from escaping its placement
return const SizedBox(
height: 250,
child: Center(
child: Text('Render HTML creative here'),
),
);
}
}
The exact WebView code depends on:
- Selected Flutter WebView package
- Target operating system
- Creative requirements
- JavaScript policy
- Navigation policy
- Application security requirements
Why htmlBuilder is application-provided
This architecture avoids forcing a heavy or platform-limited WebView dependency into every application.
It also allows developers to choose:
webview_flutter- A desktop-compatible WebView package
- A web-specific renderer
- A sandboxed custom renderer
- A platform-specific widget implementation
Direct Client Usage
Use AdxClient when the application needs complete control over ad requests and creative rendering.
final adx = AdxClient(
apiKey: 'pk_your_publisher_key',
userAgent: platformUserAgent(),
);
try {
final ad = await adx.requestAd(
const AdRequest(
slotId: '8b1f2c3d-0000-0000-0000-000000000000',
),
);
if (!ad.filled) {
debugPrint('No fill: ${ad.reason}');
return;
}
debugPrint('Filled ad from ${ad.source}');
if (ad.isTrackable && ad.impId != null) {
await adx.reportViewable(ad.impId!);
}
} finally {
adx.close();
}
Important lifecycle rule
Always close an AdxClient that is no longer needed:
adx.close();
Closing the client releases the underlying HTTP resources owned by that instance.
Reusable client
For applications making multiple requests, create a reusable client and close it when the owning service is disposed.
class AppAdService {
AppAdService({
required String apiKey,
}) : _client = AdxClient(
apiKey: apiKey,
userAgent: platformUserAgent(),
);
final AdxClient _client;
Future<Ad> requestBanner(String slotId) {
return _client.requestAd(
AdRequest(slotId: slotId),
);
}
Future<void> reportViewable(String impressionId) {
return _client.reportViewable(impressionId);
}
void dispose() {
_client.close();
}
}
Viewability Tracking
The managed BannerAd widget automatically reports an impression when the advertisement is:
- At least 50% visible
- Continuously visible for at least one second
- Associated with a trackable impression ID
This helps prevent impressions from being counted before an advertisement has actually entered a viewable state.
Managed banner behavior
BannerAd(
apiKey: 'pk_your_publisher_key',
slotId: 'banner-slot-id',
)
No manual reportViewable call is required when using the standard widget.
Custom renderer behavior
When using AdxClient directly, report the impression only after your own renderer has confirmed that the advertisement meets the required viewability conditions.
if (ad.filled && ad.isTrackable && ad.impId != null) {
await adx.reportViewable(ad.impId!);
}
Do not report an advertisement immediately after receiving the response unless it has actually satisfied the viewability requirement.
Possible custom measurement approaches include:
- Visibility-detection widgets
- Render-object bounds
- Scroll-position tracking
- Application lifecycle awareness
- Window visibility checks
- Route visibility checks
Click Handling
For managed image banners, click behavior is handled automatically.
The SDK associates the user interaction with the impression and opens the registered destination through the platform's URL-launching mechanism.
For custom creative rendering, use the SDK-provided click information rather than opening an unregistered destination independently.
Applications should:
- Validate that the destination is a supported URI
- Use external application mode where appropriate
- Handle launch failures safely
- Avoid intercepting the click for unrelated application actions
- Prevent repeated accidental activations
- Preserve the advertisement's registered tracking flow
A click-navigation failure should not crash the application.
User-Agent and Device Classification
Theaimart ADX uses the request User-Agent as one signal for SDK identification and device classification.
Create the client using:
final adx = AdxClient(
apiKey: 'pk_your_publisher_key',
userAgent: platformUserAgent(),
);
platformUserAgent() generates a User-Agent with a structure similar to:
theaimart-adx-flutter/<version> (<platform-token>)
Examples may include recognizable platform tokens such as:
theaimart-adx-flutter/1.0.0 (Android)
theaimart-adx-flutter/1.0.0 (iPhone)
theaimart-adx-flutter/1.0.0 (Windows)
theaimart-adx-flutter/1.0.0 (macOS)
theaimart-adx-flutter/1.0.0 (Linux)
The platform-aware User-Agent:
- Identifies the official Flutter SDK
- Communicates the SDK version
- Includes a recognizable device or operating-system token
- Supports backend traffic classification
- Avoids generic HTTP-client identifiers
- Reduces false bot classification
- Helps prevent silent no-fill caused by blocked User-Agent patterns
The User-Agent rules are defined in CONTRACT.md section 6.
Custom User-Agent
Only override the generated User-Agent when you have a controlled and verified reason.
A custom value should continue to include:
- The Theaimart ADX Flutter SDK identifier
- The SDK version
- A supported platform token
Removing the platform token can prevent the backend from classifying the request correctly.
Security and Request Encoding
The SDK encodes free-text request values according to the rules defined in CONTRACT.md section 7.
This protects normal values such as URLs and application metadata from being misclassified by backend filtering or Web Application Firewall rules.
The encoding layer is designed to:
- Preserve valid free-text values
- Produce deterministic request parameters
- Prevent malformed query construction
- Avoid raw values unexpectedly triggering security filters
- Keep requests compatible with SQL-backed targeting filters
- Reduce unsafe input propagation
Public publisher keys
The API key used in a Flutter application must be a public publisher key intended for client-side distribution:
pk_your_publisher_key
Never embed the following inside a Flutter application:
- Administrative credentials
- Secret backend keys
- Database passwords
- Private signing keys
- Advertiser billing credentials
- Internal service tokens
- Infrastructure access credentials
Flutter mobile and desktop application bundles can be inspected by end users. Flutter web application code and configuration are delivered directly to the browser.
Error and No-Fill Handling
Advertising failures should never interrupt the application's primary functionality.
The SDK therefore uses fail-closed behavior.
Examples of conditions that can produce a safe no-fill result include:
- Network connection failure
- DNS failure
- Request timeout
- Invalid HTTP response
- Malformed JSON
- Missing response fields
- Unsupported response variant
- Unsupported creative type
- Invalid impression identifier
- Creative-rendering failure
- Viewability-report failure
- Click-launch failure
Expected behavior:
Error → no fill or ignored best-effort tracking failure
Unsafe behavior avoided by the SDK:
Error → uncaught exception that crashes the application
Use onAdFailed to collapse or replace the placement:
BannerAd(
apiKey: 'pk_your_publisher_key',
slotId: 'banner-slot-id',
onAdFailed: (reason) {
debugPrint('Ad unavailable: $reason');
},
)
For direct client usage:
final ad = await adx.requestAd(
const AdRequest(
slotId: 'banner-slot-id',
),
);
if (!ad.filled) {
debugPrint('No fill: ${ad.reason}');
}
Do not block access to essential application content when an advertisement is unavailable.
Ad Response Model
requestAd returns a typed Ad object.
An advertisement response can describe:
- Whether an advertisement was filled
- Creative kind
- Demand source
- Impression identifier
- Creative payload
- Auction metadata
- No-fill reason
- Trackability status
Common properties include:
| Property | Description |
|---|---|
filled |
Whether an eligible advertisement was returned |
kind |
Creative type such as image, HTML, or no-fill |
source |
Demand source such as internal, OpenRTB, or house |
impId |
Impression identifier used for tracking |
creative |
Creative payload returned by the backend |
auction |
Auction-related response data |
reason |
No-fill or failure reason, when available |
isTrackable |
Whether viewability can be reported |
Filled response
if (ad.filled) {
debugPrint('Advertisement available');
}
No-fill response
if (!ad.filled) {
debugPrint('No fill: ${ad.reason}');
}
Trackable response
if (ad.isTrackable && ad.impId != null) {
await adx.reportViewable(ad.impId!);
}
Demand-source inspection
debugPrint('Demand source: ${ad.source}');
Typical demand-source values represent:
- Internal demand
- OpenRTB demand
- House advertisements
Four-Way Union Parsing
The SDK parses the response as a bounded union rather than assuming every successful HTTP response contains the same creative structure.
The supported response paths cover the contract-defined outcomes, including:
- Filled image advertisement
- Filled HTML or OpenRTB advertisement
- House or internal fallback advertisement
- No-fill or failure response
The parser validates the response before exposing it to the rendering layer.
Unexpected or incomplete response shapes fail closed and are treated as no-fill rather than being passed into application UI code as an unsafe partially initialized model.
API Reference
BannerAd
A Flutter widget that manages advertisement loading and rendering.
BannerAd(
apiKey: 'pk_your_publisher_key',
slotId: 'your-slot-id',
onAdLoaded: (ad) {},
onAdFailed: (reason) {},
htmlBuilder: (context, html, width, height) {
return YourHtmlRenderer(
html: html,
width: width,
height: height,
);
},
)
Important inputs:
| Parameter | Description |
|---|---|
apiKey |
Public Theaimart ADX publisher key |
slotId |
Identifier of the configured ad placement |
onAdLoaded |
Called after an advertisement is successfully loaded |
onAdFailed |
Called after no-fill or rendering failure |
htmlBuilder |
Application-provided renderer for HTML/OpenRTB creatives |
The exact available constructor fields should be treated as authoritative from the installed package API.
AdxClient
Creates a reusable API client.
final client = AdxClient(
apiKey: 'pk_your_publisher_key',
userAgent: platformUserAgent(),
);
Depending on the package API, client construction can also expose configuration such as:
- API base URL
- Request timeout
- HTTP client
- User-Agent
- Testing overrides
Use production defaults unless a controlled development or testing environment requires an override.
requestAd
Requests an advertisement asynchronously:
final ad = await client.requestAd(
const AdRequest(
slotId: 'your-slot-id',
),
);
The returned future resolves to a typed Ad result.
reportViewable
Reports a viewable impression:
await client.reportViewable(impressionId);
This operation is best effort. A beacon failure should not invalidate an already rendered advertisement or break the primary application flow.
close
Releases resources owned by the client:
client.close();
Call this when a reusable client or ad service is permanently disposed.
platformUserAgent
Creates the recommended platform-aware SDK User-Agent:
final userAgent = platformUserAgent();
Use it when creating AdxClient directly.
AdRequest
Defines an advertisement request:
const request = AdRequest(
slotId: '8b1f2c3d-0000-0000-0000-000000000000',
);
The slot ID should correspond to a real placement configured in the publisher account.
Use separate slot IDs for placements that require distinct reporting or configuration.
Examples:
- Home-screen banner
- Article banner
- Dashboard placement
- Search-results banner
- Desktop sidebar
- Web footer
- Content-detail advertisement
Application Lifecycle
A Flutter application can rebuild widgets frequently.
Avoid creating unnecessary long-lived HTTP clients inside repeated build operations unless the managed widget owns and disposes them correctly.
For direct usage, manage the client inside a service, state object, provider, or dependency-injection container.
Stateful lifecycle example
class AdClientOwner extends StatefulWidget {
const AdClientOwner({super.key});
@override
State<AdClientOwner> createState() => _AdClientOwnerState();
}
class _AdClientOwnerState extends State<AdClientOwner> {
late final AdxClient _adx;
@override
void initState() {
super.initState();
_adx = AdxClient(
apiKey: 'pk_your_publisher_key',
userAgent: platformUserAgent(),
);
}
@override
void dispose() {
_adx.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
Do not call close() while requests that still need the client are expected to continue.
Production Integration
For a stable production integration:
- Use a public publisher API key assigned to the application.
- Create separate slot IDs for independently managed placements.
- Use
BannerAdfor standard image-banner integrations. - Supply an audited
htmlBuilderfor HTML or OpenRTB creatives. - Use
platformUserAgent()with direct clients. - Keep the SDK identifier and device token in custom User-Agents.
- Do not report impressions before the viewability threshold is met.
- Close manually created
AdxClientinstances. - Collapse or replace placements after no-fill.
- Do not block core application functionality when advertising fails.
- Test filled, no-fill, timeout, malformed-response, and click scenarios.
- Verify every target platform independently.
- Restrict WebView navigation and application bridges.
- Never embed server-side credentials in Flutter code.
- Keep package and wire-contract versions compatible.
Recommended placement behavior
Good placement behavior:
- The advertisement is clearly visible.
- The ad does not cover essential controls.
- The ad does not imitate application navigation.
- The layout remains usable after no-fill.
- The creative fits inside explicit size constraints.
- User taps are intentional.
- The advertisement does not trigger automatically.
Avoid:
- Hidden or one-pixel advertisements
- Ads underneath opaque widgets
- Accidental-click layouts
- Ads placed directly over primary buttons
- Automatic click opening
- Reporting non-viewable impressions
- Repeated uncontrolled reload loops
- Unrestricted WebView navigation
Flutter Web Considerations
Flutter web applications operate inside the browser security model.
Consider:
- Browser CORS policy
- Content Security Policy
- Pop-up and external-navigation restrictions
- Browser visibility state
- Tab backgrounding
- Responsive banner dimensions
- Web-specific HTML-rendering behavior
- URL-launching restrictions
- Public visibility of publisher configuration
A Flutter web application cannot keep an embedded key secret. Only client-safe publisher keys should be used.
Test the package against the production domain from which the Flutter web application will be served.
Android Considerations
For Android applications:
- Ensure internet access is available.
- Test on the minimum supported Android version.
- Test on recent Android versions.
- Verify external click navigation.
- Verify that application network-security configuration permits the required HTTPS endpoints.
- Test lifecycle changes such as backgrounding and rotation.
- Ensure ad widgets are not duplicated during rebuilds.
- Validate WebView settings when rendering HTML creatives.
Use HTTPS endpoints in production.
iOS Considerations
For iOS applications:
- Test external click navigation.
- Verify App Transport Security compatibility.
- Validate application lifecycle transitions.
- Test creative rendering on iPhone and iPad layouts where applicable.
- Review WebView navigation and JavaScript policy.
- Ensure your integration follows applicable App Store rules and privacy disclosures.
Use secure production endpoints.
Desktop Considerations
For Windows, macOS, and Linux applications:
- Confirm the selected URL launcher supports the target desktop platform.
- Confirm the selected WebView package supports the target operating system.
- Test window resizing.
- Test high-DPI displays.
- Test application minimization and restoration.
- Verify viewability when the window is obscured or inactive.
- Apply explicit creative size constraints.
- Validate external-browser behavior.
The core client can request advertisements independently of the widget renderer, but rendering capabilities depend on the packages and native implementations included in the host application.
Testing
Enter the Flutter package directory:
cd packages/flutter
Fetch dependencies:
flutter pub get
Run the unit-test suite:
flutter test
The tests cover platform-independent SDK behavior, including:
- Free-text request encoding
- Ad-model parsing
- Filled-response parsing
- No-fill parsing
- Union-response handling
- Invalid-response handling
- HTTP client behavior
- Mocked network responses
- Trackability behavior
The client tests use a mock HTTP client, allowing request and response behavior to be verified without contacting the production advertising backend.
Recommended verification command
flutter pub get
flutter analyze
flutter test
Recommended production test matrix
Test at least the following cases:
| Test case | Expected behavior |
|---|---|
| Filled image ad | Image renders successfully |
| Image tap | Registered click destination opens |
| Viewable for at least one second | Impression beacon fires once |
| Less than 50% visible | Impression is not reported |
| No-fill response | Placement collapses or remains unobtrusive |
| Network timeout | Safe failure without application crash |
| Invalid JSON | Safe no-fill |
| Missing impression ID | Ad is not treated as trackable |
| HTML creative without builder | Safe failure or no-fill |
| HTML creative with builder | Custom renderer displays the creative |
| URL-launch failure | Application remains stable |
| Widget disposal | No invalid post-disposal update |
| Client disposal | HTTP resources are released |
| Repeated rebuild | No uncontrolled duplicate requests |
For UI and viewability verification, use integration tests or physical/emulated target devices in addition to unit tests.
Frequently Asked Questions
What is theaimart_adx?
theaimart_adx is the official Flutter SDK for requesting, rendering, and tracking advertisements from Theaimart ADX.
Which Flutter platforms are supported?
The SDK is designed for Android, iOS, web, Windows, macOS, and Linux applications.
Some rendering features require platform-compatible URL-launcher or WebView packages.
Does the SDK include a banner widget?
Yes. BannerAd provides a drop-in Flutter widget for standard advertising placements.
Does the SDK render image ads automatically?
Yes. Managed image creatives are rendered through Flutter's network-image functionality.
How are advertisement clicks handled?
Managed image ads use tap-to-open behavior through the configured URL-launching implementation.
Does it support HTML creatives?
Yes. Supply an htmlBuilder to render HTML or OpenRTB creatives using your preferred WebView or custom rendering package.
Why is a WebView dependency not included automatically?
Different Flutter platforms require different WebView implementations. Keeping the renderer application-provided avoids forcing an unnecessary or unsupported dependency into every integration.
Does the SDK track viewability automatically?
BannerAd automatically reports a trackable impression after the advertisement remains at least 50% visible for at least one second.
Do I need to call reportViewable manually?
Not when using the managed BannerAd widget.
When using AdxClient directly, your application must measure viewability and report the impression manually.
What happens when a request fails?
The SDK fails closed. Errors result in no-fill behavior rather than an uncaught exception escaping into the host application.
Why should I use platformUserAgent()?
It generates a fraud-safe User-Agent containing the SDK identity and a recognizable platform token. This helps the backend classify the request correctly and avoids generic blocked User-Agent patterns.
Can I use a custom User-Agent?
Yes, but it should preserve the SDK identifier, version, and platform token required by the wire contract.
Should I close AdxClient?
Yes. Close manually created clients when they are no longer needed.
Can I create one client for multiple ad requests?
Yes. A reusable client is generally preferable for multiple direct requests. Dispose it through your application's lifecycle-management mechanism.
Can advertising errors crash my Flutter application?
The SDK is designed to convert networking, parsing, and supported rendering failures into safe no-fill behavior. Application-provided custom renderers should follow the same principle.
Can I put my secret server key in the Flutter application?
No. Use only public publisher keys intended for client-side distribution.
Does the SDK work with OpenRTB demand?
The response model can represent OpenRTB-sourced advertisements. HTML or OpenRTB creative rendering requires an appropriate htmlBuilder.
What should happen after no-fill?
Hide, collapse, or gracefully replace the advertising placement. Do not leave a disruptive empty region or block access to application content.
Flutter App Monetization with Theaimart ADX
The Theaimart ADX Flutter SDK can be used by developers building:
- Android Flutter applications
- iOS Flutter applications
- Flutter web applications
- Windows desktop applications
- macOS desktop applications
- Linux desktop applications
- AI applications
- Productivity tools
- Utility applications
- Content platforms
- Developer tools
- SaaS companion applications
- Cross-platform consumer products
- Publisher applications
- Local-first desktop software
The package provides a common monetization layer across Flutter platforms while allowing each application to retain control over creative rendering, lifecycle management, WebView security, and user experience.
Learn more about Theaimart ADX:
Wire Contract
The SDK implements version 1 of the Theaimart ADX wire contract:
../../CONTRACT.md
Relevant contract areas include:
- Request structure
- Response variants
- Publisher authentication
- User-Agent requirements
- Device classification
- Free-text input encoding
- Impression identifiers
- Viewability reporting
- Click tracking
- Creative representation
- No-fill behavior
- Failure handling
The Flutter SDK and backend must remain compatible with the same contract version.
Breaking changes to request fields, response models, creative payloads, or tracking behavior should be introduced through an explicit wire-contract version update.
License
Apache License 2.0.
Copyright © 2026 Theaimart.
Licensed under the Apache License, Version 2.0. You may not use this package except in compliance with the License. Refer to the repository's LICENSE file for the complete license terms.
Libraries
- theaimart_adx
- Official theaimart Ad Network SDK for Flutter.