Skip to content

Options

Pass options once, to DeaSdk.init. They are read when the SDK starts. A later init call returns the running instance and keeps its options, including when it passes a different appId.

DeaOptions holds what the SDK captures. A few settings are named arguments of DeaSdk.init itself, next to DeaOptions.

The sample below uses path_provider for modelDirectory. Add it to your app first:

flutter pub add path_provider
import 'dart:io' show Platform;

import 'package:dea_sdk/dea_sdk.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final support = await getApplicationSupportDirectory();

  DeaSdk.init(
    DeaOptions(
      appId: Platform.isIOS ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_APP_ID',
      requireConsent: true,
      events: const [
        EventKind.down,
        EventKind.move,
        EventKind.up,
        EventKind.cancel,
        EventKind.scroll,
        EventKind.hover,
        EventKind.keyDown,
      ],
      motionRate: 50,
      idleMotionMs: 3000,
      touchMarginMs: 200,
    ),
    appKey: Platform.isIOS ? 'YOUR_IOS_APP_KEY' : 'YOUR_ANDROID_APP_KEY',
    modelDirectory: support,
  );
  runApp(const MyApp());
}

Core options

appId

Type Default Required
String — Yes

The app id DEA issued for this platform's app. DEA registers your Android app and your iOS app separately, so pass the Android id on Android and the iOS id on iOS. See Accounts and keys.

The SDK reads the id to know it is running for a production app. It does not send it to DEA.

requireConsent

Type Default Required
bool true No

When true, nothing is recorded until the user has agreed. See User Consent.

Set it to false only when consent is already established outside the SDK — for example, your app asks during onboarding and calls DeaSdk.init only after the user agrees.

debug

Type Default Required
bool false No

Requests diagnostic output. The published Flutter package carries no log, so in that package this option has no effect. Leave it false.

onLog

Type Default Required
void Function(LogEntry entry)? null No

Called with each SDK log entry. The published Flutter package carries no log, so this is never called there. The SDK never sends a log entry anywhere itself.

Capture options

events

Type Default Required
List<EventKind> The six pointer kinds (pointerKinds) No

The input kinds to capture. Capturing fewer kinds reduces work but also reduces the evidence the score is built on.

Value Captures
EventKind.down A finger, stylus or mouse button goes down
EventKind.move A pointer moves while down
EventKind.up A pointer is lifted
EventKind.cancel The system cancels a pointer
EventKind.scroll Mouse-wheel and trackpad scrolling
EventKind.hover A mouse or stylus moves without touching
EventKind.keyDown A key press your app reports with captureKey
EventKind.keyUp A key release your app reports with captureKey

Key kinds are not in the default list and are never captured automatically. Add them only if your app reports typing — see Report typing. Without them, captureKey does nothing.

The same list also filters what your app forwards with capturePointer: a kind that is not listed is dropped.

motionRate

Type Default Required
int (Hz) 50 No

The accelerometer and gyroscope rate to request. Values below 25 are raised to 25. Once the device has delivered motion data, getSessionInfo().device.sensorRate reports this rate; it reads 0 while no motion data has arrived, and while motion is switched off with setMotion(false).

idleMotionMs

Type Default Required
int (ms) 3000 No

When no one has touched the screen for this long, motion data is recorded at a reduced rate — one reading every idleMotionMs — until the next touch. 0 records every reading.

touchMarginMs

Type Default Required
int (ms) 200 No

Motion data is always kept at the full rate for this long before and after each touch, even while idle.

Note: idleMotionMs and touchMarginMs shape the motion data the score is computed from: each touch is scored with the motion reading taken just before it. Keep the defaults.

Attestation options

These are arguments of DeaSdk.init, not fields of DeaOptions. DEA issues their values when it registers your app, one set per platform:

Value iOS Android
appId (in DeaOptions) Required Required
appKey Required Required
playIntegrityProject Ignored Required

appKey

Type Default Required
String? null Yes, for Attest

The app key DEA issued together with this platform's appId: the Android app's key on Android, the iOS app's key on iOS. The key is public — it identifies your app and ships inside it — and the SDK sends it to DEA as the X-App-Key header when it registers the device key. See Accounts and keys.

Without it, attest() answers Verdict.unsupported (with supported false) without contacting DEA, and its detail says that no appKey was given. Capture and the classification do not need it.

DeaSdk.init(
  const DeaOptions(appId: 'YOUR_APP_ID'),
  appKey: 'YOUR_APP_KEY',
);

registryAppId

Type Default Required
String? null No

An argument of DeaSdk.init. The appId the SDK writes inside the proofs it signs, which DEA accepts only when it names the app behind appKey. Set it to this platform's appId. Left null, proofs carry a built-in development id instead. Attest and getClassification() do not read it; the proof calls on the Ads page do.

playIntegrityProject

Type Default Required
int? null Yes on Android, for Attest. Ignored on iOS

The Google Cloud project number DEA issued for your Android app, together with its appId and appKey. Ignored on iOS. See Attest.

DeaSdk.init(
  const DeaOptions(appId: 'YOUR_APP_ID'),
  appKey: 'YOUR_APP_KEY',
  playIntegrityProject: 123456789012,
);

Model options

The SDK scores with a model built into the package. It can also download a newer model published by DEA and keep it on the device. These are arguments of DeaSdk.init.

modelDirectory

Type Default Required
Directory? (dart:io) null No

Where a downloaded model is kept; the SDK creates dea/models inside it. Pass your app's application-support directory, for example from path_provider's getApplicationSupportDirectory().

Without it there is nowhere to keep a model: no update check runs, and the SDK always scores with the built-in model. With a directory:

  • At start-up, a model kept by an earlier run is loaded before the first input is scored.
  • The SDK asks DEA's model host whether a newer model is published at every start, again when the app returns to the foreground once a day has passed since the last answered check, and when you call checkForModel(). An unchanged answer downloads nothing.
  • A newer model is downloaded, checked, and starts scoring at once; it is kept for later runs. A model older than, or the same as, the one in use is never loaded.

A check runs in the background: it never blocks scoring and never throws. Production apps read DEA's production model channel.

modelUpdates

Type Default Required
bool true No

Set it to false to stop update checks. The kept model is deleted, and the SDK scores with the built-in model. Has no effect without modelDirectory.

modelTimeout

Type Default Required
Duration 30 seconds No

How long one model request may take before it is abandoned.