Picture this: it's audit season, and someone from compliance asks a question every engineering team dreads — "Can you prove this record was deleted, when it happened, and what it said before it was removed?" In most databases, the honest answer involves a backup restore, a grep through logs, and a prayer. In SapixDB, it's a handful of well-defined API calls, because deletion, in this system, was never a single blunt operation. It's four distinct, deliberately separate primitives — and knowing which one to reach for is the whole lesson.

This post walks through a realistic scenario — a healthcare support-ticket system with HIPAA-grade retention obligations — to show exactly how SapixDB's tombstones, soft-deletes, restores, and time travel fit together, plus how the actual Retention Policy feature automates the whole thing.

The Scenario: A Compliance Archive for Support Tickets

Suppose you run support-tickets-agent, an agent that owns every customer support ticket your company has ever logged. Some of those tickets contain protected health information (PHI). Compliance requires that resolved tickets be removed from everyday view after 180 days, that removals are provably logged, and that — if a removal turns out to be a mistake — someone can undo it without touching a backup tape.

Creating the agent itself requires an admin-scoped key:

POST /v1/agents Authorization: Bearer <admin-key> { "agent_id": "support-tickets-agent", "seed_hex": "4f3c9a1e...64-char-hex-seed" } 

This call needs an admin-scoped key — it's not something a regular service key can do — and it silently writes the agent's genesis block for you.

Writing a ticket is a normal append:

POST /v1/agents/support-tickets-agent/records { "data": { "type": "ticket", "id": "TCK-4821", "status": "resolved", "priority": "high", "assigned_to": "lena.fischer" }, "flags": 0 } 

Now the compliance clock starts ticking on TCK-4821. Here's where the four primitives come in — and where most teams, understandably, get confused.

Four Operations, One Mental Model

It's worth saying plainly: these are four distinct things, and they are not interchangeable.

  • Gone from view → tombstone (flags: 2)
  • Compliance record that it was removed → soft-delete (DELETE, admin only)
  • Want it back → /restore
  • Want to know what it used to say → as_of

Tombstone: Making a Record Disappear From Normal Queries

A tombstone is what makes a ticket stop showing up in the support dashboard's "Current" and "CountCurrent" views. The data is never erased — it's just no longer considered current.

POST /v1/agents/support-tickets-agent/records { "data": { "_original_hash": "3a7fcd91..." }, "flags": 2 } 

Use this when the requirement is "this row should no longer appear in the app's normal view."

Soft-Delete: An Audit Marker, Not a Disappearance

This is the one people most often get wrong. The soft-delete endpoint is admin-scoped only, and it does not hide the record from ordinary queries:

DELETE /v1/agents/support-tickets-agent/records/3a7fcd91... Authorization: Bearer <admin-key> 

This writes a {"_deleted": true, "_original_hash": "3a7fcd91..."} marker — but critically, it does not set the tombstone flag. The original ticket still shows up in normal queries. It exists purely as a compliance trail, discoverable via:

GET /v1/agents/support-tickets-agent/records/deleted 

If your mental model is "soft-delete makes it disappear," unlearn that now. It's an audit marker. Tombstoning is the thing that hides it.

Restore: The Real One-Call Undo

This is SapixDB's actual answer to "oops
Free Community edition available at sapixdb.com