[{"data":1,"prerenderedAt":138},["ShallowReactive",2],{"doc:\u002Fdocs\u002Fsdks\u002Fflutter":3},{"page":4,"toc":130,"updated":137},{"path":5,"title":6,"seoTitle":7,"description":8,"blocks":9},"\u002Fdocs\u002Fsdks\u002Fflutter","Flutter","Flutter SDK: Native Device Identification in Dart","Identify devices in Flutter apps through the native iOS and Android SDKs, with a typed Dart API and the same verdicts on both platforms.",[10,13,18,23,26,37,39,42,48,50,53,80,83,113,118,121,126],{"type":11,"text":12},"p","`fingerly_flutter` is a plugin over the native [iOS](\u002Fdocs\u002Fsdks\u002Fios) and [Android](\u002Fdocs\u002Fsdks\u002Fandroid) SDKs. Collection happens in native code; Dart gets typed results.",{"type":14,"level":15,"text":16,"id":17},"heading",2,"Requirements","requirements",{"type":19,"items":20},"list",[21,22],"Flutter 3.10 or newer, Dart 3.","iOS 13 and Android 5.0 (API 21) or newer.",{"type":14,"level":15,"text":24,"id":25},"Install","install",{"type":27,"samples":28},"code",[29,33],{"label":30,"lang":31,"code":32},"Terminal","bash","flutter pub add fingerly_flutter",{"label":34,"lang":35,"code":36},"pubspec.yaml","yaml","dependencies:\n  fingerly_flutter: ^0.1.0",{"type":11,"text":38},"The iOS side supports both CocoaPods and Swift Package Manager.",{"type":14,"level":15,"text":40,"id":41},"Identify a device","identify-a-device",{"type":27,"samples":43},[44],{"label":45,"lang":46,"code":47},"lib\u002Ffingerly.dart","dart","import 'package:fingerly_flutter\u002Ffingerly.dart';\n\nfinal fingerly = await Fingerly.load(apiKey: 'fly_pk_us_production_…');\n\nFuture\u003Cvoid> signIn(String email, String password) async {\n  final result = await fingerly.identify(tag: 'sign-in');\n  await api.signIn(email, password, requestId: result.requestId);\n}",{"type":11,"text":49},"Send `requestId` to your backend with the action, and decide there after reading the stored event with a secret key. See [server-side verification](\u002Fdocs\u002Fserver-side-verification).",{"type":14,"level":15,"text":51,"id":52},"API","api",{"type":54,"columns":55,"rows":59},"table",[56,57,58],"Member","Returns","Notes",[60,64,68,72,76],[61,62,63],"`Fingerly.load({required String apiKey, String endpoint = '', ConsentState consent = ConsentState.granted})`","`Future\u003CFingerly>`","An empty endpoint uses the region in the key. The consent state is shared by the whole app, so pass it on every `load`.",[65,66,67],"`setConsent(ConsentState state)`","`Future\u003Cvoid>`","Changes the [consent state](\u002Fdocs\u002Fprivacy-and-consent#consent). `consent` reads it. Until it is `granted`, `identify` and `collect` throw `FingerlyConsentException`.",[69,70,71],"`identify({String? tag, bool submit = true})`","`Future\u003CIdentifyResult>`","`suspectScore` is `int?` and `null` when nothing was scored.",[73,74,75],"`collect()`","`Future\u003CSignalReport>`","Collects without submitting.",[77,78,79],"`Fingerly.nativeVersion()`","`Future\u003CString>`","The native SDK version.",{"type":14,"level":15,"text":81,"id":82},"Verdicts","verdicts",{"type":54,"columns":84,"rows":88},[85,86,87],"Verdict","Platform","What it means",[89,93,96,99,102,105,109],[90,91,92],"`instrumentation`","Both","An instrumentation toolkit is attached to the app.",[94,91,95],"`mitm`","Something is intercepting the app's encrypted traffic.",[97,91,98],"`automation`","A debugger or a test runner is driving the app.",[100,91,101],"`tampering`","The app's code has been hooked or modified.",[103,91,104],"`farm`","The device looks mass-provisioned or freshly reset.",[106,107,108],"`jailbreak`, `simulator`","iOS","Jailbroken device; iOS Simulator.",[110,111,112],"`root`, `emulator`, `appCloner`","Android","Rooted device; emulator; cloning framework.",{"type":27,"samples":114},[115],{"label":116,"lang":46,"code":117},"verdicts.dart","if (result.verdicts.jailbreak.value &&\n    result.verdicts.jailbreak.confidence == Confidence.high) {\n  \u002F\u002F add friction, and let your server make the final decision\n}",{"type":14,"level":15,"text":119,"id":120},"Errors","errors",{"type":27,"samples":122},[123],{"label":124,"lang":46,"code":125},"errors.dart","try {\n  await fingerly.identify();\n} on FingerlyException catch (error) {\n  if (error.status == 401) { \u002F* the key is wrong *\u002F }\n  if (error.status == 402) { \u002F* the organization is not accepting traffic *\u002F }\n}",{"type":127,"tone":128,"text":129},"callout","tip","If you see a missing plugin error after installing, run `flutter clean` and rebuild the app rather than hot reloading.",[131,132,133,134,135,136],{"id":17,"text":16,"level":15},{"id":25,"text":24,"level":15},{"id":41,"text":40,"level":15},{"id":52,"text":51,"level":15},{"id":82,"text":81,"level":15},{"id":120,"text":119,"level":15},"2026-09-17T16:57:29.000Z",1789667797814]