Other events
The webhook events for forms, region rules, anchors, scans, breaches, legal holds, usage and overdue processor tasks, with examples.
Ten webhook events report changes to your set-up, your evidence, your breaches and your processors. Each arrives in the envelope described in Webhook format. In all of them the envelope's test is false.
Events#
form.published#
Sent when
A form version is published. Refresh anything you cache from the form.
Payload
Field in data |
Type | Description |
|---|---|---|
formId |
UUID | The form's id. |
formKey |
string | The form's key. |
name |
string | The form's name. |
version |
integer | The version that is now live. |
contentHash |
string | The hash of that version's content. |
publishedOn |
time | When it was published. |
requiresReconsent |
boolean | true when the change is material, so returning visitors are asked again. |
materialChanges |
array of strings | A description of each material change. Empty when there is none. |
Example
{
"id": "2d9a6c4f-0b7e-4a13-8f5c-e1b3d7a9c605",
"type": "form.published",
"createdOn": "2026-09-24T10:12:03.412Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"formId": "0b9c6f0e-6a55-4c1e-9d0a-2f6f0f4f7a11",
"formKey": "kalpa-account",
"name": "Account messages",
"version": 4,
"contentHash": "e41a07bc…",
"publishedOn": "2026-09-24T10:12:03.000Z",
"requiresReconsent": true,
"materialChanges": ["Added purpose “Class reminders by WhatsApp”"]
}
}region.rule.changed#
Sent when
A region rule is created, changed or deleted. Refresh any cached answer to "which form applies here".
Payload
Field in data |
Type | Description |
|---|---|---|
change |
string | created, updated or deleted. |
ruleId |
UUID | The rule's id. |
name |
string | The rule's name. |
formId |
UUID | The form the rule serves. |
scope |
string | GLOBAL, CONTINENT, COUNTRY or SUBDIVISION. |
lawCode |
string or null |
The law the rule applies, such as DPDP. |
enabled |
boolean | Whether the rule is in use. |
Example
{
"id": "c8e03b5d-4a1f-4967-b2e8-0d6f9a3c7e41",
"type": "region.rule.changed",
"createdOn": "2026-09-24T10:12:03.412Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"change": "updated",
"ruleId": "5f2c8a1e-9d34-4b70-a6c2-7e0b3d5f1a98",
"name": "India",
"formId": "0b9c6f0e-6a55-4c1e-9d0a-2f6f0f4f7a11",
"scope": "COUNTRY",
"lawCode": "DPDP",
"enabled": true
}
}evidence.anchored#
Sent when
A day's consent events are sealed under one signed root. Store these events: together they are a copy of the anchors that the deployment cannot later change.
Payload
Field in data |
Type | Description |
|---|---|---|
statement.specification |
string | piedap-evidence-anchor/1.1. Anchors made before 1.1 carry piedap-evidence-anchor/1.0. |
statement.projectId |
UUID | Your project. |
statement.periodStart, statement.periodEnd |
time | The day the anchor covers. |
statement.eventCount |
integer | How many consent events it seals. |
statement.merkleRoot |
string | The root that every event of the day is included under. |
statement.previousAnchorHash |
string | The hash of the anchor before this one. |
statement.sealedEventTypes |
array of strings | The event types the root was built from. From 1.1 only. |
anchorHash |
string | The hash of the statement. |
signature |
string | The signature over the statement. |
algorithm |
string | The signature algorithm, Ed25519. |
signingKeyId |
string | The signing key, matched against kid in GET /keys. |
Example
{
"id": "91b4e7a2-5c0d-4f38-9e6b-a2d1c8f03b57",
"type": "evidence.anchored",
"createdOn": "2026-09-25T00:15:02.731Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"statement": {
"specification": "piedap-evidence-anchor/1.1",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"periodStart": "2026-09-24T00:00:00.000Z",
"periodEnd": "2026-09-25T00:00:00.000Z",
"eventCount": 1284,
"merkleRoot": "7a0c3e…",
"previousAnchorHash": "d92f18…",
"sealedEventTypes": ["CREATED", "UPDATED", "WITHDRAWN",
"RENEWED", "EXPIRED", "ERASED", "LINKED"]
},
"anchorHash": "3be6a4…",
"signature": "kq3n…",
"algorithm": "Ed25519",
"signingKeyId": "…"
}
}scan.changes_detected#
Sent when
A cookie scan finds something the previous scan did not. The first scan of a project sends nothing.
Payload
Field in data |
Type | Description |
|---|---|---|
scanId |
UUID | The scan that found the changes. |
url |
string | The address that was scanned. |
trigger |
string | MANUAL or SCHEDULED. |
finishedOn |
time | When the scan finished. |
newItems |
array of strings | Cookies, storage keys and hosts not seen before, written as kind:name. |
newViolations |
array of strings | Items newly set before the visitor answered, written the same way. |
comparedWithScanId |
UUID | The earlier scan this one was compared with. |
Example
{
"id": "f03c9d6b-8a2e-4175-b4f0-6c9e2a7d1b38",
"type": "scan.changes_detected",
"createdOn": "2026-09-24T03:10:42.905Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"scanId": "8d1f5a3c-2e7b-4c90-a5d4-f6b0e9c3a172",
"url": "https://www.example.in/",
"trigger": "SCHEDULED",
"finishedOn": "2026-09-24T03:10:42.000Z",
"newItems": ["cookie:_ga", "host:analytics.example.com"],
"newViolations": ["cookie:_ga"],
"comparedWithScanId": "1c6e9b4d-7f30-4a82-9b15-d3a8c0e5f746"
}
}breach.report_due#
Sent when
An open breach has its report to the Data Protection Board due within 12 hours. The event is sent once for each breach.
Payload
Field in data |
Type | Description |
|---|---|---|
breachId |
UUID | The breach record. |
title |
string | Its title in the console. |
awareOn |
time | When your team became aware of the breach. |
boardReportDue |
time | The deadline for the report to the Board. |
pending |
array of strings | The steps not yet recorded: BOARD_INITIAL_NOTICE, PEOPLE_NOTICE and BOARD_REPORT. |
Example
{
"id": "5a8d2f7c-1e94-4b06-8c3a-9f7b4e0d6c21",
"type": "breach.report_due",
"createdOn": "2026-09-24T16:30:00.118Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"breachId": "b6c0e4a9-3d75-4f12-a8e1-2c9d7f5b0a63",
"title": "Support mailbox export sent to the wrong vendor",
"awareOn": "2026-09-22T04:30:00.000Z",
"boardReportDue": "2026-09-25T04:30:00.000Z",
"pending": ["PEOPLE_NOTICE", "BOARD_REPORT"]
}
}breach.people_notice#
Sent when
Someone chose Send to your systems on a breach in the register. It is sent each time, to every enabled endpoint that receives it. If none does, the console refuses with NO_ENDPOINT and records nothing. The product sends no email or SMS: your systems send the notice to each affected person, through their account or the contact they registered with you.
Payload
Field in data |
Type | Description |
|---|---|---|
breachId |
UUID | The breach record. |
title |
string | Its title in the console. |
awareOn |
time | When your team became aware of the breach. |
occurredOn |
time or null | When it happened, if recorded. |
affectedPeople |
integer or null | The people affected, if recorded. |
method |
string or null | How your systems tell people, as recorded on the breach. |
noticeText |
string | The notice to each affected person, as Copy notice gives it. Paragraphs are separated by a blank line. |
noticeSha256 |
string | The SHA-256 of noticeText, in lower-case hex. The audit log records it with the action. |
sentOn |
time | When the notice was sent to your systems. |
Example
{
"id": "8c2e5f1a-7b3d-4e90-a6c4-1d9f0b7e3a52",
"type": "breach.people_notice",
"createdOn": "2026-09-22T09:40:12.551Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"breachId": "b6c0e4a9-3d75-4f12-a8e1-2c9d7f5b0a63",
"title": "Support mailbox export sent to the wrong vendor",
"awareOn": "2026-09-22T04:30:00.000Z",
"occurredOn": "2026-09-21T18:00:00.000Z",
"affectedPeople": 1240,
"method": "SMS to the registered number of each customer",
"noticeText": "Kaveri Stores is writing to tell you about a…",
"noticeSha256": "9f2c4e7a1b3d5f6082a4c6e8f0b2d4f6…",
"sentOn": "2026-09-22T09:40:12.548Z"
}
}usage.threshold_reached#
Sent when
The live records made this month cross 80% of your project's monthly limit, and again at 100%. Each threshold is sent once a month. Consent is still recorded above the limit.
Payload
Field in data |
Type | Description |
|---|---|---|
month |
string | The calendar month in UTC, such as 2026-09. |
records |
integer | Live consent records made this month. |
impressions |
integer | Times a form was shown this month. |
limit |
integer | The project's monthly record limit. |
percentUsed |
number | records as a percentage of limit, to one decimal place. |
projectedRecords |
integer | The records expected by the end of the month at this rate. |
overLimit |
boolean | true when records is above limit. |
threshold |
integer | The threshold crossed: 80 or 100. |
Example
{
"id": "e7b19c5a-6d02-4e8f-9a41-3c5d8f2b7e90",
"type": "usage.threshold_reached",
"createdOn": "2026-09-24T11:00:00.264Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"month": "2026-09",
"records": 40320,
"impressions": 118904,
"limit": 50000,
"percentUsed": 80.6,
"projectedRecords": 51564,
"overLimit": false,
"threshold": 80
}
}propagation.overdue#
Sent when
Live processor tasks are past their due date with nothing reported. The check runs once a day at 06:00, and sends one event for each processor that has overdue tasks. Follow the processor up. See Follow up processor tasks.
Payload
Field in data |
Type | Description |
|---|---|---|
partnerKey, partnerName |
string | The processor. |
overdue |
integer | Its open tasks past their due date. |
oldestDueOn |
time | The earliest due date among them. |
newlyOverdue |
array | Up to 200 tasks not named in an earlier event: taskId, consentId, action, purposes and dueOn. |
test |
boolean | false. Test tasks are never chased. |
Example
{
"id": "3d8b2f60-c4e1-4a95-8b07-6f2e9a1d5c38",
"type": "propagation.overdue",
"createdOn": "2026-10-03T06:00:01.507Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"partnerKey": "nilgiri-mailers",
"partnerName": "Nilgiri Mailers",
"overdue": 4,
"oldestDueOn": "2026-09-28T09:30:12.004Z",
"newlyOverdue": [
{
"taskId": "2b9e4f61-0c3d-4a7e-8f15-6d2c9b0a7e34",
"consentId": "cns_3f1c9a7e2b8d4c6fa0e5d1b7c9f2a4e8",
"action": "STOP",
"purposes": ["marketing"],
"dueOn": "2026-10-02T09:30:12.004Z"
}
],
"test": false
}
}legal_hold.placed#
Sent when
Someone placed a legal hold on the Legal holds page. Keep your own copies of what it covers until it is released. See Hold evidence for a case or an appeal.
Payload
Field in data |
Type | Description |
|---|---|---|
holdId |
UUID | The hold. |
scope |
string | PROJECT, SUBJECT for one person or RECORD for one record. |
consentId |
string or null | The record, for RECORD. |
subjectRef |
string or null | For SUBJECT, the first 12 characters of the person's keyed hash, as the audit log shows it. Never the identifier. |
reason |
string | Why the hold was placed. |
caseReference |
string or null | The case, if given. |
placedBy |
string or null | The name of the person who placed it. |
placedOn |
time | When it was placed. |
heldRecords |
integer | The consent records it kept when it was placed. |
Example
{
"id": "1e7b3c9d-5a20-4f68-b4d1-9c3e7a5f0b82",
"type": "legal_hold.placed",
"createdOn": "2027-07-12T08:15:30.204Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"holdId": "4b1f6c2e-8d3a-4e5f-9a1b-2c3d4e5f6a7b",
"scope": "SUBJECT",
"consentId": null,
"subjectRef": "ad2cf5165c11",
"reason": "Appeal against the Board's order before the Tribunal",
"caseReference": "TDSAT Appeal No. 14 of 2027",
"placedBy": "Priya Sharma",
"placedOn": "2027-07-12T08:15:30.187Z",
"heldRecords": 3
}
}legal_hold.released#
Sent when
Someone released a legal hold. What it kept is then deleted at the end of its retention, like any other evidence.
Payload
Field in data |
Type | Description |
|---|---|---|
holdId, scope, consentId, subjectRef, caseReference |
— | As in legal_hold.placed. |
releasedBy |
string or null | The name of the person who released it. |
releasedOn |
time | When it was released. |
note |
string or null | Why it was released, if given. |
Example
{
"id": "6d0a2e8f-3c71-4b59-9e14-7f2b5d8c1a96",
"type": "legal_hold.released",
"createdOn": "2028-03-13T05:02:11.640Z",
"projectId": "c2a6f0de-51b3-4f0a-9d7e-8b1f3a6c4e90",
"test": false,
"data": {
"holdId": "4b1f6c2e-8d3a-4e5f-9a1b-2c3d4e5f6a7b",
"scope": "SUBJECT",
"consentId": null,
"subjectRef": "ad2cf5165c11",
"caseReference": "TDSAT Appeal No. 14 of 2027",
"releasedBy": "Priya Sharma",
"releasedOn": "2028-03-13T05:02:11.622Z",
"note": "Appeal decided on 12 March 2028"
}
}