A valid request URL is required to generate request examples{
"erasure": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"contact_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "pending",
"requested_at": "2023-11-07T05:31:56Z"
},
"notice": "<string>"
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}Erase a contact
Requires customers:erase — its own permission, held by owner and deliberately not by admin. It is not customers:write: a merge is destructive and repairable, since the merge record says what moved, while this is destructive and final. Nothing records what the deleted rows held, and there is no un-erase. Granting it needs roles:manage, so an admin cannot hand it to themselves.
The request arrives through you rather than from the person: you are the controller, you decided what to collect and why, and you are the only party that can tell a genuine subject request from somebody phishing one.
What happens
Answers 202: the request is durable and nothing has been destroyed yet. A background pass performs it, and it takes no arguments — the outstanding work is the row this call created, so a lost message costs seconds and never the obligation.
The contact goes, with every identity edge, every session, every outstanding credential, the authentication history, the support conversations, the analytics events, the audience memberships and the team seats. What stays, each for a reason GET /v1/organization/contacts/{id}/export states beside the table: the active-contact meter (the number your bill reads), the merge provenance (half of it is about a different person who did not ask for anything), public feedback posts with their authorship removed rather than the text deleted, and the customer teams with their subscriptions and invoices — the money belongs to the team, and an issued invoice has a statutory life of its own.
Sessions are ended and published to GET /v1/revocations/{publishable_key} in the same statement, so a JWT minted before the erasure stops verifying within seconds rather than outliving the person by its five minutes.
When it completes, contact.erased is delivered to your webhook endpoints. That is the fact to act on: your own database, warehouse and mailing list hold copies of this person that nothing here can reach.
What is not touched
Records at your payment gateway. Take the export before requesting the erasure — it lists the provider identifiers, and afterwards nothing here can find them.
A valid request URL is required to generate request examples{
"erasure": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"contact_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "pending",
"requested_at": "2023-11-07T05:31:56Z"
},
"notice": "<string>"
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}Authorizations
A staff session token, uk_st_…. Minted by sign-up, sign-in or the two-factor exchange. Only a 401 means it is spent; not_a_member (403) is about the organization named in X-Organization-Id and leaves the token good for the others.
Headers
The organization the caller is acting on — the org_… code that appears in the panel URL. It identifies; the membership JOIN is what authorizes, so a forged code reads nothing: the answer is not_a_member (403), which does not mean the session is over. Absent, the session's default organization answers, or — if that membership was revoked while the session was open — any other one the caller still holds.
Path Parameters
Query Parameters
Which environment to act in. A view parameter, valid only on the staff surface — a machine credential never chooses its environment, it is resolved from the key.
live, test