Data retention
Two opt-in settings that remove WhatsApp message content from Linq's systems on a schedule, what they keep, and how to build around them.
By default, we keep message content under the standard policy described throughout this API. Two opt-in settings remove it sooner: ephemeral messages and zero-day retention. They only apply to messages created after they’re turned on, and if both are on, zero-day retention wins.
Both settings remove message content: text, attachments, and the other parts of a message. The record that a message existed stays. That means its IDs, chat, phone numbers, timestamps, direction, delivery status, and billing records.
What’s removed and what’s kept
Section titled “What’s removed and what’s kept”| Removed | Kept |
|---|---|
| Message text | Message and chat IDs |
| Attachment files | Phone numbers |
| Every other part of a message’s content | Timestamps and direction |
Delivery status and message.sent / message.delivered / message.read events |
|
| Billing records | |
| The attachment’s ID |
What these settings cover
Section titled “What these settings cover”They cover the copies Linq holds: our databases, storage, queues, and backups. They don’t reach Meta.
WhatsApp messages sent and received through Linq go through Meta’s hosted WhatsApp Business Platform. Meta decrypts and processes the content on its own servers and keeps its own copy under its own terms. Turning on either setting doesn’t change what Meta keeps or for how long.
Ephemeral messages
Section titled “Ephemeral messages”Content is removed after a window set for your account, anywhere from 1 to 24 hours (24 hours by default). The window applies to your whole account, to messages you send and messages you receive, and it starts when the message is created.
A message you’re still sending keeps its content until delivery finishes, even if that runs past the window. The same goes for a message whose delivery result we’re still waiting on. Messages you receive don’t have that hold.
Once the window has passed:
- The message disappears from transcript reads, the event log, the live stream, and replays. Transcripts normally have no gaps in their sequence numbers, and expired ephemeral messages are the one exception.
- Its IDs, timestamps, phone numbers, direction, delivery status, and billing records stay, and keep working normally.
- There’s no expiry timestamp in the API. If you need to know when a message
will go, add your window to its
created_at. - An idempotent retry of the send returns empty
partsonce the content is removed.
Removal isn’t instant. Treat the window as a minimum; content usually goes within a few minutes after it.
Zero-day retention
Section titled “Zero-day retention”The rule, in one table
Section titled “The rule, in one table”| Messages you send | Messages you receive | |
|---|---|---|
| Where you see the content | The response to your send request | Your webhook deliveries for that message |
| Transcript, event log, stream, replays | No content, ever | No content, ever |
| How long we hold it | Until delivery finishes | Until every webhook endpoint has it, or has spent 35 minutes returning errors |
An idempotent retry of a send returns empty parts and zero_retention: true.
For messages you receive, the webhook is the only way to get the content. The live stream and the event log never carry it, even right after the message arrives.
Content you receive is removed once every webhook endpoint subscribed to it has received it successfully, or has spent 35 minutes returning errors. Only time when your endpoint is returning errors counts. Network trouble, problems on our side, and scheduling delays don’t. One endpoint running out its 35 minutes never removes content another endpoint is still owed.
An attachment on a zero-day message has its own clock. It’s removed after your first completed download, or about 35 minutes after the webhook that carried it was received, whichever comes first. Time when our download endpoint is failing doesn’t count.
How to tell a message is zero-day
Section titled “How to tell a message is zero-day”Zero-day messages carry zero_retention: true, both in webhooks and when you
read them back. On every other message the field is absent. Check this field
on each payload rather than keeping your own list of which numbers are
zero-day, because settings can change.
{ "id": "evt_example", "type": "message.received", "timestamp": "2026-09-24T11:00:00Z", "data": { "message": { "id": "msg_example", "direction": "inbound", "parts": [{ "type": "text", "body": "I'd like to reschedule" }], "zero_retention": true } }}{ "id": "msg_example", "direction": "inbound", "parts": [], "zero_retention": true}The values are just examples. An empty parts on a zero-day message is
expected, not an error.
Attachments
Section titled “Attachments”The same attachment can belong to more than one message, for example one upload sent to several customers. We keep it until every message that uses it is due for removal and no delivery in progress still needs it. If any message using it has standard retention, the attachment stays available.
Once an attachment is removed, downloading it returns an error instead of the file.
Edge cases
Section titled “Edge cases”A few things work differently from the rules above. In each case we keep content longer than the setting says; we never remove it early.
- Backups. A backup taken before content was removed can briefly still hold it.
- Messages received during a database outage. If we accept a message while we can’t check your settings, it’s kept under standard retention, even after things recover. We never apply a setting to it later.
- Messages we couldn’t process. If a message runs into a processing problem after we accept it, we keep it until someone on our side resolves it by hand. This is the one case with no time limit.
Sending and delivery don’t change
Section titled “Sending and delivery don’t change”Messages under either setting send, deliver, and report status like any
other message. POST /v1/messages,
POST /v1/chats/{chat}/messages, and the usual
message.sent, message.delivered, and message.read events all work
normally. Only how long we keep the content changes.
Nothing tells you when content has been removed. Save what you need from the send response or the webhook when it arrives, because that may be your only chance.
Best practices
Section titled “Best practices”- Save what you need when you first see it. For zero-day messages, the send response and the webhook are the only places the content appears.
- Make sure every zero-day number has a webhook endpoint. Without one, you never receive its inbound content.
- Download zero-day attachments right away. They’re removed after your first download, or about 35 minutes after the webhook.
- Don’t treat an empty
partsas an error on a zero-day message, or a missing message in a transcript on an ephemeral account. - Check
zero_retentionon each payload instead of guessing from the number or chat.
Related
Section titled “Related”- Sending messages — send routes, idempotency, and delivery outcomes
- Attachments — upload, download, and the authenticated attachment URL
- Webhooks — registering endpoints and verifying deliveries
- Events and recovery — the live stream and the event log
- Errors — the envelope and the code ranges