Consent Docs

SDK versions

Every version of the browser runtime and the Node.js, Python, Android and iOS packages, what changed in each, and how to upgrade.

Release notes10 min readFor everyone

Newest first, package by package. The current browser runtime and Node.js package is 1.0.7. The current Python package is 1.0.4.

How versions are served#

A released version never changes. What you load decides when you move to a newer one.

You load You get To upgrade
/sdk/v1/loader.js The current runtime Nothing to do
/sdk/v1/runtime/1.0.7/piedap-consent.min.js with integrity That build, byte for byte Change the version and the hash in the tag
piedap-consent-1.0.7.tgz from npm That version of the runtime and the Node.js SDK Install the new file
piedap_consent-1.0.4-py3-none-any.whl from pip That version of the Python SDK Install the new file

Every 1.0 version reads the cookies and local storage written by the earlier ones. Visitors are not asked again because of an upgrade.

Browser runtime and Node.js package#

The browser runtime and the Node.js server SDK ship together as @piedap/consent and share a version number.

1.0.7, 9 October 2026#

Added#

  • Where a DPDP region rule applies, the banner and the preferences name the privacy contact's phone number and who handles grievances, from Project settings. Each number is a tel: link and each email address a mailto: link.
  • The labels contactPhone and grievanceOfficer, in every language the runtime speaks. They can be reworded per form and language; {phone} and {contact} mark where the details go.

Fixed#

  • An answer to a changed form is kept when the page reloads before the answer reaches the API. The banner no longer asks again on that next page.

1.0.6, 9 October 2026#

Added#

  • Age question. On a form set to ask, the banner asks "Are you 18 or older?" before the purposes. A No records the person as a child, refuses everything optional and shows the form's page for a parent or guardian. See DPDP duties for rights and children.
  • eighteenOrOver on the snapshot, on change listeners and in the piedap:consent event.
  • The labels ageQuestion, ageYes, ageNo, parentalConsentNotice and parentalConsentLink, in every language the runtime speaks.
  • The preview draws the age question, and the note for a parent after No.
  • Node.js: ageDeclaration on recordConsent.

Changed#

  • withdraw() sends one call, POST /sdk/v1/consent/{consentId}/withdraw, so the record ends withdrawn with its date. It no longer sends a change of answers alongside.
  • withdraw() closes the banner. On a first visit it records the refusal and then withdraws it.
  • withdraw() rejects with the API's error when the API refuses the withdrawal, and the error event fires. A reason over 500 characters is cut to 500 rather than refused.
  • Every answer and withdrawal is queued in local storage before it is sent, and leaves the queue once the API has it. Writes go with keepalive and an Idempotency-Key. A write cut off by the page closing is sent again on the next page and recorded once.
  • Writes for one form are sent in order. An answer given while the first is on its way changes that record rather than starting a second one.

Fixed#

  • A withdrawal could end as a refused record with no withdrawal date.
  • A withdrawal made while the API could not be reached was lost.

1.0.5, 3 October 2026#

The browser runtime is unchanged apart from its version.

Added#

  • Node.js: checkConsent() asks whether a person allows a purpose now. It waits one second unless you pass timeoutMs, never retries, and returns unavailable with allowed: false when no answer arrives. Types ConsentCheckResult, ConsentCheck, ConsentCheckBasis and ConsentCheckUnavailable, and the constant CHECK_TIMEOUT_MS. See Check consent before you process.
  • Node.js: basis, noticeReference, noticeSha256, expiresAt and lastActivityAt on recordConsent, the same three fields on ConsentRecord, and isSkippedImport() with SKIPPED_IMPORT_CODES. See Bring in consent given earlier.
  • Node.js: capture on recordConsent and updateConsent, captureContext on ConsentRecord, and captureReferenceHash(). See Record consent taken in a branch, by phone or on paper.

Changed#

  • Node.js: an error with no response carries the code TIMEOUT or NETWORK_ERROR.

1.0.4, 25 September 2026#

Added#

  • Choices per partner. On a form that allows it, the preferences show a switch for each partner of a purpose. A purpose with some partners off is marked "Partly on". See Let visitors choose partners.
  • hasConsent(purpose, partner), partnerAllowed(purpose, partner) and whenGranted(purpose, partner) answer for one partner. setConsent(answers, partners) sets partner answers.
  • partners on the snapshot, on change listeners, in the piedap:consent event and in the data layer push.
  • data-partner on held scripts and iframes.
  • A second cookie, piedap_partners, lists the partners that are off. piedap_consent keeps its format, so code that reads it needs no change.
  • The npm package exports parsePartnerCookie, PARTNER_COOKIE_NAME, normalisePartners, partnerKeyFromName and partnerKeys.
  • Node.js: partners on each decision in recordConsent and updateConsent, and granted(purpose, partner).
  • Node.js: records carry test, which is true when a test key wrote them.

Changed#

  • Node.js: parseConsentCookie(consent, partners) and consentFromCookieHeader(header) also read the piedap_partners cookie.
  • The preview reports partner answers when Save my choices is pressed.

1.0.3, 25 September 2026#

Added#

  • Linked identifiers. A record can be found, withdrawn and erased by up to five further identifiers. Set them with the identifiers option or setIdentifiers(). See Identifiers.
  • The npm package exports the LinkedIdentifier and SubjectType types.
  • Node.js: identifiers on recordConsent and updateConsent.
  • Node.js: linkIdentifiers(subjectId, subjectType, identifiers) links identifiers to every record of a person.

Changed#

  • An identifier that needs an identity proof and has none is left out with a warning. If the API still refuses a proof, the answer is recorded without identifiers.

1.0.2, 25 September 2026#

Added#

  • Brand styling. Theme tokens, custom CSS and a custom first layer, with contrast correction. See Style the banner.
  • A preview file, piedap-consent-preview.min.js, is served with each version from this one on.
  • Your own data on records. data-piedap-metadata, the metadata option and setMetadata().
  • The npm package exports the BannerTheme, BannerColours and FormLayout types.
  • Node.js: calls on a person as a whole: findSubject, exportSubject, withdrawSubject, eraseSubject and linkRequest.
  • Node.js: subjectFingerprint(key, identifier, subjectType) recomputes the fingerprint that receipts and webhooks carry.

Changed#

  • The runtime refuses to start with a key that is not a pk_ key. Check that your tag holds a publishable key.
  • Where a DPDP region rule applies, the first layer itemises each purpose with the data it uses and links to Your rights.
  • The language a visitor picks in the banner is remembered for later pages.

1.0.1, 24 September 2026#

Added#

  • A language chooser in the banner and the preferences. It shows where a DPDP region rule applies and the form is published in more than one language.
  • On Shopify, every answer is passed to the Customer Privacy API.
  • Node.js: recordConsent accepts dataPrincipalType and guardian, for consent given by a parent or lawful guardian.

Changed#

  • Where a DPDP region rule applies, the contact for exercising rights is shown. The privacy button stays unless the page has its own data-piedap-open link.
  • TC strings carry the visitor's language as the consent language.

Fixed#

  • The form's Google Consent Mode v2 setting is followed.
  • In update-only mode the runtime no longer changes ads_data_redaction.
  • whenGranted() also resolves when consent arrives without a click: an opt-out default, a region with no form, or a stored answer.
  • Marked tags further down the page are released once the page has been parsed, also when the API cannot be reached.
  • The button on a blocked-content placeholder opens the preferences when the form has no purpose in that category.

1.0.0, 19 September 2026#

Added#

  • The banner and preferences for opt-in, opt-out and notice-only regions, resolved by region rules.
  • Holding tags: type="text/plain" with data-consent, iframes with data-src, and automatic blocking of known hosts with placeholders.
  • window.PiedapConsent, the piedap_consent cookie, the piedap:consent event and the piedap_consent_update data layer push. See Browser runtime methods.
  • Google Consent Mode v2, with signals to Microsoft Advertising, Microsoft Clarity, the Meta Pixel and the TikTok Pixel.
  • IAB TCF and IAB GPP as extensions loaded on demand, the US Privacy string, and Global Privacy Control.
  • Pinned builds with Subresource Integrity, and options in the script URL for Tag Manager.
  • Node.js: ConsentClient for recording, reading, changing and withdrawing consent with a secret key, email double opt-in, activity reports, consent portal links and unsubscribe links. See Node.js client.
  • Node.js: verifyWebhook, identityProof, parseConsentCookie, consentFromCookieHeader and verifyReceipt. See Node.js helpers.

Python package#

The Python SDK, piedap-consent, has its own version numbers. It needs Python 3.9 or later and has no dependencies. See Python client.

1.0.4, 9 October 2026#

Added#

  • age_declaration on record_consent: the person's own answer to "Are you 18 or older?". False records the person as a child. See DPDP duties for rights and children.
  • The model AgeDeclaration, and Consent.age_declaration with the page for a parent shown to a person under 18.

1.0.3, 3 October 2026#

Added#

  • check_consent() asks whether a person allows a purpose now. It waits one second unless you pass timeout, never retries, and returns a ConsentCheck with unavailable set and allowed false when no answer arrives. Models ConsentCheck and CheckBasis, and the constants CHECK_TIMEOUT and MAX_ALSO_KNOWN_AS.
  • basis, notice_reference, notice_sha256, expires_at and last_activity_at on record_consent, the same three fields on Consent, and is_skipped_import() with SKIPPED_IMPORT_CODES.
  • capture on record_consent and update_consent, the models Capture and CaptureContext, Consent.capture_context, and capture_reference_hash().

Changed#

  • ConsentConnectionError.timed_out is True when the wait for a response ran out.

1.0.2, 25 September 2026#

Added#

  • Linked identifiers: Identifier, identifiers on record_consent and update_consent, and link_identifiers.
  • Partner answers: partners on Decision, parse_partner_cookie, and parse_consent_cookie(value, partners) with granted(purpose, partner).
  • test on records.

1.0.1, 24 September 2026#

Added#

  • Consent by a parent or lawful guardian on record_consent.
  • Calls on a person as a whole: find_subject, export_subject, withdraw_subject, erase_subject and link_request.
  • subject_fingerprint.

Fixed#

  • Receipts signed with Ed25519 are read.

1.0.0, 19 September 2026#

Added#

  • ConsentClient with resolve_form, record_consent, get_consent, update_consent, withdraw_consent, verify, start_email_consent, record_activity and consent_portal_link.
  • identity_proof, parse_consent_cookie and verify_webhook.

Mobile packages#

Neither mobile package is published to a public registry. The Android build script writes piedap-consent-android-1.0.1.jar. The iOS Swift package is added by folder and has no version number, so its changes are listed by date. See Record consent in a mobile app.

25 September 2026#

The Android jar keeps the name 1.0.1. Build it again from the current source to get these changes.

Added#

  • Android and iOS: identify records consent under a signed-in person, with a proof from your server. clearIdentity goes back to the device id.

Changed#

  • Android and iOS: a key that does not start with pk_ is refused before any request is made.

24 September 2026, Android 1.0.1#

The same changes were made to the iOS package.

Added#

  • available on the form. It is false where no form targets the place: shouldAsk is then false and granted answers true.
  • The API's error code on a failed request: code on iOS and getCode() on Android.

Changed#

  • An answer to a new form version, to a request to consent again or to another form starts a new record. Before, it changed the old record.
  • Redirects are refused and reported as an error.
  • iOS: the package needs Swift 5.10 or later.

Fixed#

  • After a record is erased on the server, the next answer starts a new record.
  • withdraw clears the device when the server no longer has the record.
  • A notice-only form is recognised by its NOTICE_ONLY consent model.

19 September 2026, Android 1.0.0#

Added#

  • First release of both packages: load the form, record an answer, withdraw, and read granted from the device. See Android SDK and iOS SDK.

Find the version in use#

In the browser:

JavaScript
PiedapConsent.version; // "1.0.7"

From a terminal:

Shell
curl -sI https://console.dpconsent.com/consent/sdk/v1/loader.js \
  | grep -i x-piedap-runtime-version
curl -s https://console.dpconsent.com/consent/sdk/v1/runtime/manifest.json

The manifest gives the current version, its integrity hash and the package files the deployment serves. Every record the browser runtime writes names its version in the record's metadata as sdk.

Upgrade#

Sites on loader.js are upgraded for you. For a pinned tag or an installed package:

Pinned tagHTML
<script
  src="https://console.dpconsent.com/consent/sdk/v1/runtime/1.0.7/piedap-consent.min.js"
  integrity="sha384-…"
  crossorigin="anonymous"
  data-piedap-key="pk_…"
  data-piedap-api="https://console.dpconsent.com/consent"></script>
npmShell
npm install \
https://console.dpconsent.com/consent/sdk/v1/packages/piedap-consent-1.0.7.tgz
pipShell
pip install \
https://console.dpconsent.com/consent/sdk/v1/packages/piedap_consent-1.0.4-py3-none-any.whl

Take the new integrity hash from Install, under Website, Other ways to install, Pinned + SRI, or from the manifest. Change the version and the hash together: a tag with a new version and an old hash does not run.

↑↓ to move, Enter to open