Legal Holds on Messaging Conversations
A legal hold (litigation hold) preserves a messaging conversation for eDiscovery. When you place a hold on a conversation, every message in that thread is exempt from the age-based retention sweep — the sweep skips both the media-null step and the hard-delete step — so the thread survives for litigation preservation, supervision review, or a regulator’s request. This page covers messaging conversations (SMS, MMS, WhatsApp, RCS, email, chat); for voice and video recordings, the same hold is exposed on the Settings → Compliance → Legal holds screen under recordings.What a hold protects you from
Retention is designed to delete. Under Settings → Compliance → Retention, each channel has a window; once a message ages past it, the retention sweep first clears the message’s media (themedia_url is nulled), then — when
your retention policy applies hard delete — removes the message row
entirely. That is the right posture for storage limitation in normal
operation, and the wrong posture when counsel notifies you that a matter is
anticipated or ongoing.
A legal hold inverts that for one conversation: place the hold, and the
retention sweep skips the thread for as long as the hold stands. Messages
that arrive after the hold was placed are also protected — the hold
belongs to the conversation, not just to the messages that existed at the
moment you placed it.
A held conversation is also protected against direct destruction: a
hard-delete of a held conversation is refused with
409 legal_hold_active, so no operator — admin included — can destroy a
preserved thread without first releasing the hold.
A hold does not change what you can read or export. Held threads remain
fully visible in the dashboard and through the conversations API; the hold
only stops the deletion machinery.
Place or release a hold
The hold surface is one endpoint pair per conversation. Placing and releasing require an owner or admin role; reads use the same gate. Every write is recorded in your audit log (see Audit trail).Check the current hold state
legal_hold—truewhile the conversation is exempt from the retention sweep.reason— the free-text justification recorded with the last change (up to 512 characters).updated_by/updated_at— who changed the hold most recently and when.message_count/held_message_count— the protected fraction of the thread, so you can confirm the hold actually propagated.
404.
Place the hold
Sendhold: true with the reason your matter-management process requires:
messages_updated — the number
of existing message rows the hold was propagated to. Placing a hold is
idempotent: re-sending hold: true on an already-held conversation simply
re-stamps the reason and timestamp.
Release the hold
When the matter is closed and counsel confirms preservation may end, release withhold: false:
Who can place a hold
Legal-hold reads and writes both require an owner or admin API key or dashboard role. Preservation is a compliance-governance decision, so the surface is deliberately kept off the everyday messaging operator role. A caller without the role receives403.
Audit trail
Every place-or-release call is written to your workspace audit log with the resulting hold state, the recorded reason, and the number of messages the hold propagated to. An auditor can reconstruct the preservation chain — who held which conversation, why, when, and when it was released — from the audit log alone. The most recent reason, actor, and timestamp also stay readable on the conversation itself via theGET endpoint.
How the hold interacts with retention and erasure
- Age-based retention sweep. Held conversations are skipped entirely — no media-null, no hard-delete — for as long as the hold stands. This includes messages that arrive after the hold was placed.
- Admin hard-delete. Refusing to destroy a held conversation is by
design: the hard-delete path returns
409 legal_hold_activeuntil the hold is released. Use the reversible archive option if you merely want the thread out of the inbox. - DSAR / erasure requests. A legal hold is a preservation obligation, not a defensible-disposal shortcut — GDPR erasure and litigation preservation can genuinely conflict, and that conflict is resolved by your counsel, not by the platform. Erasure workflows do not silently override a held thread; reconcile holds against open erasure requests as part of your DSAR process (see Data subject requests).
- Immutable archival. A hold preserves the live thread in place; an archival export produces a tamper-evident copy you pin into your own WORM store. For matters likely to outlive your Orbit retention windows, run both: hold the thread, then archive it.
How the flag reaches the sweep
A messaging hold is a flag on the existingmetadata JSON column — no schema
change, no migration, nothing to provision before you can place a hold. The
hold is stored under the key legal_hold as a JSON boolean, alongside three
sibling keys the hold writes at the same time:
legal_hold—truewhile the conversation is exempt from the sweep.legal_hold_reason— the free-text justification recorded with the last change (up to 512 characters).legal_hold_updated_by— the user id of the operator who last changed the hold.legal_hold_updated_at— the ISO timestamp of the last change.
metadata.legal_hold
reads as the text true. A row with the key absent (JSON null) or set to
false is not held and stays sweep-eligible — so a conversation that was
never held, or a hold you have released, behaves exactly like every other
row. The predicate is a strict equality: only an explicit true removes a
thread from the swept set.
Why the flag is placed on the conversation, not each message
The retention sweep that reaps message media keys onmessages.metadata
per row. To exempt a whole thread it is not enough to flag the conversation
row — the sweep would still reap each message’s media_url and, when your
policy applies hard delete, delete each message row on age. So placing a
hold does two writes in one call:
- Stamp
legal_hold: trueon the conversation row. - Propagate the same flag to every
messagesrow already in that conversation.
false on the conversation and on every message row, so the thread
rejoins the normal sweep on the next cycle. The sibling audit keys
(legal_hold_updated_by, legal_hold_updated_at) are kept on release
rather than deleted, so the row still shows who released the hold and when.
What the hold protects against
The age-based sweep runs in two steps for each message that ages past its per-channel window: first it nullsmessages.media_url (clearing the
stored media), then — only when your retention policy sets
apply_hard_delete — it deletes the message row outright. A hold exempts
the thread from both steps for as long as it stands: the media is not
nulled and the row is not deleted, even when hard delete is enabled. This
is the protection that matters for regulated buyers — a conversation under
an active matter survives the media-nulling step and the
apply_hard_delete row-removal step, not just one of them.
For the per-channel windows and the apply_hard_delete toggle, see
Per-Domain Data Retention Policy.
Re-applying a hold is a no-op
Placing a hold on a conversation that is already held does not duplicate or escalate the hold — it re-stamps the reason, actor, and timestamp on the conversation and every message row, and returns the resulting state. You can re-run a place-hold call as many times as your matter-management process needs (for example, to refresh the recorded reason) without changing the sweep’s behaviour. The response’smessages_updated reports the number of
existing message rows the flag was propagated to in that call.
eDiscovery readiness
A legal hold delays the retention sweep; it does not assert that any particular regulation is satisfied. Whether a hold is sufficient for a given matter, how long it must stand, and which conversations it must cover are your counsel’s calls — Orbit provides the exemption, the audit trail, and the API surface, not the retention determination. Every place-or-release call is written to your workspace audit log with the resulting hold state, the recorded reason, the actor, the timestamp, and the number of message rows the hold propagated to. An auditor can reconstruct the preservation chain — which conversations were held, by whom, for what stated reason, when each was placed, and when each was released — from the audit log alone. To assemble a production-ready evidence bundle for a matter, pair the hold with an immutable archival export of the preserved thread.Worked example: hold a conversation by id, then release it
The hold surface keys on a conversation id, not a message id — the hold applies to the whole thread. Find the conversation id in the conversation view in the dashboard or in theconversation_id field of any message in
the thread.
Place the hold:
hold: false:
Manage holds in the dashboard
Go to Settings → Compliance → Legal holds. The screen covers both preservable entity kinds side by side:- Messaging conversations — paste the conversation id (visible in the conversation view and in the API), read the current hold state with its held/total message tally, and place or release the hold with a reason.
- Voice and video recordings — the equivalent hold for recording ids, exempting them from the media-deletion retention sweep.
Your preservation posture stays yours
Legal holds are a tenant-owned control: Orbit provides the exemption, the audit trail, and the API surface — when preservation must start, which conversations it covers, what reason is sufficient, and when it may end are your organization’s decisions. Nothing places a hold automatically; every hold exists because an owner or admin in your workspace created it, and every one of those decisions is auditable.Related
Immutable Archival Export
Copy preserved records into a tamper-evident bundle for your own WORM
store.
Data Subject Requests
Access and erasure workflows, and how to reconcile them with open holds.
Per-Domain Data Retention Policy
The per-channel retention windows and the hard-delete toggle a hold
exempts a thread from.
Evidence Binder
Assemble audit-ready evidence bundles from the controls you configured.
SOC 2 Controls
The broader control environment around logging and access.