Settings & Configuration
A field-by-field reference for every placement config. For worked examples, see the Integration Guide.
TeadsSdk
| Method | Returns | Notes |
|---|---|---|
configure(String appKey) | Future<void> | Call once at app start, before any placement. Throws PlatformException if the key is rejected |
setTestMode(bool) | Future<void> | Native test mode. Process-wide. Required for Recommendations.setTestRtb. Remove before release |
await TeadsSdk.configure('YOUR_APP_KEY');
MediaPlacementConfig
Fields
| Field | Type | Default | Description |
|---|---|---|---|
pid | int | required | Placement ID for video ads (e.g. 84242) |
articleUrl | String? | null | URL of the content being read — drives contextual targeting and brand safety |
enableValidationMode | bool | false | Forces a test creative. Remove before release |
pid is an intUnlike the native SDKs' string-based widget IDs, Media takes a numeric placement ID.
MediaPlacementConfig(pid: '84242') will not compile.
MediaPlacement
| Property | Type | Description |
|---|---|---|
config | MediaPlacementConfig | required |
onReady | VoidCallback? | |
onFailed | void Function(TeadsAdError)? | |
onClicked | void Function(TeadsAdClick)? | |
onClickedOrganic | void Function(TeadsAdClick)? | |
onEvent | void Function(TeadsAdEvent, Map<String, dynamic>?)? |
MediaPlacement.initialHeight is 250 — the height reserved until the creative reports
its real one.
MediaPlacement(
config: MediaPlacementConfig(
pid: 84242,
articleUrl: 'https://example.com/article/123',
),
)
FeedPlacementConfig
Commonly used fields
| Field | Type | Default | Description |
|---|---|---|---|
articleUrl | String | required | The page context. The bridge refuses to serve without it |
widgetId | String | required | Widget identifier (e.g. MB_1) |
installationKey | String | required | Your installation key |
widgetIndex | int | 0 | Coordination key, not a position — see below |
userId | String? | null | For personalized recommendations. Consent required |
darkMode | bool | false | Dark theme for the widget |
pubImpId | String? | null | Publisher impression ID |
Advanced fields
Defaults are correct for a standard integration. Change them only if Teads asks you to.
| Field | Type | Default |
|---|---|---|
unitFormat | String | 'feed' |
integrationType | String | 'direct' |
widgetEvents | String | 'all' |
bridgePath | String | 'index.html' |
bridgeEndpoint | String | The default bridge host |
bridgeParams | String? | null |
sdkVersion | String? | null — reports the linked native SDK version. Override only for testing |
flutterPackageVersion | String | the plugin version |
widgetIndex is a coordination key, not a visual positionOnly a placement with widgetIndex: 0 fetches its ad directly. Any other value waits
for a widgetIndex: 0 placement on the same page to publish shared bridge parameters.
With no widgetIndex: 0 placement on the page, the ad never loads and no error is
reported. Use 0 unless you have a second Feed guaranteed to load first with 0.
copyWith
FeedPlacement(config: feedConfig.copyWith(darkMode: true))
darkMode is the only field that takes effect on an already-loaded placement — it is
pushed into the live page. Every other field only affects the initial bridge URL, so
changing it does nothing until the page is recreated.
FeedPlacement
| Property | Type | Description |
|---|---|---|
config | FeedPlacementConfig | required |
maxHeight | double? | Caps the height so the feed scrolls internally. null grows to content height |
onEvent | void Function(TeadsAdEvent, Map<String, dynamic>?)? | Bridge lifecycle/telemetry |
onUnsupported | void Function(TeadsAdError)? | Parity gaps and page errors — the only route for them |
onOrganicClick | void Function(Uri organicUrl)? | Organic tap. Null opens an external browser |
onFullScreenChange | void Function(bool fullScreen)? | Fold your chrome away |
FeedPlacement.loadMoreThreshold is 600 logical pixels — the distance from the end at
which the next chunk is requested.
BannerPlacementConfig
Deliberately the same shape as FeedPlacementConfig: natively, Banner and Feed are the
same widget with a different format.
| Field | Type | Default | Description |
|---|---|---|---|
articleUrl | String | required | The page context |
widgetId | String | required | Banner widget identifier (e.g. MB_10) |
installationKey | String | required | Your installation key |
widgetIndex | int | 0 | Coordination key, as for Feed |
userId | String? | null | Consent required |
darkMode | bool | false | The value used at construction only |
testDisplay | bool | false | Forces a test creative. Remove before release |
BannerPlacement
| Property | Type | Description |
|---|---|---|
config | BannerPlacementConfig | required |
controller | BannerController? | Imperative handle. One is created internally if omitted |
onReady / onFailed / onClicked / onClickedOrganic / onEvent | As for Media |
BannerPlacement.initialHeight is 100.
BannerController
| Method | Returns | Description |
|---|---|---|
toggleDarkMode(bool) | Future<void> | Changes dark mode on a loaded banner |
Calls made before the banner has loaded are buffered and applied when it does.
final controller = BannerController();
BannerPlacement(config: bannerConfig, controller: controller);
// later:
await controller.toggleDarkMode(true);
BannerPlacementConfig.darkMode sets the value the banner is built with;
toggleDarkMode changes a banner that already exists. You need the controller for
runtime changes.
InterstitialPlacementConfig
| Field | Type | Default | Description |
|---|---|---|---|
articleUrl | String | required | The page context |
widgetId | String | required | Interstitial widget identifier (e.g. INT_MW_1) |
installationKey | String | required | Your installation key |
floorPrice | double? | null | Bid floor in US dollars (2.5 = $2.50) |
Android's native interstitial config also accepts widgetIndex, userId and
darkMode, which have no iOS counterpart. Rather than accept fields one platform would
silently drop, the plugin exposes only what both support.
floorPrice is rounded to the nearest whole dollar at the platform boundary, because
both native SDKs still type it as an integer.
InterstitialPlacement
| Member | Type | Description |
|---|---|---|
create({required config}) | Future<InterstitialPlacement> | Static factory; creates the native placement |
load() | Future<void> | Completes when the request is dispatched, not when the ad is ready |
isReady | Future<bool> | Re-check immediately before show() |
show() | Future<bool> | false if there was nothing to show |
dispose() | Future<void> | Required — releases the WebView and OM session |
onReady / onFailed / onClicked / onClickedOrganic / onClosed / onEvent | assignable fields |
RecommendationsPlacementConfig
Two mutually exclusive named constructors, mirroring the native request shapes.
.url
| Field | Type | Default | Description |
|---|---|---|---|
widgetId | String | required | Recommendations widget identifier |
articleUrl | String | required | The page context |
widgetIndex | int | 0 | The widget's index on the page |
externalId | String? | null | Your own identifier for the request, for reporting |
obPubImp | String? | null | Publisher impression ID |
.platform
| Field | Type | Default | Description |
|---|---|---|---|
widgetId | String | required | Recommendations widget identifier |
widgetIndex | int | 0 | The widget's index on the page |
contentUrl | String? | null | The content URL |
portalUrl | String? | null | The portal URL, for platform publishers |
bundleUrl | String? | null | The bundle URL of the app displaying the widget |
lang | String? | null | Content language, e.g. en — required by the server for platform requests |
psub | String? | null | An additional source breakdown available for platforms |
obPubImp | String? | null | Publisher impression ID |
A platform request is for an app or portal rather than one article. One of
contentUrl, portalUrl or bundleUrl must hold an actual URL, and lang must be
set. Both are optional in the Dart signature because they are optional in both native
SDKs; the server rejects a request without them.
Recommendations
| Method | Returns | Description |
|---|---|---|
fetch(config) | Future<List<TeadsRecommendation>> | Throws PlatformException on failure |
registerClick(rec) | Future<String?> | Call only at the moment of a tap |
release(recs) | Future<void> | Frees the native click cache for a list you no longer show. Optional; never throws |
adChoicesUrl | Future<String?> | The URL your AdChoices icon must open — required to ship |
setTestRtb(bool) | Future<void> | Forces paid items for testing. Only works with TeadsSdk.setTestMode(true). Process-wide. Remove before release |
TeadsPrivacy
| Method | Description |
|---|---|
setGdprApplies(bool) | Whether GDPR applies to this user |
setGdprConsentStringV2(String?) | IAB TCF v2 string |
setGdprConsentStringV1(String?) | IAB TCF v1 string (legacy) |
setUsPrivacyString(String?) | US Privacy (CCPA) string |
setGppString(String?) | IAB GPP string |
setGppSections(String?) | GPP applicable section IDs |
clearAllOverrides() | Return to reading platform storage |
isIdfaTrackingAuthorized | Future<bool?> — reads the current state, never prompts |
requestTrackingAuthorization() | Future<bool?> — shows the iOS ATT prompt. null on Android. Call it after the first frame, never before runApp |
The consent setters are only needed for a custom CMP; requestTrackingAuthorization() is
needed by almost every iOS app. See Privacy & Consent.
TeadsLog
| Member | Type | Default |
|---|---|---|
TeadsLog.level | LogLevel | LogLevel.warn |
TeadsLog.sink | TeadsLogSink | prints via debugPrint |
See Logging.
RecommendationsViewabilityReporter
| Member | Type | Default | Description |
|---|---|---|---|
reportingInterval | Duration | 2000 ms | How often pending reports are batched into one request |
pollInterval | Duration | 250 ms | How often each item's visibility is re-measured |
track(GlobalKey, rec) | Start tracking an item | ||
untrack(GlobalKey) | Stop tracking — call when a key is reused | ||
dispose() | Required — releases the timers |
See Recommendations Viewability.
Best Practices
Production settings
- ✅ Production
pid,widgetIdandinstallationKeyvalues - ✅
enableValidationModeandtestDisplayremoved - ✅ A real
articleUrlfor the content being read - ✅
widgetIndex: 0unless you deliberately coordinate multiple Feeds - ✅ Consent handling verified
Security
- ✅ Never commit installation keys or app keys — use
--dart-defineor a config file that is not in version control - ✅ Validate URLs before passing them to a placement
- ✅ Do not log full consent strings in production builds
flutter run --dart-define=TEADS_APP_KEY=your-key
const appKey = String.fromEnvironment('TEADS_APP_KEY');
await TeadsSdk.configure(appKey);
Performance
- ✅ Hold configs rather than rebuilding them every frame
- ✅ Dispose
InterstitialPlacementandRecommendationsViewabilityReporter - ✅ One
BannerPlacementat a time - ✅ Never one placement per list row
Related Documentation
- Placement Events — the event vocabulary
- Integration Guide — worked examples
- Test Configurations — test IDs
- Troubleshooting Guide — common issues