Integration Settings
The first module in the Admin Dashboard. This is where you configure the consent banner, install the SDK on your website and mobile app, set up translations for Indian regional languages, and wire up webhooks for real-time consent events.
Navigate to: Admin Dashboard > Integration Settings
Page structure
Integration Settings has two top-level tabs:
| Top tab | What it contains |
|---|---|
| Local Scanner | Run a self-hosted data-discovery (PII) scan on your own machine and upload the report. Powers the Data & Audit module; the bundled Runner fulfils DSR data fetches locally. |
| Consent Settings | Four inner tabs: Appearance, Consent Data, Integration Settings, Automation. All banner configuration lives here. |
Tab: Local Scanner
Top-level tab under Integration Settings
Download the scanner from this tab and run a data-discovery (PII) scan on your own machine - see the Data Discovery page for the full download-and-run walkthrough, supported sources, and read-only credentials. You upload the report here. The same download also includes the Runner, which fetches a data subject's records locally when an operator opens a DSR - so raw data never leaves your network.
Supported sources: PostgreSQL / Supabase, MySQL, Microsoft SQL Server, MongoDB, DynamoDB, Firebase, and a folder of files.
Consent Settings > Appearance
Inner tab under Consent Settings
Controls the visual appearance of the consent banner. Changes here update the live preview below the tab in real time before you save.
| Setting | Description |
|---|---|
| Position | Where the banner renders on screen: bottom, top, bottom-left, bottom-right. Corner variants render as a card; full-width variants span the entire screen edge. |
| Banner title | Heading text displayed in the banner (e.g. "We care about your privacy"). |
| Banner description | Body text explaining why data is collected. Privacy policy link appended here if configured. |
| Accept All button text | Label for the primary consent button. |
| Cookie Settings button text | Label for the secondary button that opens the category preference panel. |
| Privacy policy link | URL appended to the banner description as a clickable link. |
| Background color | Banner background. Hex color picker. |
| Text color | All banner text. Hex color picker. |
| Button color | Accept All button background. Also used for toggle-on state and active link colors. |
| Button text color | Text on the Accept All button. |
| Border radius | Corner rounding in pixels applied to the banner card and buttons. |
Consent Settings > Consent Data
Inner tab under Consent Settings
Two sub-sections: cookie categories (the broad consent toggles shown to all users) and layered consent purposes (contextual prompts shown at the exact point of data collection, as required by DPDP Act §6).
Cookie categories
Enable or disable the four standard categories. Each enabled category appears as a toggle in the consent banner's settings panel.
| Category | Default | Description |
|---|---|---|
| Essential | Always on (locked) | Session management, CSRF tokens, authentication. Cannot be disabled by the user. |
| Analytics | Off | Page view tracking, heatmaps, product analytics (GA4, Mixpanel, etc.). |
| Marketing | Off | Advertising, retargeting, ad conversion tracking (Meta Pixel, Google Ads, etc.). |
| Performance | Off | CDN caching, speed optimisation, infrastructure monitoring cookies. |
Layered consent purposes
DPDP Act §6 requires consent to be specific, informed, and collected at the point of use. A broad "accept analytics" toggle covers your tracking cookies, but if you also send marketing emails you need separate, explicit consent at the moment you ask for the email address. This is layered consent.
To enable: turn on Enable Layered Consent at the top of the Consent Data tab, then add one or more purposes. Each purpose has:
| Field | Notes |
|---|---|
| Purpose key | Stable machine identifier. Used in your code to call requestPurpose(). Example: marketing_emails, location_tracking. |
| Display name | Human-readable name shown in the prompt. Example: "Marketing Emails". |
| Description | Explains what data is collected and why. Displayed in the prompt body. |
| Legal basis | "Consent" shows Allow/Decline buttons. "Legitimate interest" shows a "Got it" acknowledgement notice instead. |
| Prompt title | Optional override for the prompt heading. Defaults to the display name. |
| Prompt description | Optional override for the prompt body. Defaults to the description. |
Below the purpose list, a live Prompt Preview lets you select any active purpose and see exactly how its prompt will look in three placements: inline (next to the triggering element), modal (blocking overlay), and toast (corner notification). Preview colors follow your Appearance tab settings.
Consent Settings > Integration Settings
Inner tab under Consent Settings. Two sections: Web Integration and Mobile SDK.
Web Integration
Supported platforms: JavaScript (vanilla HTML), Next.js, Shopify, WordPress. Select your platform to get the correct snippet.
Select your platform and configure options
Two options available in this step:
- Google Consent Mode v2: When enabled, the SDK calls
gtag('consent', 'update', ...)and pushes aconsent_updateevent to the GTM dataLayer whenever consent changes. Requires GTM already loaded on the page. - Page filtering: Restrict which pages show the banner. Enter comma-separated paths in "Show only on" (e.g.
/,/pricing) or "Hide on" (e.g./dashboard,/app). The two fields are mutually exclusive. A "Hide floating icon after consent" checkbox also available.
Copy and install the snippet
Platform-specific instructions:
JavaScript / HTML
Paste inside your <head> tag.
<script src="https://theprivacylabs.com/sdk/consent-banner.js" data-org="YOUR_ORG_ID" async ></script>
Next.js (App Router)
Add to your root layout.tsx using the next/script component. Strategy must be afterInteractive.
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Script
src="https://theprivacylabs.com/sdk/consent-banner.js"
data-org="YOUR_ORG_ID"
strategy="afterInteractive"
/>
</body>
</html>
);
}Shopify
Online Store > Themes > Edit code > Open theme.liquid. Paste before the closing </head> tag.
<script src="https://theprivacylabs.com/sdk/consent-banner.js" data-org="YOUR_ORG_ID" async ></script>
WordPress
Add to your theme's functions.php, or use a plugin like Code Snippets.
function add_privacylabs_consent() { ?>
<script
src="https://theprivacylabs.com/sdk/consent-banner.js"
data-org="YOUR_ORG_ID"
async
></script>
<?php }
add_action('wp_head', 'add_privacylabs_consent');Wire up layered consent (if enabled)
This step only appears if you have enabled Layered Consent and added active purposes in the Consent Data tab. The dashboard generates the exact snippet for your platform and your purpose keys. General pattern:
// At the point of data collection (e.g. before a form submits):
DPDPConsent.requestPurpose('marketing_emails', { context: 'lead_form' })
.then(function(granted) {
if (granted) {
submitLead(); // User said yes - collect the data
}
// If not granted, do not collect.
});To listen for consent changes (e.g. a user withdraws later):
window.addEventListener('dpdp:purpose-status', function(e) {
// e.detail.purposeKey - the purpose that changed
// e.detail.status - 'granted' | 'declined' | 'already_granted'
if (e.detail.purposeKey === 'analytics_collection'
&& e.detail.status === 'withdrawn') {
stopAnalytics();
}
});Block third-party scripts until consent
For any script tag you want gated by category consent, settype="text/plain"and add adata-consent-categoryattribute. The SDK replaces the type withtext/javascriptonly after the user consents to that category.
<!-- Google Analytics - fires only after analytics consent -->
<script
type="text/plain"
data-consent-category="analytics"
src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
></script>
<!-- Meta Pixel - fires only after marketing consent -->
<script
type="text/plain"
data-consent-category="marketing"
>
fbq('init', 'YOUR_PIXEL_ID');
fbq('track', 'PageView');
</script>Verify installation
Enter your website URL in the verification box and click Test. The dashboard checks whether the SDK script tag is present on the live page and reports back. You can also test manually: open an incognito window, visit your site, and confirm the banner appears. If it does not, check that Banner enabled is on in the Appearance tab, and that the data-org value matches your organisation ID (visible in the Integration Settings tab header).
Mobile SDK
There is no mobile banner
On web, the SDK renders the entire banner UI automatically. On mobile, it does not. The mobile SDK handles consent state management and server sync only. You are responsible for building your own consent banner UI (a bottom sheet, modal, or screen) and a Privacy Settings screen that lets users change their preferences later. The SDK provides the data layer; your UI calls into it.
| Responsibility | SDK handles | You build |
|---|---|---|
| Consent state management | ||
| Sync consent to Privacy Labs server | ||
| Cross-device consent sync (via linkIdentity) | ||
| Category names and descriptions (localised) | ||
| Withdrawal logic | ||
| Consent banner / bottom sheet UI | You build | |
| Privacy Settings screen UI | You build | |
| Gating third-party SDK calls | You build |
Install the SDK
npm install @theprivacylabs/react-native-consent @react-native-async-storage/async-storage
flutter pub add theprivacylabs_consent
Initialise
import { PrivacyLabsConsent } from '@theprivacylabs/react-native-consent';
import AsyncStorage from '@react-native-async-storage/async-storage';
PrivacyLabsConsent.init({
orgId: 'YOUR_ORG_ID',
onConsentChange: (consent) => {
if (consent.preferences.analytics) Analytics.enable();
else Analytics.disable();
},
}, AsyncStorage);import 'package:theprivacylabs_consent/theprivacylabs_consent.dart';
await PrivacyLabsConsent.init(
orgId: 'YOUR_ORG_ID',
onConsentChange: (consent) async {
await FirebaseAnalytics.instance
.setAnalyticsCollectionEnabled(
consent.preferences['analytics'] ?? false
);
},
);Build your consent banner UI
On first app launch, check whether consent has been given. If not, show your custom consent banner (a Modal, BottomSheet, or full screen). Call the SDK to record the user's choice.
const status = await PrivacyLabsConsent.getConsentStatus();
if (!status?.hasConsent) {
// Show your consent banner UI
setShowBanner(true);
}
// In your banner's "Accept All" handler:
await PrivacyLabsConsent.acceptAll();
// In your banner's "Save preferences" handler:
await PrivacyLabsConsent.setConsent({
analytics: true,
marketing: false,
});Build a Privacy Settings screen
Required by DPDP Act. Link to this screen from your app's Settings. Use useConsentCategories(locale) to get localised category names and descriptions.
import { useConsent, useConsentCategories } from '@theprivacylabs/react-native-consent';
const PrivacySettings = () => {
const { consent, setConsent, acceptAll, withdrawConsent } = useConsent();
const { categories } = useConsentCategories('en');
return (
<ScrollView>
{categories.map(cat => (
<Switch
key={cat.id}
value={consent?.preferences[cat.id] ?? false}
disabled={cat.required}
onValueChange={(v) => setConsent({ [cat.id]: v })}
label={cat.name}
/>
))}
<Button title="Accept All" onPress={acceptAll} />
<Button title="Withdraw Consent" onPress={withdrawConsent} />
</ScrollView>
);
};Link identity after login
Call linkIdentity() after a user logs in or signs up. This ties consent records to a known user and enables cross-device sync.
// After login: await PrivacyLabsConsent.linkIdentity(userEmail, 'login'); // After signup: await PrivacyLabsConsent.linkIdentity(userEmail, 'signup');
Gate third-party SDKs
Mobile SDKs are compiled into your binary and cannot be blocked at runtime the way web scripts can. Instead, use theonConsentChangecallback to enable/disable data collection in each SDK.
onConsentChange: async (state) => {
// Firebase Analytics
await analytics()
.setAnalyticsCollectionEnabled(state.preferences.analytics);
// Mixpanel
state.preferences.analytics
? mixpanel.optInTracking()
: mixpanel.optOutTracking();
// Adjust
Adjust.setEnabled(state.preferences.marketing);
// AppsFlyer
appsFlyer.stop(!state.preferences.marketing, () => {});
}Mobile SDK API reference
PrivacyLabsConsent.init(config, storage?)
Initialise the SDK. Must be called before any other method. config.orgId is required.
PrivacyLabsConsent.getConsentStatus()
Returns the current consent state or null if no consent has been given yet.
PrivacyLabsConsent.acceptAll()
Accept all categories and sync to server.
PrivacyLabsConsent.setConsent(preferences)
Set individual category preferences. Example: { analytics: true, marketing: false }.
PrivacyLabsConsent.withdrawConsent()
Withdraw all consent. Clears local state and records withdrawal to server.
PrivacyLabsConsent.hasConsent(category)
Check a specific category. Returns boolean.
PrivacyLabsConsent.linkIdentity(email, event)
Link a user identity for cross-device sync. event is "login" or "signup".
PrivacyLabsConsent.requestPurpose(key, options?)
Show a layered consent prompt for a specific purpose. Returns boolean (granted or not).
useConsent() - React Native hook
Returns { consent, setConsent, acceptAll, withdrawConsent }.
useConsentCategories(locale) - React Native hook
Returns { categories } with localised names and descriptions.
Consent Settings > Automation
Inner tab under Consent Settings. Two sections: Webhooks and Translations.
Webhooks
Webhooks push consent lifecycle events to your backend the moment they happen. Use them to keep CRMs, analytics pipelines, and support tools in sync without polling.
Events
| Event | Fired when |
|---|---|
| purpose.granted | User grants consent for a purpose (banner or layered prompt). |
| purpose.denied | User explicitly denies consent for a purpose. |
| purpose.withdrawn | User withdraws a previously granted consent via preferences or a DSR. |
| purpose.expired | A consent record passes its retention window and is auto-expired. |
Setup
- 1Go to Admin > Integration Settings > Consent Settings > Automation > Webhooks. Click Add Webhook.
- 2Paste your HTTPS endpoint URL and tick the events to receive.
- 3On save, a one-time signing secret is shown. Copy it and store as an environment variable. You cannot retrieve it later.
- 4Use the Send test event button to verify your endpoint receives events correctly.
Payload
POST https://your-endpoint.com/privacylabs-webhook
Content-Type: application/json
X-PrivacyLabs-Event: purpose.granted
X-PrivacyLabs-Timestamp: 1714915200
X-PrivacyLabs-Signature: sha256=<hex-hmac-sha256>
{
"event": "purpose.granted",
"timestamp": 1714915200,
"data": {
"purposeKey": "marketing_emails",
"sessionId": "sess_...",
"platform": "web",
"occurredAt": "2026-01-15T10:22:33.123Z"
}
}Signature verification
Compute HMAC-SHA256 over timestamp.rawBody using your signing secret. Compare against the hex value after sha256= in the signature header. Use constant-time comparison and reject requests older than 5 minutes to prevent replay attacks.
import crypto from 'crypto';
function verifyWebhook(rawBody, headers, secret) {
const timestamp = headers['x-privacylabs-timestamp'];
const received = headers['x-privacylabs-signature'].replace('sha256=', '');
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
const ageSec = (Date.now() / 1000) - Number(timestamp);
if (ageSec > 300) return false; // 5-minute replay window
return crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(received, 'hex')
);
}Translations
The DPDP Act requires consent notices to be available in a language the user understands (Eighth Schedule of the Constitution covers 22 Indian languages). You write the banner copy once in English; the platform translates it into whichever languages you enable.
How the language switcher works: When translations are enabled, a small language picker appears inside the banner. The user manually selects their preferred language from the available options. The banner does not auto-detect the browser locale or attempt geo-IP detection. The available languages shown are only those that have been enabled by you in the Automation tab.
Translation workflow
- 1Go to Automation > Translations. Select the languages to enable from the chip list.
- 2Click Generate Translations. The engine translates every banner string from your English source.
- 3Open each language row and click Edit to review. Saving promotes the status from auto-translated to reviewed.
- 4Toggle Active on the languages you want live. The SDK immediately makes them available in the banner.
What gets translated
All visible banner strings: title, description, Accept All button, Cookie Settings button, Save Preferences button, Withdraw Consent link, Privacy Policy link, and the four standard category names with their descriptions. Purpose names and descriptions (if layered consent is enabled) are translated separately at the purpose level.
Next up
With the banner deployed, run your first data-discovery scan and upload the report so your data map, DSR automation, and the auto-generated privacy policy can work.
Data Discovery