JavaScript SDK

dpdpstack-js-sdk is the official, typed client for the hosted platform API at getdpdp.net. It wraps every endpoint - consent, erasure, audit, retention, DSR/breach workflows, and Certificates of Erasure - and ships a drop-in consent widget. Zero runtime dependencies; works in Node 18+ and the browser.

Not to be confused with the Python package dpdpstack-python-sdk, which is the local, zero-egress erasure engine. This SDK is a thin HTTP client for the hosted vault and dashboard - see Hosted dashboard.

Install

npm install dpdpstack-js-sdk

Or drop it on a page via CDN (exposes window.dpdpstack):

<script src="https://cdn.jsdelivr.net/npm/dpdpstack-js-sdk/dist/dpdpstack.global.js"></script>

API keys

KeyPrefixUseCapabilities
Secretdpdp_sk_…Server-side onlyFull access
Publishabledpdp_pk_…Safe in the browserRead purposes + record consent only

A publishable key is the only kind that should ever reach a browser; set an origin allowlist on it from the dashboard's API keys page. The certificate verify / registry / public-key endpoints are fully public and need no key.

Quick start (server)

Use a secret key from a backend - never ship it to a browser.

import { DPDPStack, DPDPError } from "dpdpstack-js-sdk";

const dpdp = new DPDPStack({ apiKey: process.env.DPDP_SECRET_KEY }); // dpdp_sk_…

// Record + read consent
await dpdp.grantConsent({ principal_ref: "user_42", purpose: "marketing" });
const status = await dpdp.consentStatus("user_42");

// Issue + verify a Certificate of Erasure
const cert = await dpdp.certificates.issue({ principal_ref: "user_42", purpose: "marketing" });
const { valid } = await dpdp.certificates.verify(cert.certificate_jwt);

try {
  await dpdp.requestErasure({ principal_ref: "user_42" });
} catch (err) {
  if (err instanceof DPDPError) console.error(err.status, err.detail);
}

principal_ref is your opaque user id (an internal id or hash) - never an email, name, or other PII.

Mount a drop-in consent capture widget with a publishable key. Purposes are fetched from the API automatically (or pass them inline).

import { DPDPStack, mountConsentWidget } from "dpdpstack-js-sdk";

const dpdp = new DPDPStack({ apiBase: "/api/v1", apiKey: "dpdp_pk_…" });

const widget = mountConsentWidget("#consent", {
  client: dpdp,
  principalRef: "user_123",
  locale: "en",                 // notices render per-locale, English fallback
  onSave: (receipts) => console.log(receipts),
});

widget.setLocale("hi");         // switch language
widget.destroy();               // remove from the DOM

The same thing via the CDN build:

<div id="consent"></div>
<script src="https://cdn.jsdelivr.net/npm/dpdpstack-js-sdk/dist/dpdpstack.global.js"></script>
<script>
  const dpdp = new dpdpstack.DPDPStack({ apiBase: "/api/v1", apiKey: "dpdp_pk_…" });
  dpdpstack.mountConsentWidget("#consent", { client: dpdp, principalRef: "user_123" });
</script>

Configuration

new DPDPStack({
  apiKey: "dpdp_sk_… | dpdp_pk_…",       // omit for public-only calls
  apiBase: "https://getdpdp.net/api/v1",  // default; use "/api/v1" for a same-origin proxy
  fetch: customFetch,                     // optional (Node < 18, tests)
  headers: { "X-Trace": "…" },            // sent with every request
  credentials: "include",                 // optional fetch credentials mode
});

Every non-2xx response throws a DPDPError with .status, .detail, and .body.

Methods

The SDK mirrors the HTTP API; field names match the wire format exactly.

AreaMethods
ConsentlistPurposes() · createPurpose() · grantConsent() · withdrawConsent() · consentStatus(ref) · listConsentRecords() · recordActivity()
ErasurerequestErasure() · confirmErasure(token)
AuditgetAuditLog({ principal_ref? })
Retentionretention.list() · retention.upsert() · retention.run({ dry_run? })
Certificatescertificates.issue() · certificates.verify(jwt) · certificates.publicKey() · certificates.registry(fp) · certificates.issueFromEvidence()
Evidenceevidence.ingest() · evidence.list({ source?, subject? })
DSRdsr.list() · dsr.create() · dsr.get(id) · dsr.act(id, { action })
Breachesbreaches.list() · breaches.report() · breaches.get(id) · breaches.act(id, { action }) · breaches.notifications(id)
Targetstargets.list() · targets.create() · targets.get(id) · targets.update(id) · targets.remove(id)
Erasure taskserasureTasks.list() · erasureTasks.retry(id)

Public (no key): certificates.verify, certificates.registry, certificates.publicKey, confirmErasure.

Next