Data deletion: app removal, one person, or a workspace
Data leaves HookChat in three ways. A person who connected your accounts can remove your app at Meta, which reaches HookChat as a callback. A customer who messaged you can ask you, the business, to delete their data, which you do with one call. And you can delete your whole workspace. This page says what each one erases, and what stays with you.
| Who asks | How it reaches HookChat | What is erased |
|---|---|---|
| The person who connected your accounts removes the app, or asks Meta to delete their data | A signed callback from Meta | Those accounts, their tokens and everything under them |
| A customer who messaged you asks you to delete their data | You call DELETE /v1/conversations/{id}, or use the console | That one conversation and everything about it |
| You close your workspace | The owner uses Delete workspace in the console settings | The workspace and everything HookChat holds for it |
Erase one person, when your customer asks#
Under privacy law your customer asks you, the business, to delete their data, and HookChat acts for you. A conversation is one person on one of your accounts, so its id is all HookChat needs. Erase it from the conversation page in the console with Erase this person's data, where you type their name or ERASE to confirm, or call the API with a live key. A test key cannot erase.
DELETE /v1/conversations/CONV%23acme%23instagram%2317841400000000001%23900001 HTTP/1.1
Host: hookchat.dev
Authorization: Bearer <a live key>The SDKs call it conversations.erase(id), and the CLI hookchat conversations erase <id>, which asks first at a terminal and needs --yes in a script. The id has # in it, so encode each one as %23 in a URL.
It erases the conversation itself: the name, picture and last text. It erases every message both ways and the stored profile. It erases the copies of its events sent to all your endpoints, with their bodies. And it erases its send records, any upload from a computer still waiting for Meta, and any held human-agent message. The answer holds counts, never content, and it cannot be undone.
{
"ok": true,
"data": {
"done": true,
"removed": { "conversation": 1, "profile": 1, "messages": 12, "markers": 3, "deliveries": 14, "send_records": 2, "uploads": 0, "holds": 0 }
}
}- Calling it again is safe: when nothing is left, the answer is 200 with every count at zero.
- A big conversation that does not finish in about 15 seconds answers 202 with
done: false. HookChat finishes it in the background; call again later and a 200 withdone: truesays nothing is left. - An id from another workspace is the same 404
conversation_not_foundas one that never existed. - The audit log records who erased it, a hash of the conversation id, and the counts. It keeps no participant id and no text.
- No webhook event is sent: you made the call, so you already know. If the person writes again, a new conversation starts.
One thing is outside the erase and expires on its own: the raw copy of each webhook as Meta sent it to HookChat. It is kept by day of arrival, not by person, and one copy can carry several people's messages, so it cannot be found without reading every copy. It expires within 7 days.
Delete your workspace#
The workspace owner can delete the whole workspace from Settings in the console. Only the owner sees the button, and the server checks again. You type the workspace name to confirm. There is no API key route for it: an API key cannot delete a workspace.
At once, every member and every API key lose access, pending invites are withdrawn, webhook endpoints stop receiving events, and connected accounts stop receiving and sending messages and are unsubscribed at Meta. Then HookChat deletes, in the background:
- The connected accounts and their access tokens.
- Every conversation and message, with the stored profiles.
- The copies of events sent to your endpoints, with their bodies, and the endpoints themselves.
- Send records, uploads still waiting for Meta, and held human-agent messages.
- API keys, members and invites.
It cannot be undone, and the workspace name cannot be used for a new workspace. HookChat keeps a record that the workspace was deleted, by whom and when, with counts and no message content. The raw copy of each webhook as Meta sent it is not stored per workspace and expires on its own within 7 days. The copies of events you received are yours to delete on your side.
When the app is removed: two callbacks, one outcome#
When a person removes your app, Meta calls the gateway's deauthorize callback. When they ask for deletion, Meta calls the data deletion callback. In both cases the gateway revokes the accounts that person authorised and queues an erase job. The deletion callback also records a request with a confirmation code and hands Meta a status URL, which Meta shows to the person. Meta signs each callback, and the gateway checks the signature before it acts, so a forged request is refused with a 400.
| Meta sends | The gateway does |
|---|---|
| Deauthorize (the app was removed) | Revokes the accounts, queues the erase. No status page, because Meta does not ask for one. |
| Data deletion request | Revokes the accounts, queues the erase, records the request and answers with a status URL and a confirmation code. |
You set the two callback URLs once, in your Meta app dashboard on the Instagram and Messenger products: https://hookchat.dev/deauthorize and https://hookchat.dev/data-deletion. That is part of connecting an account. From then on the gateway answers Meta inside its time limit before doing the slow work.
What is erased#
The erase job is scoped to the person who authorised the app, and it removes everything HookChat holds for the accounts they connected:
- The connected accounts and their access tokens.
- Their conversations and every message in them.
- The delivered copies of their events: the webhook bodies the gateway sent you, and the stored payloads behind them.
- The send attempt records for those conversations.
A large account can take more than one run. The job stops at its time limit, queues itself again and carries on from where it left off, so a request stays in progress until the last row is gone. Only then is it marked complete.
The status page#
The status URL points at a plain page on the gateway. It shows the confirmation code, whether the request is in progress or complete, and the date it was received. It never shows who the person is or which accounts were involved. The code stays valid for 90 days, so the person can come back and check.
{
"url": "https://hookchat.dev/data-deletion/status?code=3f9c2b7e1a4d",
"confirmation_code": "3f9c2b7e1a4d"
}What complete means, and what it does not#
Complete means the accounts and everything listed above are gone. Two things are outside that and expire on their own. The raw inbound buffer, where the gateway keeps each event as it arrived from Meta, is not indexed by person and expires within 7 days. The delivery records for that account's events, with the bodies they carried, are erased too. Every other delivery record is kept for 90 days and then expires.
Without any request, message data does not stay long either. Each message expires 7 days after it was sent, and a conversation 7 days after its last message. The event body a delivery record carried expires after 7 days, while the record itself stays for 90.
The callback erase is scoped to the person who authorised the app, not to the people who messaged that account. Meta does not give the gateway a way to match a single customer of a page to a deletion request, so a request removes the account and all of its conversations, not one thread within it. To erase one customer, erase their conversation instead.
What is yours to do#
Every event the gateway delivered to your endpoint is a copy you hold. HookChat cannot reach into your systems, so when a request completes, delete what you stored for that account on your side. The events carry the account id, which is the key to find them. If you keep an audit of deletions, the request date on the status page is the one to record.
The same goes for one person: when you erase a conversation, delete what you stored about it too. The events you received carry the conversation id, which is the key to find them.