redacto_consent_sdk
Flutter SDK for integrating Redacto consent notices and a self-service Privacy Center into your app.
Installation
flutter pub add redacto_consent_sdk
Requirements
- Dart
>=3.3.0 <4.0.0 - Flutter
>=3.19.0
Architecture
The SDK follows a client-server architecture pattern:
- Your Backend Server acts as a proxy between your Flutter application and Redacto's API, handling token generation and refresh.
- Your Flutter Application uses SDK widgets to display consent notices and collect user choices.
- SDK Widgets fetch consent content, render UI, and submit consent records.
Before You Start
You need three UUIDs from your Redacto Console and a CMS API Key.
Where to Find Your UUIDs
| Value | Where to find it |
|---|---|
| Organisation UUID | Console → Settings → Organization → Copy UUID (or from the URL: /org/{ORG_UUID}/...) |
| Workspace UUID | Console → Settings → Workspaces → Select your workspace → Copy UUID (or from the URL: /org/.../workspace/{WORKSPACE_UUID}/...) |
| Notice UUID | Console → Consent Management → Notices → Click on your notice → Copy UUID (or from the URL: .../notices/{NOTICE_UUID}) |
CMS API Key
Your backend needs a CMS API Key to call the Redacto token API. This key must never appear in frontend code.
Important: You need to obtain your CMS API Key from the Redacto Dashboard. Store this key securely in your environment variables and never expose it to the frontend.
- Go to Console → Settings → API Keys.
- Click Create API Key.
- Copy the key — you will not see it again.
- Store it as an environment variable on your server:
export CMS_API_KEY="your-api-key-here"
Required App Configuration
Store the following values in your app configuration (for example, Dart defines, secure config, or remote config):
| Config Value | Required | Used For |
|---|---|---|
BACKEND_URL |
Yes | Your backend endpoint for consent token and refresh token APIs |
NOTICE_UUID |
Yes (modal flows) | Notice rendered by RedactoNoticeConsent |
ORGANISATION_UUID |
Yes (inline flows) | Loading consent content and token requests |
WORKSPACE_UUID |
Yes (inline flows) | Loading consent content and token requests |
BASE_URL |
No | Override the default Redacto consent API base URL |
How to wire these values:
- Set these values in your app's runtime/build configuration.
- Send
ORGANISATION_UUID,WORKSPACE_UUID, and optionalBASE_URLto your backend token endpoint. - Use returned
accessTokenandrefreshTokenwithRedactoNoticeConsent, or pass UUIDs (and tokens when available) toRedactoNoticeConsentInline.
Components
RedactoNoticeConsent
Modal consent component for initial consent and reconsent flows.
Best for: Initial consent collection, standalone consent flows
Key Characteristics:
- Requires tokens upfront (must be provided before rendering)
- Displays as a modal overlay
- Blocks UI interaction by default
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
noticeId |
String |
Yes | - | Notice UUID |
accessToken |
String |
Yes | - | JWT access token |
refreshToken |
String |
Yes | - | JWT refresh token |
baseUrl |
String? |
No | https://api.redacto.io/consent |
Override consent API base URL |
settings |
ConsentSettings? |
No | - | UI styling overrides |
language |
String |
No | "en" |
Initial language |
blockUI |
bool |
No | true |
Prevents back-dismiss |
onAccept |
VoidCallback |
Yes | - | Called on accept |
onDecline |
VoidCallback |
Yes | - | Called on decline |
onError |
ValueChanged<Object>? |
No | - | Error callback |
applicationId |
String? |
No | - | Application/user-specific UUID |
validateAgainst |
ValidateAgainst |
No | ValidateAgainst.all |
Validation mode |
includeFullyConsentedData |
bool |
No | false |
Include review payload for already-consented users |
reviewModeButtonText |
String? |
No | "Update Consent" UI path |
Custom review CTA text |
onPrivacyCenterTap |
VoidCallback? |
No | - | Called instead of opening the privacy center URL in an external browser; use for in-app Privacy Center navigation |
When onPrivacyCenterTap is set, tapping the privacy center link in the notice routes to your handler (for example, Navigator.push to a screen hosting RedactoPrivacyCenter). See Privacy Center.
RedactoNoticeConsentInline
Embedded consent component for inline form contexts.
Best for: Registration forms, checkout flows, multi-step processes
Key Characteristics:
- Renders inline within your form
- Auto-submits consent when all conditions are met
Auth paths: The inline widget supports two mutually exclusive auth paths — provide either noticeId + accessToken (post-token) OR orgUuid + workspaceUuid + noticeUuid (pre-token: render the widget while you fetch tokens). Params marked No* in the table below are conditionally required: exactly one of the two combos must be provided.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
noticeId |
String? |
No* | - | Notice UUID (post-token path) |
accessToken |
String? |
No* | - | JWT access token (post-token path) |
orgUuid |
String? |
No* | - | Organisation UUID (pre-token path) |
workspaceUuid |
String? |
No* | - | Workspace UUID (pre-token path) |
noticeUuid |
String? |
No* | - | Notice UUID (pre-token path) |
baseUrl |
String? |
No | https://api.redacto.io/consent |
Override consent API base URL |
settings |
ConsentSettings? |
No | - | UI styling overrides |
language |
String |
No | "en" |
Initial language |
onAccept |
VoidCallback? |
No | - | Called after auto-submit |
onDecline |
VoidCallback? |
No | - | Decline callback |
onError |
ValueChanged<Object>? |
No | - | Error callback |
onValidationChange |
ValueChanged<bool>? |
No | - | Emits validation state |
applicationId |
String? |
No | - | Application/user-specific UUID |
validateAgainst |
ValidateAgainst |
No | ValidateAgainst.required |
Validation mode |
includeFullyConsentedData |
bool |
No | false |
Include review payload for already-consented users |
Usage Example
import "package:flutter/material.dart";
import "package:redacto_consent_sdk/redacto_consent_sdk.dart";
class ConsentDemo extends StatelessWidget {
const ConsentDemo({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
builder: (_) => RedactoNoticeConsent(
noticeId: NOTICE_UUID,
accessToken: accessToken,
refreshToken: refreshToken,
validateAgainst: ValidateAgainst.all,
onAccept: () => Navigator.of(context).pop(),
onDecline: () => Navigator.of(context).pop(),
onError: (error) => debugPrint(error.toString()),
),
);
},
child: const Text("Open consent"),
);
}
}
Styling (ConsentSettings)
ConsentSettings supports:
- Base properties:
link,borderRadius,backgroundColor,headingColor,textColor,borderColor,font - Buttons:
button.accept(backgroundColor,textColor)button.decline(backgroundColor,textColor)button.language(backgroundColor,textColor,selectedBackgroundColor,selectedTextColor)
Privacy Center
A self-service Privacy Center widget for managing consents, submitting data subject access requests (DSAR), and tracking activity. Renders as a mobile-first single column (matching React Native): top navbar (page title, email, language selector, theme toggle), page content, bottom tab bar (Consents | Requests | Activities | Receipts), and a "Powered by Redacto" footer. Case details is an internal overlay reached from the Requests tab—not a bottom-tab page.
baseUrl is the consent API base URL (same as notice flows, for example https://api.redacto.io/consent), not a separate privacy center URL.
Import
import "package:redacto_consent_sdk/redacto_consent_sdk.dart";
RedactoPrivacyCenter, PrivacyCenterPage, and related Privacy Center exports are available from the main library entry—no separate import path (unlike React Native's /privacy-center subpath).
Dependencies
Privacy Center features rely on packages bundled as direct SDK dependencies: intl, file_picker, share_plus, open_filex, and path_provider. Receipt download/share and DSAR file upload use the platform share sheet and file picker; follow standard Flutter iOS and Android setup for those plugins. You do not need to add these packages separately when using redacto_consent_sdk.
RedactoPrivacyCenter
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
baseUrl |
String |
Yes | - | Consent API base URL for Privacy Center requests |
accessToken |
String |
Yes | - | JWT access token |
refreshToken |
String |
Yes | - | JWT refresh token |
onError |
void Function(Object error) |
Yes | - | Error handler |
theme |
Brightness |
No | Brightness.light |
Visual theme (Brightness.light or Brightness.dark); user can toggle from the navbar |
initialPage |
PrivacyCenterPage |
No | PrivacyCenterPage.consentManager |
Initial tab: consentManager, form, activity, or receipt. Do not use caseDetails—it is internal and opened from the Requests list |
language |
String |
No | "en" |
Initial language code (for example en, hi); drives UI strings and the API language query param; user can change from the navbar |
contactEmail |
String? |
No | - | User contact email for case history and forms when the JWT does not embed it (common with backend-issued consent tokens) |
onBack |
VoidCallback? |
No | - | When set, the navbar shows a back arrow that invokes this callback (for example Navigator.of(context).pop()) |
Usage Example
import "package:flutter/material.dart";
import "package:redacto_consent_sdk/redacto_consent_sdk.dart";
class PrivacyCenterScreen extends StatelessWidget {
const PrivacyCenterScreen({
super.key,
required this.accessToken,
required this.refreshToken,
this.userEmail,
});
final String accessToken;
final String refreshToken;
final String? userEmail;
@override
Widget build(BuildContext context) {
return Scaffold(
body: RedactoPrivacyCenter(
baseUrl: BASE_URL,
accessToken: accessToken,
refreshToken: refreshToken,
contactEmail: userEmail,
theme: Brightness.light,
initialPage: PrivacyCenterPage.consentManager,
onBack: () => Navigator.of(context).pop(),
onError: (error) => debugPrint(error.toString()),
),
);
}
}
Headless API
For fully custom UIs, the package also exports headless building blocks on top of the same backend:
PrivacyCenterApiandPrivacyCenterAuthManager— API client and token refreshPrivacyCenterPage,PCScope,PcTheme— navigation scope and theming- Models from
privacy_center_models.dart(cases, consents, activities, receipts, etc.)
See the example app for a runnable integration.
Localization
Notice consent
- Set initial locale with
languageonRedactoNoticeConsentorRedactoNoticeConsentInline. - UI labels and text content are loaded from notice translations.
- Users can switch languages via the built-in selector when translations are available.
Privacy Center
- Set initial locale with
languageonRedactoPrivacyCenter. - Privacy Center ships built-in UI strings for many locales; users switch language from the navbar selector.
languagedrives both UI strings and API-backed labels where applicable (request types, statuses, purposes).- Date and relative-time formatting uses
intlinternally; the SDK initializes locale data as needed—no extra app setup required.
Troubleshooting
- No modal data: verify
noticeId,accessToken, andrefreshToken. - Inline submit not firing: ensure required selections are complete and
onValidationChangebecomestrue. - HTTP errors: check backend token generation and
baseUrlvalue. - Empty case history or case API errors: pass
contactEmailwhen your JWT does not include the user's email. - Wrong language on case details after toggle: the SDK refetches case data on language change; verify tokens are valid and
baseUrlis correct. - Receipt download or export failures: check platform file and share permissions (iOS share sheet, Android storage where applicable).
Development
cd packages/consent-sdk-flutter
flutter pub get
dart analyze
flutter test