Step 8: Webhook Notification (Consent Status Update)
Once the Data Principal Grants or Revokes consent via the Consent Notice UI, the Consent Manager will notify the Data Fiduciary (DF) by calling the configured Webhook URL.
This webhook delivers the final consent decision along with a cryptographically signed payload.
π When Is the Webhook Triggered?β
The webhook is triggered when:
- User grants consent
- User revokes consent
- Consent expires (if applicable)
π Webhook Endpoint (DF Side)β
During onboarding, the DF must configure a webhook URL in the Consent Manager dashboard.
Example:
https://yourdomain.com/api/webhooks/consent-status
This endpoint must:
- Accept
POSTrequests - Accept
application/json - Be publicly accessible over HTTPS
Webhook Requestβ
Method: POST
Content-Type: application/json
Webhook Payloadβ
{
"consent_id": "string",
"status": "string",
"receipt": {
...
}
}
Consent Receipt Schemaβ
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://www.indiaconsent.com/schema/consent-receipt-v1.json",
"title": "ConsentReceipt",
"type": "object",
"required": [
"receiptId",
"version",
"consentId",
"cmId",
"status",
"fiduciary",
"dataPrincipal",
"service",
"language",
"purposes",
"issuedAt",
"expiresAt",
"payloadHash",
"receiptPayload",
"supersedesPrevious"
],
"properties": {
"receiptId": {
"type": "string",
"description": "Unique identifier for this receipt (UUID preferred).",
"pattern": "^[a-zA-Z0-9\-_:]+$"
},
"version": {
"type": "string",
"description": "Schema/version of the receipt format.",
"enum": [
"1.0"
]
},
"consentId": {
"type": "string",
"description": "Reference to the ConsentRequest ID (crId) this receipt was generated from"
},
"cmId": {
"type": "string",
"description": "Identifier of the Consent Manager issuing this receipt."
},
"fiduciary": {
"type": "object",
"description": "Information about the fiduciary managing this consent",
"required": [
"fidId",
"name"
],
"properties": {
"fidId": {
"type": "string",
"description": "Unique identifier of the fiduciary in CM system."
},
"name": {
"type": "string",
"description": "Registered name of the fiduciary."
}
},
"additionalProperties": false
},
"dataPrincipal": {
"type": "object",
"description": "Data Principal information as known to CM (NO PII from DF).",
"required": [
"dpHash"
],
"properties": {
"dpHash": {
"type": "string",
"description": "Pseudonymous identifier linking this receipt to the DP within this fiduciary context."
}
},
"additionalProperties": false
},
"service": {
"type": "object",
"description": "Service for which consent was given.",
"required": [
"serviceId",
"serviceName"
],
"properties": {
"serviceId": {
"type": "string",
"description": "Unique identifier for the service"
},
"serviceName": {
"type": "string",
"description": "Human-readable name of the service"
}
}
},
"language": {
"type": "string",
"description": "Language code of the selected language of consent grant/revoke (e.g., 'en', 'hi', 'ta')"
},
"purposes": {
"type": "array",
"description": "List of purposes with associated data categories and user choices.",
"minItems": 1,
"items": {
"type": "object",
"required": [
"purposeId",
"purposeText",
"description",
"dataCategories"
],
"properties": {
"purposeId": {
"type": "string",
"description": "Unique identifier for this purpose (DF-defined)."
},
"purposeText": {
"type": "string",
"description": "Human-readable text of the purpose."
},
"description": {
"type": "string",
"description": "Human-readable description of the purpose."
},
"dataCategories": {
"type": "array",
"description": "Categories of data under this purpose",
"minItems": 1,
"items": {
"type": "object",
"required": [
"id",
"label",
"allowed"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this data category (DF-defined)"
},
"label": {
"type": "string",
"description": "User-visible text (CM will render as toggle label)"
},
"allowed": {
"type": "boolean",
"description": "Whether the user consented to this data category under this purpose."
}
}
}
},
"retention": {
"type": "object",
"required": [
"duration",
"unit",
"expiresAt"
],
"properties": {
"duration": {
"type": "integer",
"description": "Data retention duration for this purpose. DF-defined value, to be interpreted by the CM. E.g. if unit is 'month' and duration is 6, CM can show '6 Months' as retention period to DP. Its value can be 1 to 11 for unit 'month' and 1 to 5 for unit 'year'."
},
"unit": {
"type": "string",
"enum": [
"month",
"year"
]
},
"expiresAt": {
"type": "string",
"format": "date-time",
"description": "Exact timestamp when the consent for this purpose expires. Value of this field will be set when user grants. DF can use this field to find the exact expiry datetime"
}
}
}
},
"additionalProperties": false
}
},
"status": {
"type": "string",
"description": "Effective status of the consent at the time of issuing/updating the receipt.",
"enum": [
"granted",
"revoked",
"expired"
]
},
"issuedAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the receipt was issued."
},
"expiresAt": {
"type": "string",
"format": "date-time",
"description": "When the consent naturally expires, if applicable."
},
"cmNotice": {
"type": "object",
"description": "Information about how DP can manage consent and contact CM.",
"required": [
"manageUrl"
],
"properties": {
"manageUrl": {
"type": "string",
"format": "uri",
"description": "URL where DP can view/revoke this consent."
}
},
"additionalProperties": true
},
"payloadHash": {
"type": "string",
"description": "Hash (e.g., SHA-256) of the canonical JSON payload of this receipt (without signature)."
},
"receiptPayload": {
"type": "string",
"description": "Canonical JSON representation of the complete receipt (payload + signature) as stored in DB"
},
"supersedesPrevious": {
"type": "boolean",
"default": true,
"description": "Whether this receipt supersedes a previous one"
}
},
"additionalProperties": false
}
Sample Consent Receiptβ
{
"cmId" : "cm-indiaconsent-01",
"consentId" : "0d2f6211-17f3-4e99-aec0-d6a0d404cfcd",
"dataPrincipal" : {
"dpHash" : "68fb2ced2daaf430ebd5c9eb"
},
"expiresAt" : "2026-04-06T11:39:09.891204400Z",
"fiduciary" : {
"fidId" : "c8ab306d-0a53-4af1-9f3c-c4662df39500",
"name" : "AlignMyCareer"
},
"issuedAt" : "2026-04-06T11:39:09.891204400Z",
"language" : "en",
"payloadHash" : "6cfaf1d741a62828ed41e910c16080fcfbc349bbc4e696a11bd73fc62517e88d",
"purposes" : [
{
"purposeId" : "order.placement",
"purposeText" : "Order Placement & Fulfilment",
"description" : "To place, process, ship, and deliver your orders purchased on our platform",
"retention" : {
"unit" : "year",
"duration" : 1,
"expiresAt" : "2027-04-06T11:39:09.891204400Z"
},
"dataCategories" : [
{
"allowed" : true,
"id" : "contact.fullname",
"label" : "Full Name"
},
{
"allowed" : true,
"id" : "contact.email",
"label" : "Email Address"
},
{
"allowed" : true,
"id" : "contact.address",
"label" : "Shipping Address"
}
]
},
{
"purposeId" : "payment.processing",
"purposeText" : "Payment Processing & Refunds",
"description" : "To process payments, refunds, charges, and transaction confirmations.",
"retention" : {
"unit" : "year",
"duration" : 1,
"expiresAt" : "2027-04-06T11:39:09.891204400Z"
},
"dataCategories" : [
{
"allowed" : true,
"id" : "payment.method",
"label" : "Payment Method"
},
{
"allowed" : true,
"id" : "payment.status",
"label" : "Payment Status"
}
]
}
],
"receiptId" : "adbf439a-d216-4862-8ee6-7164199a1509",
"receiptPayload" : "{"payload":{"cmId":"cm-indiaconsent-01","cmNotice":{"manageUrl":"http://localhost:5173/consent?cr_id=0d2f6211-17f3-4e99-aec0-d6a0d404cfcd"},"consentId":"0d2f6211-17f3-4e99-aec0-d6a0d404cfcd","dataPrincipal":{"dpHash":"68fb2ced2daaf430ebd5c9eb"},"expiresAt":"2026-04-06T11:39:09.891204400Z","fiduciary":{"fidId":"c8ab306d-0a53-4af1-9f3c-c4662df39500","name":"AlignMyCareer"},"issuedAt":"2026-04-06T11:39:09.891204400Z","language":"en","purposes":[{"dataCategories":[{"allowed":true,"id":"contact.fullname","label":"Full Name"},{"allowed":true,"id":"contact.email","label":"Email Address"},{"allowed":true,"id":"contact.address","label":"Shipping Address"}],"description":"To place, process, ship, and deliver your orders purchased on our platform","purposeId":"order.placement","purposeText":"Order Placement & Fulfilment","retention":{"duration":1,"expiresAt":"2027-04-06T11:39:09.891204400Z","unit":"year"}},{"dataCategories":[{"allowed":true,"id":"payment.method","label":"Payment Method"},{"allowed":true,"id":"payment.status","label":"Payment Status"}],"description":"To process payments, refunds, charges, and transaction confirmations.","purposeId":"payment.processing","purposeText":"Payment Processing & Refunds","retention":{"duration":1,"expiresAt":"2027-04-06T11:39:09.891204400Z","unit":"year"}}],"receiptId":"adbf439a-d216-4862-8ee6-7164199a1509","service":{"serviceId":"shopping.order.fulfilment","serviceName":"Online Shopping & Order Fulfilment"},"status":"granted","supersedesPrevious":true,"version":"1.0"},"signature":{"alg":"RS256","jwsCompact":"eyJraWQiOiJjbS1yc2Eta2V5IiwidHlwIjoiY29uc2VudC1yZWNlaXB0K2p3dCIsImFsZyI6IlJTMjU2In0.eyJjbUlkIjoiY20taW5kaWFjb25zZW50LTAxIiwiY21Ob3RpY2UiOnsibWFuYWdlVXJsIjoiaHR0cDovL2xvY2FsaG9zdDo1MTczL2NvbnNlbnQ_Y3JfaWQ9MGQyZjYyMTEtMTdmMy00ZTk5LWFlYzAtZDZhMGQ0MDRjZmNkIn0sImNvbnNlbnRJZCI6IjBkMmY2MjExLTE3ZjMtNGU5OS1hZWMwLWQ2YTBkNDA0Y2ZjZCIsImRhdGFQcmluY2lwYWwiOnsiZHBIYXNoIjoiNjhmYjJjZWQyZGFhZjQzMGViZDVjOWViIn0sImV4cGlyZXNBdCI6IjIwMjYtMDQtMDZUMTE6Mzk6MDkuODkxMjA0NDAwWiIsImZpZHVjaWFyeSI6eyJmaWRJZCI6ImM4YWIzMDZkLTBhNTMtNGFmMS05ZjNjLWM0NjYyZGYzOTUwMCIsIm5hbWUiOiJBbGlnbk15Q2FyZWVyIn0sImlzc3VlZEF0IjoiMjAyNi0wNC0wNlQxMTozOTowOS44OTEyMDQ0MDBaIiwibGFuZ3VhZ2UiOiJlbiIsInB1cnBvc2VzIjpbeyJkYXRhQ2F0ZWdvcmllcyI6W3siYWxsb3dlZCI6dHJ1ZSwiaWQiOiJjb250YWN0LmZ1bGxuYW1lIiwibGFiZWwiOiJGdWxsIE5hbWUifSx7ImFsbG93ZWQiOnRydWUsImlkIjoiY29udGFjdC5lbWFpbCIsImxhYmVsIjoiRW1haWwgQWRkcmVzcyJ9LHsiYWxsb3dlZCI6dHJ1ZSwiaWQiOiJjb250YWN0LmFkZHJlc3MiLCJsYWJlbCI6IlNoaXBwaW5nIEFkZHJlc3MifV0sImRlc2NyaXB0aW9uIjoiVG8gcGxhY2UsIHByb2Nlc3MsIHNoaXAsIGFuZCBkZWxpdmVyIHlvdXIgb3JkZXJzIHB1cmNoYXNlZCBvbiBvdXIgcGxhdGZvcm0iLCJwdXJwb3NlSWQiOiJvcmRlci5wbGFjZW1lbnQiLCJwdXJwb3NlVGV4dCI6Ik9yZGVyIFBsYWNlbWVudCAmIEZ1bGZpbG1lbnQiLCJyZXRlbnRpb24iOnsiZHVyYXRpb24iOjEsImV4cGlyZXNBdCI6IjIwMjctMDQtMDZUMTE6Mzk6MDkuODkxMjA0NDAwWiIsInVuaXQiOiJ5ZWFyIn19LHsiZGF0YUNhdGVnb3JpZXMiOlt7ImFsbG93ZWQiOnRydWUsImlkIjoicGF5bWVudC5tZXRob2QiLCJsYWJlbCI6IlBheW1lbnQgTWV0aG9kIn0seyJhbGxvd2VkIjp0cnVlLCJpZCI6InBheW1lbnQuc3RhdHVzIiwibGFiZWwiOiJQYXltZW50IFN0YXR1cyJ9XSwiZGVzY3JpcHRpb24iOiJUbyBwcm9jZXNzIHBheW1lbnRzLCByZWZ1bmRzLCBjaGFyZ2VzLCBhbmQgdHJhbnNhY3Rpb24gY29uZmlybWF0aW9ucy4iLCJwdXJwb3NlSWQiOiJwYXltZW50LnByb2Nlc3NpbmciLCJwdXJwb3NlVGV4dCI6IlBheW1lbnQgUHJvY2Vzc2luZyAmIFJlZnVuZHMiLCJyZXRlbnRpb24iOnsiZHVyYXRpb24iOjEsImV4cGlyZXNBdCI6IjIwMjctMDQtMDZUMTE6Mzk6MDkuODkxMjA0NDAwWiIsInVuaXQiOiJ5ZWFyIn19XSwicmVjZWlwdElkIjoiYWRiZjQzOWEtZDIxNi00ODYyLThlZTYtNzE2NDE5OWExNTA5Iiwic2VydmljZSI6eyJzZXJ2aWNlSWQiOiJzaG9wcGluZy5vcmRlci5mdWxmaWxtZW50Iiwic2VydmljZU5hbWUiOiJPbmxpbmUgU2hvcHBpbmcgJiBPcmRlciBGdWxmaWxtZW50In0sInN0YXR1cyI6ImdyYW50ZWQiLCJzdXBlcnNlZGVzUHJldmlvdXMiOnRydWUsInZlcnNpb24iOiIxLjAifQ.tkKRozkzSraI96c4mAS00X5UrEG0260FN8U1HExyDwhtUN4Q9qmXIfISv46lKyCNMQCAANWZTLeSeM3NzUVizShHSzRZEOkzDGZyVG_Kv5nOX00ZaSVoQhx7dVTrb3j77ELwdARsxdYIY-3eNZ9srVBm-Vm84j-w8UCVhGAo7Er2H2wRtdk_doX6ZYv2O5aSIX13Q92mj9wt-MInw-eYueHnU1GGyZBrxC3mt0KMqo_GfVtVVZEN5pw5OGi-CUbFImUqX9bydAbDk_Q2W3sRkCf6ZhMywA6VMSE6IwBBSMdc5m3CloRsJ1cEFqgrwR87v7f5FfeNxJ41tzLPuD7DJw","kid":"cm-rsa-key","payloadHash":"6cfaf1d741a62828ed41e910c16080fcfbc349bbc4e696a11bd73fc62517e88d","signedAt":"2026-04-06T11:39:09.891204400Z"}}",
"service" : {
"serviceId" : "shopping.order.fulfilment",
"serviceName" : "Online Shopping & Order Fulfilment"
},
"status" : "granted",
"supersedesPrevious" : true,
"version" : "1.0"
}
π Webhook Signature Verificationβ
To ensure authenticity:
-
Each webhook payload is digitally signed.
-
The DF must verify the signature using the Consent Managerβs public key.
-
Optionally validate the receipt hash for integrity.
Recommended Validation Stepsβ
-
Verify the request is received over HTTPS.
-
Validate signature using public key.
-
Validate receipt hash.
-
Ensure
requestIdmatches an existing request. -
Ensure idempotency (avoid duplicate processing).
Expected DF Responseβ
Your webhook endpoint must return:
HTTP/1.1 200 OK
If a non-2xx response is returned:
- Consent Manager may retry delivery.
- Multiple attempts may occur.
π Retry Policy (Recommended Behavior)β
- If webhook fails, retry mechanism will attempt redelivery.
- Ensure your endpoint is idempotent.
β οΈ Important Security Guidelinesβ
-
Do not trust payload without signature validation.
-
Do not expose webhook URL publicly without validation logic.
-
Maintain logs for audit purposes.
-
Store consent receipt securely for compliance.
Consent Lifecycle Completionβ
User Grants / Revokes
β
Consent Manager Generates Receipt
β
Signed Webhook Sent to DF
β
DF Verifies & Stores Consent Record