Skip to content
🚨 DPDP Rules 2025: Compliance Deadline 35 weeks awayRead handbook →

Mobile & server SDKs

Install a published DPDP Guard SDK for web, React Native, Flutter, Android, iOS, Node, Python or the JVM, and integrate without a native Convex client.

DPDP Guard publishes eight SDKs plus one shared contract package. Each SDK is a typed client over DPDP Guard’s /api/v1 HTTP surface, so your app or backend never talks to Convex directly and never depends on this repository.

For a benefit-led overview with use cases for each SDK, see the public SDKs page.

Availability

Versions below were verified against each public registry directly on 31 August 2026. The shared contract package is at 1.6.0 (see “Versioning” below). Registries are the source of truth — a few SDK repository READMEs are still stale and describe themselves as unreleased even though their artefact is live.

Platform Package Version Licence Install from
Web / JavaScript @dpdpguard/js 2.1.0 MIT npm
React Native @dpdpguard/react-native 2.0.0 MIT npm
Flutter dpdpguard_flutter 1.1.0 MIT pub.dev
Android (Kotlin) ai.dpdpguard:consent-sdk 1.2.0 MIT Maven Central
iOS / macOS (Swift) DPDPGuardConsent 1.3.0 unspecified Swift Package Manager
Node (server) @dpdpguard/server 2.1.0 MIT npm
Python (server) dpdpguard-sdk 1.1.0 MIT PyPI
JVM — Kotlin/Java (server) ai.dpdpguard:server-sdk 1.1.0 MIT Maven Central
Shared contract @dpdpguard/contract 1.6.0 Apache-2.0 npm

All three mobile client SDKs now support offline consent capture. iOS shipped it first, in 1.3.0 (24 August 2026); Android (1.2.0) and React Native (2.0.0) followed on 29 August. Each captures and signs a consent decision with zero connectivity — using a Secure Enclave key on iOS and a StrongBox/TEE-backed key on Android and React Native — then batches and syncs once connectivity returns. All three implement the identical dpdpcca/2 canonicalisation from conformance/audit-hash-spec.md, so a signature produced on any of them reconciles with the server. This is a breaking (major) release for React Native specifically: @dpdpguard/react-native 2.0.0 now declares react/react-native as peer dependencies and requires React Native’s New Architecture, so it is no longer usable from a plain JS runtime with no RN present.

Python is the newest SDK, published 30 July 2026. dpdpguard-sdk is an official server SDK, hand-maintained to mirror @dpdpguard/server method for method so behaviour — auth modes, idempotency headers, error codes, audit-hash canonicalisation — is identical whichever of the two your service uses. Install it with pip install dpdpguard-sdk or uv add dpdpguard-sdk; the import name is dpdpguard. It needs Python 3.9 or newer, has one runtime dependency (httpx), and ships type hints with a py.typed marker. It supersedes the earlier guidance to generate your own Python client from openapi/v1.yaml; generation remains the documented fallback only for languages without an official SDK.

Six of the SDKs cut a major release on 29 July 2026. None of them changed their own API to do it. @dpdpguard/contract published its first breaking version, 1.0.0, and the versioning policy forces a major bump in every SDK that consumes the contract — so an SDK’s major number tells you which contract generation it belongs to, not how much its own surface moved. Your existing integration code compiles unchanged against the new majors.

The contract’s two releases since then forced nothing. Both are minor and purely additive, and neither changes an existing endpoint, field or error code:

  • 1.1.0 (30 July 2026) added three read-only, flag-gated partner API routes for a fiduciary’s own backend — GET /api/v1/retention/due, GET /api/v1/breaches and GET /api/v1/cross-border/transfers. No SDK calls them.
  • 1.2.0 (31 July 2026) added eleven error codes for DPDP Guard’s separate /mcp/v1 agent surface and nothing else — openapi/v1.yaml is untouched, so the OpenAPI description is still 2.4.1. None of the eleven is returned by an /api/v1 endpoint and no SDK implements that surface, so none of them vendors the new codes.
  • 1.3.0 (4 August 2026) added one new endpoint, POST /api/v1/offline-consent/links (openapi/v1.yaml -> 2.5.0), for a fiduciary’s own server integration (HIS, POS terminal, CBS) to mint an offline/QR consent link without using dpdpbot’s admin page. It is gated by dpdp_offline_consent_link_api_enabled and 404s while off. It does not touch the error catalog or audit-hash canonicalisation, and it is a server-to-server route no SDK here implements yet.
  • 1.4.0 (8 August 2026) added the offline-capture integration surface — three endpoints, POST /api/v1/offline/captures, /offline/pos and /offline/ivr — plus POST /api/v1/consent/verify, the Consent Gate decision endpoint (openapi/v1.yaml -> 2.7.0).
  • 1.5.0 (11 August 2026) added two more Consent Gate observability endpoints (decision log, bypass alerts) plus a documentation-only audit-hash key-versions section (openapi/v1.yaml -> 2.8.0).
  • 1.6.0 (24 August 2026) added GET /api/v1/consent-status, an identifier-resolution endpoint for e-commerce/CMS plugins (openapi/v1.yaml -> 2.9.0).

None of 1.1.0 through 1.6.0 changes an existing endpoint, field or error code, and all eight SDKs were synced to the contract’s 1.5.0 release as a routine, voluntary minor bump on 11–12 August 2026 — the point at which every SDK first landed on the current 1.x contract generation.

Every SDK in the table above is published and installable today — including Flutter, whose earlier publish block (a pub.dev tag-push restriction) has since cleared.

The public and authenticated parts of /api/v1 are both live. The public endpoints (organisation lookup, published notices, banner configuration, anonymous consent capture) need no key at all. The authenticated methods (token brokering, consent gating, server-side DSR/grievance workflows) need a service API key, which is self-serve: generate one from the Integrations page in your dashboard — no request to support, no waiting period.

Install

# Web / any fetch-capable JavaScript runtime
npm install @dpdpguard/js

# React Native
npm install @dpdpguard/react-native

# Node backend
npm install @dpdpguard/server

# Flutter
flutter pub add dpdpguard_flutter

# Python backend
pip install dpdpguard-sdk   # or: uv add dpdpguard-sdk
// Android — app/build.gradle.kts
dependencies {
    implementation("ai.dpdpguard:consent-sdk:1.2.0")
}

// JVM backend — build.gradle.kts
dependencies {
    implementation("ai.dpdpguard:server-sdk:1.1.0")
}
// iOS / macOS — Package.swift
.package(
    url: "https://github.com/dpdp-guard-ai/dpdpguard-ios-sdk.git",
    from: "1.3.0"
)

Client vs. server: where the API key lives

The split between the client and server SDKs is a security boundary, not a packaging convenience.

  • Server SDKs (@dpdpguard/server, dpdpguard-sdk for Python, and ai.dpdpguard:server-sdk) hold your service API key. They mint short-lived data-principal access tokens with brokerToken() / broker_token(), check consent before your own processing runs, and verify the X-DPDP-Signature header on inbound webhooks.
  • Client SDKs (web, React Native, Flutter, Android, iOS) deliberately have no token broker. A service API key is extractable from any app binary, so brokering stays server-side: your backend mints the token and hands it to the app, which passes it to the client via setAccessToken() or the constructor. Audit-hash and webhook-signature helpers are likewise absent from the hybrid client SDKs — both need a server-held HMAC secret.

A typical mobile integration therefore uses two SDKs: a server SDK in your backend to broker the token, and a client SDK in the app to use it.

Typical client usage

import { DpdpGuardClient } from "@dpdpguard/react-native";

const client = new DpdpGuardClient({
  baseUrl: "https://<your-deployment>.convex.site",
});

// Token brokered by your own backend, never by the app.
client.setAccessToken(tokenFromMyBackend);

const org = await client.getOrganization("acme");
const { notices } = await client.getNotices(org.orgId);

const { requests } = await client.listDsrRequests();
await client.createDsrRequest({ organizationId: org.orgId, type: "erasure" });

The Flutter SDK exposes the same surface in Dart, and @dpdpguard/js covers the public, unauthenticated subset only (org lookup, notices, banner config, anonymous consent).

Typical server usage

import {
  DpdpGuardClient,
  hasConsent,
  verifyWebhookSignature,
} from "@dpdpguard/server";

const client = new DpdpGuardClient({
  baseUrl: "https://<your-deployment>.convex.site",
  apiKey: process.env.DPDP_SERVICE_API_KEY,
});

// Mint a short-lived token for a known user, then hand it to your app.
await client.brokerToken(externalId);

// Gate your own processing on a consent decision. `hasConsent` is a pure
// helper over consent records you already hold — it makes no network call.
if (hasConsent(consents, "Marketing")) {
  await addToExport(user);
}

// Verify an inbound webhook before acting on it.
const ok = verifyWebhookSignature(
  webhookSecret,
  rawBody,
  req.headers["x-dpdp-signature"],
);

The Python SDK mirrors the same flow, in snake_case:

import os
from dpdpguard import DpdpGuardClient, has_consent, verify_webhook_signature

client = DpdpGuardClient(
    "https://<your-deployment>.convex.site",
    api_key=os.environ["DPDP_SERVICE_API_KEY"],
)

# Mint a short-lived token for a known user, then hand it to your app.
client.broker_token(external_id)

# Gate your own processing on a consent decision — no network call.
if has_consent(consents, "Marketing"):
    add_to_export(user)

# Retry-safe: the same key returns the original response instead of
# double-writing the request.
client.create_dsr_request(
    organization_id=org_id, type="erasure", idempotency_key=key
)

ok = verify_webhook_signature(webhook_secret, raw_body, signature_header)

DpdpGuardClient is also a context manager, so with DpdpGuardClient(base_url) as client: closes the underlying httpx.Client for you.

Errors

Every non-2xx response raises a DpdpGuardApiError — the same name across the TypeScript, Python, Dart and Kotlin SDKs — carrying the HTTP status and a stable code from the error catalog in @dpdpguard/contract. Branch on the code, not on the free-text message: codes are part of the versioned contract, messages are not.

Versioning

Three axes move independently:

  • Wire API — the major version is in the URL path (/api/v1).
  • Contract package@dpdpguard/contract follows semantic versioning and carries the OpenAPI description, the error catalog, and the audit-hash canonicalisation spec with its golden vectors. Published at 1.6.0; the OpenAPI description inside it carries its own info.version (2.9.0), separate from the /api/v1 path.
  • Each SDK — versioned independently on its own registry.

A breaking contract change (a newly required field, a removal, an error-code change, or any change to audit-hash canonicalisation) forces a major bump in the SDKs that consume it, whether or not that SDK’s own code changed — this is what produced the 29 July 2026 wave of major releases. An audit-hash change additionally requires human sign-off before anything downstream is published, because it affects whether existing consent evidence still reconciles. Every contract release since then — 1.1.0 through 1.6.0 — has been minor and purely additive, and none of them forced an SDK release on its own (see the list above); all eight SDKs were nonetheless synced to 1.5.0 as a routine, voluntary minor bump on 11–12 August 2026.

All eight SDKs are on the current contract generation

As of 31 August 2026, every SDK tracks the 1.x contract generation — the Flutter and iOS lag this page tracked through late July and early August (both were briefly stuck on the older 0.2.0 schemas) closed during the 11–12 August sync:

  • @dpdpguard/js, @dpdpguard/server and @dpdpguard/react-native each declare @dpdpguard/contract by range, resolving to 1.6.0.
  • ai.dpdpguard:server-sdk generates its client from the current OpenAPI description.
  • ai.dpdpguard:consent-sdk (Android) and dpdpguard-sdk (Python) hand-maintain their models and vendor error-catalog.json and audit-hash-vectors.json from the current conformance data.
  • dpdpguard_flutter and DPDPGuardConsent (iOS) both re-vendored their schemas once their publish/versioning gaps cleared in the 11–12 August sync.

Audit-hash canonicalisation and the persisted ConsentRecord shape have not changed since the 1.0.0 breaking release — audit-hash-vectors.json is byte-identical from 0.2.0 through 1.6.0, and in every SDK’s vendored copy — so consent evidence written from any of the eight still reconciles. error-catalog.json has been byte-identical across every /api/v1 code since 1.2.0 appended eleven /mcp/v1-only codes (no SDK here implements that surface), so branching on code works the same on every SDK.

Every SDK that computes an audit hash runs the same golden vectors as a required test, so a hash produced on a phone must match one produced on your server — which is what makes a cross-platform consent audit trail defensible.

Licensing

Seven of the eight SDKs are MIT licensed. The JavaScript, Node, React Native, Flutter and Python repositories carry an MIT LICENSE file — the Python package additionally declares MIT in its PyPI metadata — and the two Maven Central artefacts, ai.dpdpguard:consent-sdk and ai.dpdpguard:server-sdk, declare MIT in the POM published alongside the .aar/.jar, which is what your build actually resolves. @dpdpguard/contract is Apache-2.0.

The iOS SDK (DPDPGuardConsent) is the exception: it declares no licence in its repository or its Package.swift. Treat its terms as unspecified until it does.