Skip to main content

API Reference

This article covers the API endpoints used between your systems and DataGrail for Data Broker Compliance. There are two dispatch patterns — implement whichever matches your infrastructure. Both patterns support deletion (DROP status code 3) and opt-out (DROP status code 4) outcomes, and share the same authentication summary and error codes documented at the end of this article.

Prerequisites

Before implementing a dispatch pattern, ensure you have:


Webhook

Extension of Standard Webhooks

This section covers DROP-specific request and callback formats and builds on the standard Webhooks documentation.

Deletion Dispatch

DataGrail POSTs to a URL you configure when a DROP match occurs.

Deletion Dispatch Headers

DataGrail includes two custom headers in the request for identification and security purposes.

NameDescription
X-Webhook-SignatureHMAC-SHA256 signature to verify the request originated from DataGrail.
X-Webhook-TimestampTimestamp of when the request was sent.

Deletion Dispatch Body

The DROP deletion notification body includes the following parameters:

NameDescription
integration_namestring
The integration display name in the DataGrail application.
integration_kindstring
Always webhook.
webhook_request_idstring(UUID)
A unique identifier for the webhook request.
request_typestring
Always drop_deletion — distinguishes from DSR webhooks.
topicstring
Always drop.deletion:create.
request_uuidstring(UUID)
DataGrail's internal tracking ID for this deletion — echo this back in your outcome callback.
integration_idstring(UUID)
The UUID of your configured webhook integration.
identifier_hashstring
SHA-256 hash of the matched consumer identifier.
hash_typeenum
Which list type matched: email, phone, ndz, name_vin, maid, ctvid.
drop_session_idstring(UUID)
The specific DROP session/cycle this match came from.
match_datestring
Date the match occurred.
broker_idstring
Your four-digit CalPrivacy data broker registration number.
modeenum
Broker Registration mode: test or production.
remote_identifierstring
Your consumer pointer — the same value you sent during ingestion (omitted if none was provided).
webhook_callback_urlstring
The URL to PUT your outcome to once the deletion is complete.
Example Body: DROP Deletion
{
"broker_id": "4821",
"drop_session_id": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
"hash_type": "email",
"identifier_hash": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d",
"integration_id": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"integration_kind": "webhook",
"integration_name": "Your Integration Name",
"match_date": "2026-05-30",
"mode": "test",
"remote_identifier": "0035f00000A1B2CAAZ",
"request_type": "drop_deletion",
"request_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"topic": "drop.deletion:create",
"webhook_callback_url": "https://acme.datagrail.io/api/v2/webhooks/callback"
}

Deletion Dispatch Responses

Return 2xx to acknowledge receipt, then process the deletion asynchronously.

Deletion Outcome Callback

After processing the deletion, notify DataGrail of completion by sending a callback. Use ticket_uuid from the original request to correlate the callback.

Deletion Outcome Method

The callback must be an HTTP PUT request to the webhook_callback_url provided in the deletion dispatch.

Deletion Outcome API Key

The callback request must include an API key with the Webhook Callback scope. You can create an API key in DataGrail by navigating to Settings > API Keys > Create API Key.

Deletion Outcome Body

NameDescription
schema_versionstring
The schema version of the callback body, currently 1.0.
statusstring
Always completed.
request_uuidstring(UUID)
Echoes request_uuid from the original deletion dispatch.
drop_outcomeenum(Deletion Outcome Values)
The outcome of the deletion.
error_messagestring (optional)
Required when drop_outcome is failed.
Example Callback Body: DROP Deletion Outcome
{
"schema_version": "1.0",
"status": "completed",
"request_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"drop_outcome": "deleted",
"error_message": null
}

Deletion Outcome Values

EnumDROP Status CodeDescription
deleted3Consumer's non-exempt personal information was deleted.
not_found5Consumer not found in your system.
opted_out4Multiple consumers are linked to this identifier and all were opted out of sale or sharing.
exempt2All personal information for this consumer is exempt per Civil Code §1798.99.86.
failedProcessing failed (provide error_message).

Reporting a Webhook Opt-Out

An opt-out occurs when multiple consumers are linked to the same identifier and all are opted out of the sale or sharing of their personal information — rather than having their data deleted. This is DROP status code 4, as defined in CCR Title 11, §7614(b)(2)(D).

Return drop_outcome: "opted_out" when the matched identifier resolves to multiple consumers, and your system opts all of them out of sale or sharing rather than deleting their data. Include the resolved consumer email in identifiers.email:

NameDescription
identifiers.email[0].emailstring
Required when drop_outcome is opted_out. The resolved consumer email address.
Example Callback Body: DROP Opt-Out Outcome
{
"schema_version": "1.0",
"status": "completed",
"request_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"drop_outcome": "opted_out",
"identifiers": {
"email": [{ "email": "consumer@example.com" }]
},
"error_message": null
}
Opt-Out vs. Deletion

Opt-out does not remove data — it suppresses sale and sharing. Use opted_out when you retain the consumer's data under an opt-out rather than performing a full deletion. If you delete the data entirely, use deleted (code 3) instead.

Email Formatting

Return the consumer email address exactly as stored in your system. Do not trim whitespace, lowercase, or otherwise normalize the email value. DataGrail uses the exact value you return to create the opt-out record.

Sequence Diagram


DROP Identifier Retrieval

DataGrail sends this notification to your webhook endpoint to retrieve clear identifiers for a matched consumer so it can issue deletions to 3rd-party SaaS systems (Salesforce, HubSpot, etc.) on your behalf. It uses the same Deletion Dispatch Headers as the Deletion Dispatch notification.

When is this notification sent?

Only after a DROP match, and only if you have 3rd-party SaaS connections configured in DataGrail that require clear identifiers to process deletions. If you only need internal deletions handled by the Deletion Dispatch notification above, this notification is not sent.

Identifier Retrieval Body

In addition to the Deletion Dispatch Body parameters, the DROP identifier retrieval notification body includes the following:

NameDescription
broker_idstring
Your four-digit CalPrivacy data broker registration number.
drop_session_idstring(UUID)
The specific DROP session/cycle this match came from.
identifiers.external_id[0].external_idstring
Your consumer pointer — the same value you sent during ingestion.
integration_idstring(UUID)
The UUID of your configured webhook integration.
match_datestring
Date the match occurred.
modeenum
Broker Registration mode: test or production.
request_typestring
Always drop_resolution — distinguishes from the deletion dispatch.
request_uuidstring(UUID)
DataGrail's internal tracking ID for this resolution.
results_tokenstring
Hexadecimal string to echo back on your outcome callback.
topicstring
Always drop.resolution:create.
Example Body: DROP Identifier Retrieval
{
"broker_id": "4821",
"drop_session_id": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
"identifiers": {
"external_id": [{ "external_id": "0035f00000A1B2CAAZ" }]
},
"integration_id": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"integration_kind": "webhook",
"integration_name": "Your Integration Name",
"match_date": "2026-05-30",
"mode": "test",
"request_type": "drop_resolution",
"request_uuid": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"results_token": "a1b2c3d4e5f67890",
"topic": "drop.resolution:create",
"webhook_callback_url": "https://acme.datagrail.io/api/v2/webhooks/callback",
"webhook_request_id": "8b6b1f2a-7f3e-4b9a-9c3d-2e6f7a8b9c0d"
}

Identifier Retrieval Responses

Return 2xx to acknowledge receipt, then resolve the identifiers asynchronously.


Identifier Retrieval Outcome Callback

PUT the resolved identifiers to the webhook_callback_url provided in the notification. Use results_token from the original request to correlate the callback — DataGrail matches inbound resolution outcomes by this token rather than by ticket ID.

NameDescription
statusstring
Always completed.
results_tokenstring
Echoes results_token from the original notification.
drop_outcomeenum (optional)
opted_out or exempt — set when the resolved consumer should not be deleted directly.
exemption_basisstring (optional)
Required when drop_outcome is exempt (e.g. first_party, glba, legal_hold).
identifiersobject
The resolved consumer identifiers, keyed by category (e.g. email).
Resolved Identifiers Are Never Normalized

Send resolved email addresses exactly as they exist in your system — do not lowercase or trim them. DataGrail matches DROP identifiers on the verbatim value.

Example Callback Body: DROP Identifier Retrieval Outcome
{
"status": "completed",
"results_token": "a1b2c3d4e5f67890",
"identifiers": {
"email": [{ "email": "alice@example.com" }, { "email": "alice.work@example.com" }]
}
}

ISI (Internal Systems Integration)

ISI is a customer-hosted REST API that DataGrail calls into. DROP adds two new endpoints to the existing ISI spec.

Extension of Standard ISI API Specification

This section covers DROP-specific endpoints and builds on the standard API Specification documentation.

Prerequisites

Your ISI API must:

  • Serve over HTTPS with TLS 1.2+
  • Authenticate via OAuth 2.0 Client Credentials or static bearer token
  • Advertise DROP capabilities in /api/v1/connections/list:
{
"results": [
{
"uuid": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"capabilities": [
"privacy/access",
"privacy/delete",
"privacy/drop/identifiers",
"privacy/drop/delete"
]
}
]
}

DROP Delete Endpoint

DataGrail will call this endpoint when a DROP match occurs and your system needs to perform the deletion. This endpoint is asynchronous and should not return results.

When the request has been processed, results should be returned by triggering the DataGrail Webhook Callback.

DROP Delete Endpoint URL

POST /api/v1/privacy/drop/delete/:connection-uuid

DROP Delete Headers

ParameterDescription
Authorizationstring
Your bearer token.

DROP Delete Path Parameters

ParameterDescription
connection-uuidUUID
The connection UUID

DROP Delete Body Parameters

ParameterDescription
request_uuidstring(UUID)
Request in DataGrail.
results_tokenstring
Hexadecimal string used to retrieve the results of this request.
callback_pathstring
URL path to use for the Webhook Callback. Append to your customer domain.
drop_context.broker_idstring
Your four-digit CalPrivacy data broker registration number.
drop_context.drop_session_idstring(UUID)
The specific DROP session/cycle this match came from.
drop_context.hash_typestring
Which list type matched.
drop_context.match_datestring
Date the match occurred.
remote_identifierstring
Your consumer pointer — the same value sent during ingestion.
remote_identifier_kindstring
The kind of remote identifier provided.

DROP Delete Success Response

The request was accepted and the process to respond to the request will be initiated.

Example Response - 200 OK
{
"status": "processing"
}

Your callback when deletion completes:

Example Callback
{
"status": "completed",
"results_token": "a1b2c3d4e5f67890",
"drop_outcome": "deleted",
"completed_at": "2026-05-30T18:45:00Z"
}
Why is this separate from /privacy/delete?

DROP deletions have different requirements than standard DSR deletions — different regulatory timelines, audit trails, and customer-side workflows. A separate endpoint ensures you can implement DROP-specific handling without affecting your DSR pipeline.

Reporting an ISI Opt-Out

An opt-out occurs when multiple consumers are linked to the same identifier and all are opted out of the sale or sharing of their personal information — rather than having their data deleted. This is DROP status code 4, as defined in CCR Title 11, §7614(b)(2)(D).

Return drop_outcome: "opted_out" when the matched identifier resolves to multiple consumers, and your system opts all of them out of sale or sharing rather than deleting their data. Include the resolved consumer email in identifiers.email:

Example Callback Body: DROP Opt-Out Outcome
{
"status": "completed",
"results_token": "a1b2c3d4e5f67890",
"drop_outcome": "opted_out",
"identifiers": {
"email": [{ "email": "consumer@example.com" }]
},
"completed_at": "2026-05-30T18:45:00Z"
}
Opt-Out vs. Deletion

Opt-out does not remove data — it suppresses sale and sharing. Use opted_out when you retain the consumer's data under an opt-out rather than performing a full deletion. If you delete the data entirely, use deleted (code 3) instead.

Email Formatting

Return the consumer email address exactly as stored in your system. Do not trim whitespace, lowercase, or otherwise normalize the email value. DataGrail uses the exact value you return to create the opt-out record.

DROP Identifier Retrieval Endpoint

DataGrail will call this endpoint to retrieve clear identifiers for a matched consumer so it can issue deletions to 3rd-party SaaS systems (Salesforce, HubSpot, etc.) on your behalf. This endpoint is synchronous and must return results in the response.

DROP Identifier Retrieval Endpoint URL

POST /api/v2/privacy/drop/identifiers/:connection-uuid

DROP Identifier Retrieval Headers

ParameterDescription
Authorizationstring
Your bearer token.

DROP Identifier Retrieval Path Parameters

ParameterDescription
connection-uuidUUID
The connection UUID

DROP Identifier Retrieval Body Parameters

ParameterDescription
request_uuidstring(UUID)
Request in DataGrail.
remote_identifierstring
Your consumer pointer — the same value sent during ingestion.
remote_identifier_kindstring
The kind of remote identifier provided.
identifier_categoriesarray
The identifier categories to retrieve.

DROP Identifier Retrieval Success Response

The request was accepted and the results are available in the response body.

Example Response - 200 OK
{
"identifiers": {
"email": [{ "email": "alice@example.com" }, { "email": "alice.work@example.com" }],
"phone": [{ "phone": "+15551234567" }]
}
}

When is this endpoint called?

Only after a DROP match, and only if you have 3rd-party SaaS connections configured in DataGrail that require clear identifiers to process deletions. If you only need internal deletions handled by the DELETE endpoint above, this endpoint is not required.

 

Need help?
If you have any questions, please reach out to your dedicated Account Manager or contact us at support@datagrail.io.

Disclaimer: The information contained in this message does not constitute as legal advice. We would advise seeking professional counsel before acting on or interpreting any material.