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 tabWhat it contains
Local ScannerRun 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 SettingsFour 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.

SettingDescription
PositionWhere 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 titleHeading text displayed in the banner (e.g. "We care about your privacy").
Banner descriptionBody text explaining why data is collected. Privacy policy link appended here if configured.
Accept All button textLabel for the primary consent button.
Cookie Settings button textLabel for the secondary button that opens the category preference panel.
Privacy policy linkURL appended to the banner description as a clickable link.
Background colorBanner background. Hex color picker.
Text colorAll banner text. Hex color picker.
Button colorAccept All button background. Also used for toggle-on state and active link colors.
Button text colorText on the Accept All button.
Border radiusCorner rounding in pixels applied to the banner card and buttons.
The live preview at the bottom of the page is a faithful replica of the production banner. Toggle the language switcher in the preview to check translated text before publishing.

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.

CategoryDefaultDescription
EssentialAlways on (locked)Session management, CSRF tokens, authentication. Cannot be disabled by the user.
AnalyticsOffPage view tracking, heatmaps, product analytics (GA4, Mixpanel, etc.).
MarketingOffAdvertising, retargeting, ad conversion tracking (Meta Pixel, Google Ads, etc.).
PerformanceOffCDN 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:

FieldNotes
Purpose keyStable machine identifier. Used in your code to call requestPurpose(). Example: marketing_emails, location_tracking.
Display nameHuman-readable name shown in the prompt. Example: "Marketing Emails".
DescriptionExplains 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 titleOptional override for the prompt heading. Defaults to the display name.
Prompt descriptionOptional 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.

Purposes are independent of cookie categories. A user can accept all cookie categories but still decline a specific purpose. Both states are stored and queryable via the SDK.

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.

1

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 a consent_update event 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.
2

Copy and install the snippet

Platform-specific instructions:

JavaScript / HTML

Paste inside your <head> tag.

HTML
<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.

app/layout.tsx
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.

theme.liquid
<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.

functions.php
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');
3

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:

JavaScript
// 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):

JavaScript
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();
  }
});
4

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.

HTML
<!-- 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>
5

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.

ResponsibilitySDK handlesYou 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 UIYou build
Privacy Settings screen UIYou build
Gating third-party SDK callsYou build
1

Install the SDK

React Native
npm install @theprivacylabs/react-native-consent @react-native-async-storage/async-storage
Flutter
flutter pub add theprivacylabs_consent
2

Initialise

App.tsx (React Native)
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);
main.dart (Flutter)
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
      );
  },
);
3

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.

React Native - check consent status
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,
});
DPDP Act requirements for the banner UI you build: (1) State the purpose of data collection clearly. (2) Provide an Accept All button. (3) Let users customise individual categories. (4) Link to your privacy policy. (5) Optional categories must default to OFF. (6) Withdrawal must be accessible from app settings.
4

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.

PrivacySettings.tsx (React Native)
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>
  );
};
5

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.

React Native
// After login:
await PrivacyLabsConsent.linkIdentity(userEmail, 'login');

// After signup:
await PrivacyLabsConsent.linkIdentity(userEmail, 'signup');
6

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.

React Native - common patterns
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

EventFired when
purpose.grantedUser grants consent for a purpose (banner or layered prompt).
purpose.deniedUser explicitly denies consent for a purpose.
purpose.withdrawnUser withdraws a previously granted consent via preferences or a DSR.
purpose.expiredA consent record passes its retention window and is auto-expired.

Setup

  1. 1Go to Admin > Integration Settings > Consent Settings > Automation > Webhooks. Click Add Webhook.
  2. 2Paste your HTTPS endpoint URL and tick the events to receive.
  3. 3On save, a one-time signing secret is shown. Copy it and store as an environment variable. You cannot retrieve it later.
  4. 4Use the Send test event button to verify your endpoint receives events correctly.

Payload

POST request
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.

Node.js
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')
  );
}
Respond 200 OK within 5 seconds. Longer responses are treated as failures.
Any non-2xx response triggers a retry with exponential backoff.
After 10 consecutive failures the webhook is auto-disabled. Re-enable it once your endpoint is healthy.
Your handler should be idempotent - the same event may be delivered more than once after retries.
HTTPS only. Plain HTTP and self-signed certificates are rejected at save time.

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

  1. 1Go to Automation > Translations. Select the languages to enable from the chip list.
  2. 2Click Generate Translations. The engine translates every banner string from your English source.
  3. 3Open each language row and click Edit to review. Saving promotes the status from auto-translated to reviewed.
  4. 4Toggle Active on the languages you want live. The SDK immediately makes them available in the banner.
If you edit your English banner title, description, or button labels after translations have been generated, existing translations are not updated automatically. Use the Re-translate All button to regenerate from the new English source. Your manual edits will be overwritten.

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