Skip to main content

API Reference

This article covers the API endpoints used between your systems and DataGrail for Data Broker Compliance. There are three deletion dispatch patterns — implement whichever matches your infrastructure. All three patterns 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

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

Deletion Dispatch (DataGrail → You)

POST <your-webhook-url>
Content-Type: application/json
X-Datagrail-Event: drop.deletion
X-Webhook-Timestamp: 1717027200
X-Webhook-Signature: v1=<base64(HMAC-SHA256(shared_secret, "<timestamp>:<body>"))>

Request body:

{
"schema_version": "1.0",
"event": "drop.deletion",
"ticket_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"broker_id": "4821",
"drop_session_id": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
"hash_type": "email",
"match_date": "2026-05-30",
"remote_identifier": "0035f00000A1B2CAAZ",
"remote_identifier_kind": "external_id",
"callback_url": "https://yourcompany.datagrail.io/api/v2/webhooks/callback"
}

Fields:

FieldDescription
eventAlways "drop.deletion" — distinguishes from DSR webhooks
ticket_uuidDataGrail's internal tracking ID for this deletion
broker_idYour CalPrivacy data broker registration number
drop_session_idThe specific DROP session/cycle this match came from
hash_typeWhich list type matched: email, phone, ndz, name_vin, maid, ctvid
remote_identifierYour consumer pointer — the same value you sent during ingestion
remote_identifier_kindHow to interpret the pointer: external_id, row_uuid, email, phone
callback_urlURL to POST your outcome to when deletion is complete

Return 2xx to acknowledge receipt. Process the deletion asynchronously.

Signature verification: Compute HMAC-SHA256(shared_secret, "<X-Webhook-Timestamp>:<raw-body>"), Base64-encode, and compare to the value after v1= in X-Webhook-Signature.

Deletion Outcome Callback (You → DataGrail)

After processing the deletion, POST the outcome to the callback_url provided in the webhook. Use ticket_uuid from the original request to correlate the callback.

POST <callback_url>
Content-Type: application/json
Authorization: Bearer <your-datagrail-api-token>
{
"schema_version": "1.0",
"status": "completed",
"ticket_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"drop_outcome": "deleted",
"completed_at": "2026-05-30T18:45:00Z",
"failure_reason": null
}

drop_outcome values:

ValueDROP Status CodeMeaning
deleted3Consumer's data was deleted
not_found5Consumer not found in your system
opted_out4Consumer previously opted out
failedDeletion failed (provide failure_reason)

Polling

Your agent pulls pending DROP deletion work items from DataGrail on a schedule.

Retrieve Pending Deletions (You → DataGrail)

GET /api/v2/internal_systems/pending_work?connector_type=drop&broker_registration_id=<uuid>&limit=100
Authorization: Bearer <agent-api-token>

Response:

{
"work_items": [
{
"operation": "drop_delete",
"ticket_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"connection_uuid": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"broker_id": "4821",
"drop_session_id": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
"hash_type": "email",
"match_date": "2026-05-30",
"remote_identifier": "0035f00000A1B2CAAZ",
"remote_identifier_kind": "external_id",
"results_token": "a1b2c3d4e5f67890",
"callback_url": "https://yourcompany.datagrail.io/api/v2/internal_systems/request_callback",
"created_at": "2026-05-30T14:00:00Z"
}
],
"has_more": false,
"poll_after": "2026-05-30T15:00:00Z"
}
  • Each work item is leased for 24 hours. If you don't confirm the outcome within 24h, it becomes available again.
  • poll_after is a hint for when the next poll would be productive — respect it to avoid rate limiting.
  • Process each item and POST the outcome to callback_url using the same callback format as the webhook pattern above (include results_token instead of ticket_uuid for polling callbacks).

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.

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 calls this when a DROP match occurs and your system needs to perform the deletion.

POST /api/v1/privacy/drop/delete/<connection-uuid>
Authorization: Bearer <token>
Content-Type: application/json

Request body:

{
"request_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"results_token": "a1b2c3d4e5f67890",
"callback_path": "/api/v2/internal_systems/request_callback",
"drop_context": {
"broker_id": "4821",
"drop_session_id": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
"hash_type": "email",
"match_date": "2026-05-30"
},
"remote_identifier": "0035f00000A1B2CAAZ",
"remote_identifier_kind": "external_id"
}

Your immediate response:

HTTP/1.1 200 OK
{"status": "processing"}

Your callback when deletion completes:

{
"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.

DROP Identifier Retrieval Endpoint

DataGrail calls this to retrieve clear identifiers for a matched consumer so it can issue deletions to 3rd-party SaaS systems (Salesforce, HubSpot, etc.) on your behalf.

POST /api/v2/privacy/drop/identifiers/<connection-uuid>
Authorization: Bearer <token>
Content-Type: application/json

Request body:

{
"request_uuid": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"remote_identifier": "0035f00000A1B2CAAZ",
"remote_identifier_kind": "external_id",
"identifier_categories": ["email", "phone"]
}

Your synchronous response:

HTTP/1.1 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.


Authentication Summary

The following table summarizes the authentication method for each dispatch pattern:

PatternAuth Method
Webhook (DataGrail → you)HMAC-SHA256 signature on each request
Webhook callback (you → DataGrail)Bearer token (provided by DataGrail)
Polling (you → DataGrail)Bearer token (agent API key)
ISI (DataGrail → you)OAuth 2.0 Client Credentials or static bearer token

Error Codes

The following HTTP status codes may be returned by DataGrail endpoints:

CodeMeaning
200Success
202Accepted (async processing started)
400Bad request — check response body for validation details
401Authentication failed
403Insufficient permissions
404Resource not found
409Conflict (e.g., duplicate upload in progress)
429Rate limited — respect Retry-After header
500Internal server error

Error response body:

{
"error": "validation_failed",
"message": "schema_version '2.0' is not supported",
"supported_versions": ["1.0"]
}

 

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.