Indie & small business

Enterprise DPDP tools want six weeks and a VPC. This wants a script tag.

Versioned notices, unbundled per-purpose consent, and a hash-chained consent ledger with notice-content evidence. Under 5 KB. No database access. Free to start.

5 KB gzipped, asyncFail-open by designSub-ms local checks
Your privacy choicesहिन्दी · auto

We process your personal data for the purposes below. Choose each one separately — you can change or withdraw any of them later, in the same number of steps.

Run the serviceaccount.provisioning · necessary
Product analyticsanalytics.product
Marketing emailmarketing.email
Personalisationpersonalisation
notice signup@v7·receipt hashed to ledger
<5 KBgzipped, zero dependencies
1published locale today
0database connections required
Freeup to 50k consent events a month
Scope

What this covers — and what it does not.

No consent platform can make you “DPDP compliant”, ours included, and anyone selling you that is selling you a problem. This handles the obligations that live at the point of collection and the point of request. The rest stays with you, and your dashboard says so in plain terms. Not sure where you actually stand? Take the free 3-minute self-check.

ScalePulse handles

Wired up the moment the script loads.

  • Versioned itemized notice in Englishs.5
  • Free, specific, unbundled consents.6(1)
  • Withdrawal as easy as giving its.6(4)
  • Consent records and proof of consents.6
  • Blocks gated trackers until consent is granteds.6(6)

Still yours

We can evidence these. We cannot do them for you.

  • Reasonable security safeguardss.8(5)
  • Retention limits and erasure on completions.8(7)
  • Contracts with your processorss.8(2)
  • Breach notification to the Boards.8(6)
  • Actually deleting the data in your systemss.12
  • Rights or grievance request intakes.11–13
  • Translations beyond your published locales.5(3)
Why not build it yourself

You could. It is four weekends and a translation budget.

None of this is conceptually hard. It is just a lot of fiddly, legally-load-bearing detail that has nothing to do with your product.

Versioned reviewed notices

Publish a reviewed notice with a captured policy snapshot or PDF. Every affirmative decision is bound to that exact version and content hash.

Reviewed translations are not available yet, so the product does not claim them.

Unbundled consent, enforced

Per-purpose toggles, nothing pre-ticked, and “Reject all” given exactly the same prominence as “Save choices”. The widget will not let you ship a bundled consent flow even if you try.

s.6(1) and s.6(4), enforced in the component.

Append-only consent ledger

Every grant and withdrawal becomes a hash-chained record carrying the notice version, locale, timestamp, and the affirmative action captured. Evidence is retained immutably and viewable by the tenant owner.

This is the artifact you produce when asked to prove consent.

Rights portal — in build

Requester verification, SLA clocks, and signed webhooks are the next Indie release. They are deliberately not presented as available today.

Until then, fulfil rights requests through your own product support flow.

Fast, and safe when we are not

Under 5 KB gzipped, async, no dependencies, served from the edge. Consent decisions evaluate locally against a cached ledger — no network call in your hot path.

If our edge is down the widget renders from cache and queues.

Nothing to provision

No VPC peering, no database credentials, no collector to deploy, no security review. We never see your data — only pseudonymous references and the consent decisions themselves.

Which is also why signup is instant.

Install

One integration point. Ship the consent layer.

The production script tag gets you a reviewed notice and consent. React helpers and rights webhooks are planned releases, not current dependencies. allows() only stops your own code from calling a tracker — gate the tracker's own tag (the “Block trackers” tab) and sp.js stops it from ever loading at all, not just from being told to be quiet. This is opt-in per script: anything you don't mark this way loads exactly as it always did.

index.html
<script
  src="https://cdn.scalepulse.in/sp.js"
  data-key="pk_live_7f3a…"
  data-endpoint="https://ingest.scalepulse.in/"  // required, not optional
  data-purposes="analytics,marketing.email,personalisation"
  data-lang="auto"        // Eighth Schedule detection, manual switcher
  defer
></script>

// Without data-endpoint, sp.js posts events to {src origin}/v1/e by
// default — the CDN serving this script has no such route, so events
// fail silently with a CORS error in the console.

// Read a decision anywhere. Local, no network call.
<script>
  if (window.ScalePulse.allows('analytics')) {
    initAnalytics();
  }
</script>
For your coding agent

Let Claude Code, Cursor, or Copilot do the integration.

Paste this into your own agent, in your own project. It finds your actual trackers, gates the ones it can, and tells you plainly about the ones it can't — it never guesses your public key or invents a purpose id. Runs entirely in your codebase; we never see it.

View the prompt
You are integrating ScalePulse, a DPDP (India's Digital Personal Data Protection Act) consent widget, into this codebase. Work directly in this project — do not fetch anything from the internet, and do not invent values you were not given.

GOAL
Every visitor sees a consent banner before any optional tracker runs, and every optional tracker (analytics, marketing, advertising — never anything required to operate the site) is blocked until its specific purpose is granted.

STEP 1 — Before changing anything, ask me for:
  - The ScalePulse public key (looks like pk_live_... or pk_test_...). Never invent one or leave a placeholder in code you present as done.
  - The exact purpose ids I declared in my ScalePulse notice (e.g. "analytics", "marketing.email"). Every data-sp-category you write below must match one of these exactly — a typo'd or invented category id means that tracker silently never unblocks, with no error anywhere.

STEP 2 — Add the widget once, site-wide (root layout / base template / <head>), not per-page. data-endpoint is not optional — without it sp.js defaults to POSTing events at {the script's own src origin}/v1/e, which is just the static CDN and has no such route, so every consent event fails silently with a CORS error in the console:
  <script
    src="https://cdn.scalepulse.in/sp.js"
    data-key="THE_KEY_FROM_STEP_1"
    data-endpoint="https://ingest.scalepulse.in/"
    data-purposes="analytics,marketing.email"
    data-lang="auto"
    defer
  ></script>

STEP 3 — Find every third-party analytics/marketing/advertising script in this codebase: Google Analytics (gtag.js / analytics.js), Google Tag Manager, Meta/Facebook Pixel, LinkedIn Insight Tag, Hotjar, TikTok Pixel, or anything similar. Search broadly — a <script src="..."> tag in HTML or a template, a Next.js <Script> component, a Vue/Svelte/Angular component that mounts one conditionally, a WordPress plugin's injected snippet, or application code that calls document.createElement('script') to load one.

STEP 4 — For a static tag with a src, add type="text/plain" and data-sp-category, keep everything else:
  BEFORE: <script src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
  AFTER:  <script type="text/plain" data-sp-category="analytics" src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>

STEP 5 — For an inline block (tracker init code with no src), wrap the whole tag the same way and do not touch the JS inside it:
  BEFORE: <script>fbq('init', 'PIXEL_ID'); fbq('track', 'PageView');</script>
  AFTER:  <script type="text/plain" data-sp-category="marketing.email">fbq('init', 'PIXEL_ID'); fbq('track', 'PageView');</script>

STEP 6 — For a tracker your OWN application code loads programmatically (not a static tag — e.g. a function that injects a script element on some condition, or a framework component that mounts one), do not try to force it into the type="text/plain" pattern. Gate the call itself instead, and re-check on every consent change:
  if (window.ScalePulse?.allows('analytics')) loadGoogleAnalytics();
  window.ScalePulse?.on(() => {
    if (window.ScalePulse.allows('analytics')) loadGoogleAnalytics();
  });

STEP 7 — Add a way for a visitor to change their mind later — s.6(4) requires withdrawal to be as easy as giving consent, and a gated tracker that got granted once otherwise stays granted forever with no way back. Simplest option, a "Privacy choices" or "Cookie preferences" link, typically in the site footer, that reopens the full banner on the current page:
  <a href="#" onclick="window.ScalePulse.show(); return false;">Privacy choices</a>
  If this project already has its own settings/preferences page and a full banner reopen would be out of place there, use window.ScalePulse.set(purposeId, granted) to drive per-purpose toggles directly in that existing UI instead — it records the same kind of affirmative action as the banner. Pair it with window.ScalePulse.on(fn) to keep any toggle UI in sync if consent changes elsewhere (e.g. the visitor used the banner in another tab). Do not build a custom toggle UI unless one already exists to integrate with — the banner is the tested, compliant default.
  If a hosted consent page (a custom domain like privacy.<their-domain>/consent) is configured for this tenant, link to that too — ask me whether one exists rather than guessing a domain.

STEP 8 — Do not touch anything required for the site to function: login, checkout/payments, the framework's own runtime scripts, accessibility tooling, error monitoring you consider operationally necessary. Only gate analytics/marketing/advertising trackers. If you are unsure whether something counts as "necessary," ask me — do not guess.

STEP 9 — Flag rather than silently skip anything you cannot gate this way: a script injected by a CDN/edge/reverse-proxy layer rather than appearing anywhere in this codebase (e.g. an "automatic setup" analytics option, some platform-level Shopify/WordPress built-ins) cannot be intercepted by any client-side consent tool, ours included, because there is no tag in the source to mark. Tell me explicitly which trackers fall into this category instead of leaving them silently unblocked.

STEP 10 — When done, report back: every tracker you found, what you changed for each one, the withdrawal link you added, and anything from step 9 you could not gate and why.

Why type="text/plain" and not something like data-consent="pending": a <script> whose type is not a recognised JavaScript MIME type is never fetched or executed by the browser at all — a denied tracker makes zero network requests. It is not loaded quietly or told to behave; it never runs. Withdrawing consent later cannot un-execute a script that already ran in this page view — it only stops the next one from starting, which is why this re-evaluates fresh on every page load.

The full window.ScalePulse surface

allows() covers the common case. The rest is for building your own UI instead of the banner — a settings page, a footer link, or linking consent to a signed-in account.

MethodReturnsWhat it does
allows(purposeId)booleanSynchronous, local, no network call. Read-only.
set(purposeId, granted)Promise<void>Grants or withdraws one purpose as a real affirmative action — recorded to the ledger the same as a banner click. No-ops on a necessary purpose.
show()voidReopens the full banner for the visitor to choose themselves.
on(fn)() => voidSubscribe to every consent change. Call the returned function to unsubscribe.
withdrawAll()voidWithdraws every non-necessary purpose at once.
identify(subjectToken)voidAttaches an opaque, pre-HMACed token to every event from this point on, to link consent to a known account. Raw user IDs are rejected.
readyPromise<void>Resolves once the widget has finished its initial boot.
Compare

Against the alternatives you are actually weighing.

ScalePulse IndieEnterprise CMPBuild it yourself
Time to liveMinutesWeeks — scoping, onboarding, reviewWeeks of your own time
CostFree, then ₹999/moAnnual contract, sales-ledYour time, plus translation
Reviewed translationsIn buildUsually availableYou commission and maintain them
IntegrationOne script tagTag manager, config, often a CSMYou own every edge case
Database accessNoneOften a collector or VPC peeringN/A
Consent proofHash-chained, exportableYesWhatever you remembered to log
Rights portalIn buildYes, usually a paid moduleAnother project

The middle column is a generic characterisation of enterprise consent platforms, not a claim about any named vendor — their pricing is contract-specific and we are not going to invent numbers for it. Compare against your own quotes.

Pricing

Free until it matters. Then flat.

The free tier is generous because it costs us close to nothing to run at the edge — not as a trap with a cliff at the end.

Indie
Freeforever

For a side project, a launch, or your first hundred users.

  • 1 domain
  • 50,000 consent events / month
  • One published reviewed locale
  • Workspace evidence view
  • Server-metered event allowance
  • Community support
Startup Popular
₹999/ month · $15

When it is a real product with real users and a brand.

  • Planned after the Indie foundation
  • Custom branding and custom domain
  • Signed webhooks and DSR routing
  • Audit-ready exports
Scale
₹4,999/ month · $59

Several products, a team, and someone asking about SLAs.

  • 10 domains
  • 5,000,000 consent events / month
  • Team seats and SSO
  • Sandbox environment
  • Priority SLA
  • Migration help
FAQ

The questions engineers actually ask.

Will this slow down my site?

The script is under 5 KB gzipped, has no dependencies, loads defer, and is served from the edge. It does not block render and it does not touch your critical path.

After the first load, consent decisions are read from a local cache, so allows() is synchronous and sub-millisecond. The size budget is enforced by a CI check that fails our build if it regresses.

Do I need to connect my production database?

No — and you cannot, on this tier. There is no collector, no VPC peering, and no credentials to hand over. We only ever see pseudonymous references and the consent decisions themselves.

That is also the limitation: because we cannot see your data, we cannot scan it for retention overruns or find personal data you forgot about. That is the platform product, and it is a different kind of install.

Does it actually stop Google Analytics or Meta Pixel from running?

Only for scripts you mark that way. Wrap the tracker's own tag as <script type="text/plain" data-sp-category="…"> (the “Block trackers” install tab) and it is never fetched or executed until that purpose is granted — not loaded quietly, not loaded and told to behave, genuinely never requested. A tag manager container only needs its one loader tag gated; whatever it injects afterward inherits that.

Anything you do not mark this way is untouched and loads exactly as it always did — this is opt-in per script, not a blocklist that recognises trackers by name. It also cannot reach a script your CDN or edge provider injects into the page itself rather than your own template (some “automatic setup” analytics options work this way) — there is no tag in your source to mark, and no client-side consent tool, ours included, can intercept that.

Do you support all 22 Eighth Schedule languages?

Not yet. We support the locale you publish today. Reviewed translations are a separate programme because machine-translating legal notices is not a defensible substitute.

The dashboard will show locale coverage once translated notice versions and reviewer sign-off are available. Until then, do not represent the widget as meeting the multi-language requirement.

What happens when a user asks for deletion?

Today, they use your own support or account flow. ScalePulse currently records consent decisions; its verified rights portal and webhook routing are the next Indie release.

Your app does the deleting. We cannot reach your data. Until the portal launches, you must track verification, fulfilment, and response timing yourself.

Are you a Consent Manager registered with the Data Protection Board?

No, and we are careful about this. “Consent Manager” is a defined role under the Act — a registered intermediary through which a Data Principal can give, manage, review, and withdraw consent, subject to registration and eligibility criteria set by the Board.

ScalePulse is a consent management platform: software you, the Data Fiduciary, use to discharge your own obligations. You remain the Data Fiduciary and we act as your Data Processor. If you need a registered Consent Manager, you need a registered entity, and we will say so rather than blur it.

Does installing this make me DPDP compliant?

No. Today it covers versioned notice and consent capture. Rights-request handling, security safeguards, retention, processor contracts, and breach notification remain your obligations.

Security safeguards, retention limits, contracts with your processors, and breach notification remain your obligations. The coverage panel above is the same one in your dashboard, and it is deliberately blunt about the gap.

Free tier · no card

Get it right before the next deploy.

One script tag, a purpose list, and you have defensible consent records from your very next visitor. Everything else can come later.