TrueEngageDocsStart free

Erasure API

Erase one person from your backend, then check the request until it completes. Request and response fields, scope, errors and server setup.

Updated 24 Oct 2026 5 min read

Use these endpoints to erase a person when your own system receives the deletion request. They do what the console does. For what erasure deletes and keeps, see Erasing a person.

Method and path Purpose
POST /v1/privacy/erase Start an erasure.
GET /v1/privacy/requests/:id Read the state of one request.

Before you start

  • Use a server or data API key whose scope includes data.gdpr_delete (shown as GDPR Delete in the key's scope tree). SDK keys cannot call these endpoints. See Authentication and API keys.
  • The key's environment decides where the person is erased. Test keys erase in Test, Live keys in Live.
  • Each key can make 60 requests a minute, and each environment is capped per hour. See Errors.

Erase a person

curl -X POST https://api.true-engage.com/v1/privacy/erase \
  -H "Authorization: Bearer $TRUEENGAGE_SERVER_KEY" \
  -H "Idempotency-Key: dsr-2207" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": { "type": "external_id", "value": "user-1042" },
    "reason": "Customer asked to be deleted, ticket 4821",
    "reference": "DSR-2207",
    "confirm": true
  }'

Request

Field Required Notes
subject.type Yes external_id, user_id, email or phone. user_id is the id TrueEngage gives the profile.
subject.value Yes The identifier. It is never stored; only a keyed hash is.
reason Yes 5 to 500 characters, with no personal data. Stored with the request and in the audit log.
reference No Your ticket reference, up to 128 characters.
confirm Yes Must be true. It stands in for the confirmation a console user gives by typing the workspace name.

Send an Idempotency-Key header so a retry cannot start a second request. A repeat with the same key returns the existing request.

An email or phone number matches the profile however it is written, for example with or without the + and country code. Every form of the identifier is blocked afterwards.

Response

202 for a new request, 200 for an existing one. The body is the standard envelope; data holds:

{
  "requestId": "01a17000-0000-7000-8000-000000000001",
  "status": "processing",
  "stage": "awaiting_audiences",
  "deadlineAt": "2026-11-21T09:12:00.000Z",
  "subjectsFound": 1,
  "requestedBy": { "type": "api_key", "id": "01a17000-0000-7000-8000-0000000000b2", "name": "Backend server key" },
  "reason": "Customer asked to be deleted, ticket 4821",
  "created": true
}

You get 200 and created: false when the same Idempotency-Key is reused, when an open request already covers the person, or when the person was already erased.

When no profile matches, the answer is 202 with status completed, subjectsFound 0 and notFound true. The identifier is still blocked from being re-created. This does not apply to user_id.

subjectsFound can be more than 1. TrueEngage follows merged profiles and erases them together, up to 20 profiles. More than that returns PRIVACY_SUBJECT_AMBIGUOUS.

Read a request

curl https://api.true-engage.com/v1/privacy/requests/01a17000-0000-7000-8000-000000000001 \
  -H "Authorization: Bearer $TRUEENGAGE_SERVER_KEY"

data holds:

Field Meaning
requestId The request id.
status received, processing, completed or rejected.
stage received, awaiting_audiences, purging, scrub_pending, completed or rejected.
requestedAt, deadlineAt, completedAt Timestamps. completedAt is null until done.
via console or api.
requestedBy { type, id, name }. type is user, api_key or system. Who made the request is always recorded.
reason, reference What you sent.
audienceOutcome null while waiting, then none, removed or partly_abandoned.
waitingOn Ad audiences still holding the request, each with platform and a cause. Empty when none.
steps Counts of what was removed.
residuals What stays for now: { area, until }. until is null when it has no end date.
notFound true when no profile matched.

Nothing in the response identifies the person. Poll until status is completed, at an interval of a minute or more. A request that waits on an ad platform can take up to 14 days. GET also needs the same scope.

Errors

Errors use the standard shape. The codes specific to erasure:

Status Code Meaning
400 ERASURE_CONFIRMATION_REQUIRED confirm: true is missing.
400 ERASURE_REASON_REQUIRED reason is missing, shorter than 5 or longer than 500 characters.
403 INSUFFICIENT_SCOPE The key does not have data.gdpr_delete.
404 PRIVACY_REQUEST_NOT_FOUND No request with that id in this environment.
422 PRIVACY_SUBJECT_INVALID The value does not fit the subject.type, or reference is too long.
422 PRIVACY_SUBJECT_AMBIGUOUS The identifier matched more than 20 profiles.
422 IDEMPOTENCY_KEY_REUSED That Idempotency-Key was already used for another person.
429 ERASURE_RATE_LIMITED Too many erasures in this environment this hour. Nothing was erased. Wait, then retry.
503 PRIVACY_NOT_CONFIGURED Erasure is not set up on this server. See the operator note below.

Other endpoints answer 410 USER_ERASED when you name a person who was erased, for example Promote an identity. Events and imports for an erased person's identifiers are dropped quietly for the retention period.

Operator note: self-hosted setup

If you run TrueEngage yourself, set these before you use erasure. Hosted workspaces need nothing.

Variable Default Meaning
PRIVACY_TOMBSTONE_KEY None Secret of at least 32 bytes. Set the same value on the API and on the worker. Without it POST /v1/privacy/erase answers 503 PRIVACY_NOT_CONFIGURED, and outside development the API and worker refuse to start. Blocked identifiers are keyed hashes, so changing the key stops earlier blocks from matching.
ERASURE_TOMBSTONE_DAYS 90 How long identifiers stay blocked. Between 7 and 365.
ERASURE_AUDIENCE_WAIT_DAYS 14 How long to wait for ad platforms before going ahead. Keep it at or below ADS_REMOVAL_MAX_WAIT_DAYS.
ADS_REMOVAL_MAX_WAIT_DAYS 14 How long an audience removal is retried before it is given up on and reported as a warning on the audience. Minimum 3.
ERASURE_SETTLE_SECONDS 15 Pause between erasure steps.
ERASURE_MAX_PER_HOUR 200 Erasure requests per environment per hour.

Run the database updates first, then set the secret, then deploy the worker, then the API. If you pin which queues the worker consumes, add privacy.erasure. Keys that already hold the data.gdpr_delete scope gain the endpoint on deploy, so list them first.

Related