> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dairo.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Data erasure

> Erase a person's data — or wipe an inbox — and get a signed certificate proving it happened.

When someone exercises their right to be forgotten, delete their data *and* prove
you did. An erasure job does both: it removes a person across all your stored mail
(or wipes a whole inbox), and when it finishes it hands you a signed certificate —
your GDPR or CCPA evidence, pulled on demand instead of chased over email.

Erasure runs as a durable background job, so a large deletion completes reliably
even if it takes a while. Reads use `compliance:read`; the deletion itself uses
`compliance:write`.

## Start an erasure

`POST /v1/erasure-jobs` takes a small body. Set `type` to `subject` with a
`subjectHandle` to erase a person across all your stored mail, or `type` to
`inbox` with an `inboxId` to wipe an inbox. The job is accepted right away and
comes back `pending`.

<CodeGroup>
  ```bash title="cURL" theme={null}
  # Erase a person across all stored mail
  curl -X POST https://api.dairo.app/v1/erasure-jobs \
    -H "Authorization: Bearer $DAIRO_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: erase-ada-2026-06" \
    -d '{ "type": "subject", "subjectHandle": "ada@example.com" }'

  # Or wipe an inbox wholesale
  curl -X POST https://api.dairo.app/v1/erasure-jobs \
    -H "Authorization: Bearer $DAIRO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "type": "inbox", "inboxId": "7c9e6679-7425-40de-944b-e07fc1f90ae7" }'
  ```

  ```ts title="TypeScript" theme={null}
  const job = await dairo.erasureJobs.create(
    { type: "subject", subjectHandle: "ada@example.com" },
    { idempotencyKey: "erase-ada-2026-06" },
  );
  console.log(job.jobId, job.status); // "pending"
  ```

  ```python title="Python" theme={null}
  job = dairo.erasure_jobs.create(
      type="subject",
      subject_handle="ada@example.com",
      idempotency_key="erase-ada-2026-06",
  )
  print(job.job_id, job.status)
  ```

  ```text title="MCP" theme={null}
  # Enqueuing an erasure job has no MCP tool — use REST POST /v1/erasure-jobs
  # (scope compliance:write). The get_compliance_reports tool is read-only:
  # { "action": "getErasureJob", "jobId": "…" } to poll a job you already created.
  ```
</CodeGroup>

```json theme={null}
{
  "object": "erasure_job",
  "jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "erase_subject",
  "status": "pending",
  "createdAt": "2026-06-12T10:00:00Z"
}
```

<Note>
  Pass an `Idempotency-Key`. Retrying with the same key returns the same job instead
  of enqueuing a second erasure — so a network retry can never double-delete or spawn
  a duplicate. See [idempotency](/concepts/idempotency).
</Note>

## Poll to completion

`GET /v1/erasure-jobs/{jobId}` returns the full job. Poll until `status` is terminal
(`completed` or `failed`). Once it's `completed`, the job carries exact deletion
tallies and the signed certificate.

<CodeGroup>
  ```bash title="cURL" theme={null}
  curl https://api.dairo.app/v1/erasure-jobs/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
    -H "Authorization: Bearer $DAIRO_API_KEY"
  ```

  ```ts title="TypeScript" theme={null}
  const job = await dairo.erasureJobs.get("3fa85f64-5717-4562-b3fc-2c963f66afa6");
  console.log(job.status, job.deleted);
  if (job.certificate) console.log("signed certificate:", job.certificate.signature);
  ```

  ```python title="Python" theme={null}
  job = dairo.erasure_jobs.get("3fa85f64-5717-4562-b3fc-2c963f66afa6")
  print(job.status, job.deleted)
  ```
</CodeGroup>

```json theme={null}
{
  "object": "erasure_job",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "erase_subject",
  "subjectHandle": "ada@example.com",
  "inboxId": null,
  "status": "completed",
  "deleted": {
    "messages": 42,
    "threads": 7,
    "attachments": 11,
    "storedFiles": 11,
    "ledgerRowsRedacted": 0
  },
  "certificate": { "type": "dairo.deletion.certificate.v1", "signature": "…", "kid": "dairo-ed25519-2026-06", "alg": "EdDSA" },
  "createdAt": "2026-06-12T10:00:00Z",
  "completedAt": "2026-06-12T10:00:30Z"
}
```

The `deleted` tallies count exactly what was removed — messages, threads,
attachments, stored files, and any redacted event-ledger rows. The `certificate` is a
signed artifact: verify its signature against the published
[JWKS](/agents/agent-passport#verify-a-signed-message) and you can prove to an auditor that the deletion
happened, when, and at what scope. Keep it with your compliance records.

## List your jobs

`GET /v1/erasure-jobs` returns your jobs, newest first.

<CodeGroup>
  ```bash title="cURL" theme={null}
  curl "https://api.dairo.app/v1/erasure-jobs?limit=25" \
    -H "Authorization: Bearer $DAIRO_API_KEY"
  ```

  ```ts title="TypeScript" theme={null}
  const { data: jobs } = await dairo.erasureJobs.list({ limit: 25 });
  ```

  ```python title="Python" theme={null}
  jobs = dairo.erasure_jobs.list()
  ```
</CodeGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Data residency" icon="earth-europe" href="/compliance/residency">
    Where your data lives and who controls it.
  </Card>

  <Card title="Tamper-evident audit export" icon="file-signature" href="/compliance/audit-export">
    A verifiable export of the audit trail.
  </Card>

  <Card title="API reference" icon="code" href="/api-reference">
    `GET` / `POST` `/v1/erasure-jobs` and `GET /v1/erasure-jobs/{jobId}`.
  </Card>
</CardGroup>
