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/breachesandGET /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/v1agent surface and nothing else —openapi/v1.yamlis untouched, so the OpenAPI description is still2.4.1. None of the eleven is returned by an/api/v1endpoint 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 bydpdp_offline_consent_link_api_enabledand 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/posand/offline/ivr— plusPOST /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) addedGET /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-sdkfor Python, andai.dpdpguard:server-sdk) hold your service API key. They mint short-lived data-principal access tokens withbrokerToken()/broker_token(), check consent before your own processing runs, and verify theX-DPDP-Signatureheader 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/contractfollows 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 owninfo.version(2.9.0), separate from the/api/v1path. - 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/serverand@dpdpguard/react-nativeeach declare@dpdpguard/contractby range, resolving to1.6.0.ai.dpdpguard:server-sdkgenerates its client from the current OpenAPI description.ai.dpdpguard:consent-sdk(Android) anddpdpguard-sdk(Python) hand-maintain their models and vendorerror-catalog.jsonandaudit-hash-vectors.jsonfrom the current conformance data.dpdpguard_flutterandDPDPGuardConsent(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.