Piano Consents SDK for Flutter

Piano Consents Flutter SDK provides consent management for Piano products, allowing you to record and persist user consent choices across data processing purposes.

Installation

Add the dependency to your pubspec.yaml:

dependencies:
  piano_consents_flutter: ^1.0.4

Getting Started

Create a PianoConsentConfiguration and pass it to Piano.init:

import 'package:piano_common/piano_common.dart';
import 'package:piano_consents_flutter/piano_consents_flutter.dart';

final piano = await Piano.init(
  endpoint: PianoEndpoint.production,
  aid: '<AID>',
  consentConfig: PianoConsentConfiguration(requireConsent: true),
);

Access the consents manager via piano.consents.

Configuration

PianoConsentConfiguration accepts two optional parameters:

Parameter Type Default Description
requireConsent bool false Whether explicit user consent is required
defaultPurposes Map<PianoProduct, PianoPurpose>? null Custom product-to-purpose mappings (uses built-in defaults when null)
final config = PianoConsentConfiguration(
  requireConsent: true,
  defaultPurposes: {
    PianoProduct.pa: PianoPurpose.audienceMeasurement,
    PianoProduct.dmp: PianoPurpose('CUSTOM'),
  },
);

Default product-to-purpose mappings

Product Purpose
PianoProduct.pa PianoPurpose.audienceMeasurement
PianoProduct.dmp PianoPurpose.advertising
PianoProduct.composer PianoPurpose.contentPersonalisation
PianoProduct.id PianoPurpose.personalRelationship
PianoProduct.vx PianoPurpose.personalRelationship
PianoProduct.esp PianoPurpose.personalRelationship
PianoProduct.socialFlow PianoPurpose.advertising
piano.consents.set(PianoPurpose.audienceMeasurement, PianoConsentMode.optIn);

Optionally specify which products this consent applies to:

piano.consents.set(
  PianoPurpose.audienceMeasurement,
  PianoConsentMode.optIn,
  [PianoProduct.pa],
);

Set the same mode for all purposes

piano.consents.setAll(PianoConsentMode.optOut);

Clear all consents

Resets all consents to the initial (not-acquired) state:

piano.consents.clear();
// Current consent state keyed by purpose
final consentMap = piano.consents.consents;
final mode = consentMap[PianoPurpose.audienceMeasurement]?.mode;
final products = consentMap[PianoPurpose.audienceMeasurement]?.products;

// Current product-to-purpose mapping
final mapping = piano.consents.productsToPurposesMapping;
final purpose = mapping[PianoProduct.pa];
Mode Description
PianoConsentMode.optIn All data processed according to purposes
PianoConsentMode.essential Only essential and mandatory data processed
PianoConsentMode.optOut Only mandatory data processed
PianoConsentMode.custom Fine-grained per-purpose selection
PianoConsentMode.notAcquired Consent not yet collected from the user

Purposes

Four predefined purposes are available:

PianoPurpose.audienceMeasurement   // alias: 'AM'
PianoPurpose.contentPersonalisation // alias: 'CP'
PianoPurpose.advertising           // alias: 'AD'
PianoPurpose.personalRelationship  // alias: 'PR'

Custom purposes

Create a custom purpose by providing a unique alias (max 32 characters, must not conflict with reserved aliases AM, CP, AD, PR, DL):

final custom = PianoPurpose('MY_PURPOSE');
piano.consents.set(custom, PianoConsentMode.optIn, [PianoProduct.pa]);

Products

Constant Alias Description
PianoProduct.pa PA Piano Analytics
PianoProduct.dmp DMP DMP
PianoProduct.composer COMPOSER Piano Composer
PianoProduct.id ID Piano ID
PianoProduct.vx VX Piano VX
PianoProduct.esp ESP ESP
PianoProduct.socialFlow SOCIAL_FLOW Social Flow

Error Handling

try {
  piano.consents.set(PianoPurpose.audienceMeasurement, PianoConsentMode.optIn);
} on StateError catch (e) {
  // requireConsent is false — consent management is disabled
  print(e.message);
} on ArgumentError catch (e) {
  // Invalid mode (notAcquired) or undefined purpose without products
  print(e.message);
}

Consent state is persisted automatically using SharedPreferences and restored on the next app launch.