---
title: "Delete a company and its entire timeline"
method: DELETE
path: "/api/v1/ackdb/entities/{entityId}"
tags: ["ackDB"]
---

# Delete a company and its entire timeline

`DELETE /api/v1/ackdb/entities/{entityId}`

## Request

- Base URL: `http://localhost:3009`
- URL: `http://localhost:3009/api/v1/ackdb/entities/{entityId}`
- Auth: HTTP bearer

Hard-deletes the account and everything on it, archived and restorable, with its identity links frozen as a tombstone so a re-sync cannot re-mint it.

**Goes:** contact edges (+ links, traits, relationship ownership), events, raw payloads, files, traits, identity links, member assignments, embedding chunks + conversations (derived — deleted, never archived), segment memberships (each preceded by an `exit` so Segment Sync consumers do not hold a member that no longer exists), and any human the delete leaves with no affiliation and no evidence anywhere.

**Stays:** file BLOBS (the archive references them; a permanent purge deletes them), `/ask` transcripts (detached — the conversation is the user's, not the record's), and the schema registry, segments and score definitions (config, not data). The unresolved pool is untouched; the tombstone guard fires at promotion time instead.

System events (`entity.created`, `member.assigned`, `score.changed`, …) die WITH the record: #419's rule protects the audit log of SURVIVING state, and here the state and its log leave together.

## Path parameters

- `entityId` string, required

## Query parameters

- `dryRun` boolean

## Request body

- object
  - `reason` string: Why — stored on the archive header.
  - `actor` string: Who — console user email; null for service calls.
  - `dryRun` boolean: Same as ?dryRun=true, for clients that cannot send query params.

## Response `200`

Deleted (or previewed). Returns what was deleted, what was detached, what was deliberately retained, and the tombstone that now guards the record's identifiers.

- AckdbRecordDeletionResponse
  - `data` object
    - `dryRun` boolean
    - `deletionId` string, nullable: Null on a dry run — no header is written.
    - `kind` 'company' | 'person' | 'contact'
    - `record` object
      - `id` string
      - `label` string, nullable
    - `deleted` AckdbRecordDeletionCounts: Per-table row counts a delete removed. Every field is always present (0 when untouched).
      - `events` integer: Deleted. 0 for person/contact deletes — those DETACH instead.
      - `rawPayloads` integer
      - `files` integer
      - `contentChunks` integer: Derived: deleted, never archived; rebuilt by `npm run embed`.
      - `conversations` integer: Derived: rebuilt by `npm run conversations`.
      - `contacts` integer
      - `persons` integer: The record itself (person delete) or husks left behind.
      - `entities` integer: The record itself plus any merge tombstones pointing at it.
      - `identityLinks` integer
      - `contactIdentityLinks` integer
      - `personIdentityLinks` integer
      - `traits` integer: entity_traits + contact_traits + person_traits (attributes ride the same rails).
      - `memberAssignments` integer
      - `mergeCandidates` integer
      - `segmentExits` integer: Memberships removed, each preceded by an `exit` in segment_changes.
      - `relationships` integer: Explicit company relationship episodes deleted.
      - `contactRelationships` integer: Contact hierarchy episodes deleted.
    - `detached` object: Pointers nulled on rows that SURVIVE — events kept on company timelines, agent sessions.
      - `events` integer
      - `agentSessions` integer
    - `tombstone` object
      - `active` boolean
      - `identifiers` object[]: The frozen `(type, value)` pairs, stored exactly as the resolvers store them (domains as ingested, emails lowercased, LinkedIn canonical) — the guard compares with plain equality.
        - `type` string
        - `value` string
    - `retained` object[]: What the delete deliberately left standing, and why (the #419 honesty trio).
      - `kind` string
      - `count` integer
      - `reason` string
    - `pendingRebuild` object[]: Always empty on a delete (a deleted company has nothing left to rebuild content for, and a person/contact delete does not touch content). A RESTORE is what populates it.

## Other responses

- `404`: No such record.
- `409`: `MERGED_ENTITY` / `MERGED_PERSON` — the reference names a merge tombstone (delete the survivor; its tombstones go with it). `PENDING_INGEST_CONFLICT` — a queued ingest would resurrect the data or dead-letter on the missing record; retry once the queue drains.

---

[API](https://skmtc.dev/floqer/apis/floqer-public-api.md) - [All operations](https://skmtc.dev/floqer/apis/floqer-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/floqer/apis/floqer-public-api/revisions/fce50dc07b20?raw)
