Retention windows and deletion
Retention on Orbit is not one setting — it is a set of independent windows over independent stores, each with its own default, its own allowed range, and its own thing that happens when the window elapses. Message bodies redact, recordings purge their media, video-room history hard-deletes, audit logs purge, and webhook delivery rows die with their endpoint. This page is the map across all of them: what lives where, how long it stays by default, what flips at expiry, and how the preservation controls (legal hold, WORM archive export) and the erasure controls (GDPR erasure) cut across the age-based machinery. The tenant-owned posture this map assumes — enable domains, pick windows, connect holds and archival — is configured on the Per-Domain Data Retention Policy page. This page is the architectural layer beneath it.The stores map
Every data class below is enforceable through a scheduled sweep, never a synchronous delete at the moment you save a policy. Tightening a window queues newly over-window records for the next sweep run; records already redacted or deleted do not come back.
Three consequences worth building against:
- Defaults are inert for the three policy domains. A workspace that never touches the data-retention endpoint has no automatic message, conversation, or audit-log retention behavior — only recordings (bucket lifecycle) and video rooms (90-day recording settings) expire without opt-in.
- Redaction and purge are different objects. Message retention redacts content and keeps billing-grade metadata; recording retention deletes media and keeps the call row; conversation delete removes the thread row. “Retention ran” never means “everything is gone.”
- Survivorship is billing-safe by design. Status, delivery receipts, segment counts, and prices are not personal content — they survive every window so finance and dispute workflows keep working on redacted or purged rows.
Tenant-configurable knobs
Two recording-side windows and three policy domains account for every window you can set. Recording and video-room windows are per-organization settings, exposed throughGET /api/v1/settings/retention (the dashboard renders the same knobs under compliance settings):
recording_days— the unified recordings window, clamped to 7–3650 days (7-day floor guarantees post-recording dispute lookback; the 3650-day ceiling cannot exceed the bucket lifecycle hard-purge). The sweep reads it; the bucket safety net caps every object at 365 days regardless.video_room_days— the video-room session-history window, 7–3650 days, default 90. It is a separate knob routed to a separate key, not part of the channel policy fields.
messages— 7–3650 days,0to disable.conversations— 30–3650 days; the 30-day floor blocks deleting a thread that closed hours ago.audit_logs— 365–3650 days; the 365-day floor is regulatory (SOC 2 examination window), and the2190-day fallback targets HIPAA’s expectation.
- Recording media at 365 days. The object-storage bucket lifecycle is a platform safety net — set any window you like under it, media still cannot survive past it.
- The audit floor. 365 days of audit evidence is non-negotiable; a mis-set shorter window returns a 422.
- Cross-knobs. Shrinking
recording_daysdoes not shrink messages or conversations, and disabling recording retention does not disable the policy domains. Each window is its own decision.
WORM archival export vs. operational purge
When your obligations outlive your retention windows, do not stretch the window — archive before the sweeps delete. WORM archival export (POST /api/v1/compliance/archival/export) is the retention-lock family from the export families model: a tamper-evident bundle (signed manifest, per-file SHA-256 chain, verification instructions) copied into your own S3 or WORM store. Its guiding semantics:
- Retention-lock replaces deletion. Anything you export before the window elapses is held by you, not by Orbit; the sweep still purges Orbit’s copy on schedule.
- The signed bundle, not the window, is your proof. The manifest stamps the lock promise (window, basis, version) so an auditor can verify the records were captured while the policy was in force.
- Archival and windows are decoupled by design. Windows answer “how long does Orbit hold this” — archival answers “how do I hold my own copy for longer.” An operator that has mirrored the signed bundle can let the operational sweep run and keep regulatory retention sovereign to its own store.
- Failure is loud. A bundle whose hash does not replay never lands silently in your archive; a mismatched
current_hashorprev_hashverdict tells you the chain broke.
Legal hold
A retention sweep is deletion machinery, so it shares space with preservation controls. A legal hold exempts its records from every eligible sweep for as long as the hold stands.- Per-recording holds.
PUT /api/v1/recordings/:id/legal-hold(with{ hold: true|false, reason }) flips a flag on the recording row and, when the recording is a video-room artefact, propagates the same flag to the linked video-room session row — every sweep that could reap the underlying media honors it. The flag survives release asfalse(rather than being deleted) so the audit trail of who set and cleared the hold is retained on the row. - Conversation-level aggregation. The same read merges to “hold the whole conversation” — the per-recording groups re-aggregate into one row behind
GET /api/v1/recordings/conversation/:id/legal-hold, and a batchedPUTtoggles every linked recording in one call. A conversation with no held recordings yieldsheldRecordings: 0— sweep-eligible on every row. - The hold wins while it stands. Retention defines the normal-operation posture; the hold defines litigation preservation. Set workspace windows for the default and use holds for the exceptions.
- Reconcile holds before erasure. Open holds and in-flight erasure requests interact per-contact — reconcile them in your DSAR process rather than expecting the windows to fulfill either.
GDPR erase vs. window expiry
Erasure and age-based retention are different machines on purpose:- DSAR erasure is contact-scoped and immediate-request-driven — a data-subject request runs its own workflow independently of the org-wide windows. It is not deferred until a window elapses, and it is not gated on a sweep cadence.
- Age-based windows are org-wide and scheduled — they enforce a posture, not a request.
- Per-record delete vs. window expiry. A GDPR erase deletes the contact’s records through its own path; a window’s expiry only flags rows as eligible for the next sweep.
- Posture check. A DSAR-scoped export surfaces whether a contact has erasure pending; the troubleshooting surface DSAR export failures distinguishes “nothing erased yet” from a genuinely failed export.
Boundary: platform-fixed vs. tenant-owned
The per-domain policy is a tenant-owned control end to end: Orbit provides the windows, the sweeps, and the audit trail — what the windows are is your decision. To configure the posture, walk the Per-Domain Data Retention Policy page and the wider GDPR posture guide.
Related
Per-Domain Data Retention Policy
Enable the message, conversation, and audit domains and pick their windows.
Legal Holds
Exempt recordings and conversations from retention sweeps for litigation.
Immutable Archival Export
Copy records into a signed, tamper-evident bundle before the sweeps delete them.
Export families model
The four export families and why WORM archival is its own family.
Call recording pipeline
Capture plane and ingestion — what the recording window actually purges.
Recording lifecycle
Recording states and QC verdicts the retention machinery sits beneath.
GDPR Posture Guide
Consent, DSAR, the register, and the binder around the retention posture.
Data Subject Requests
Contact-scoped access and erasure, independent of the windows.