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

# Privacy, erasure and export

> Data subject rights by API, erasure by lineage, and continuous export to your bucket.

Your company is the controller of the data; Niadra acts as the processor, under a signed DPA. Every data subject right has an API: access and portability through `export`, correction through `feedback`, erasure through `forget`, and objection to profiling through the pattern opt-out. Erasure follows lineage, walks through everything derived from the data and ends with a receipt. Your data never trains models, neither ours nor anyone else's.

## The laws, by name

The same design covers the common core of GDPR and UK GDPR, CCPA/CPRA and the US state privacy laws, PDPA, APPI, DPDP, PIPA and LGPD: data residency in a single region, controller and processor roles, rights by API, configurable retention, erasure with a receipt, no training on your data and a published list of subprocessors. For other countries, the applicable law goes in the contract annex. Sector regimes, DORA for financial entities in the European Union, HIPAA for healthcare in the United States and the EU AI Act for companies that operate agents in the European Union, are also covered in the contract annex.

Each space’s data stays in its region. The control plane holds no customer content, and AI providers are called only in the same region.

## Forget

[`POST /v1/forget`](/en/api/forget) takes a `target` (`profile`, `handle` or `conversation`) and the matching `profile_id`, `handle` or `conversation_id`. It takes a Console person with the `security` role, or a key with the `admin` scope, and requires an `Idempotency-Key`: the same request sent twice starts one erasure.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://acme-prod.us-east-1.api.niadra.com/v1/forget" \
    -H "Authorization: Bearer $NIADRA_TOKEN" \
    -H "Idempotency-Key: $(uuidgen)" \
    -H "Content-Type: application/json" \
    -d '{
      "target": "handle",
      "handle": {"type": "phone_e164", "value": "+14155550123"}
    }'
  ```

  ```python Python theme={null}
  import os
  import uuid
  import httpx

  response = httpx.post(
      "https://acme-prod.us-east-1.api.niadra.com/v1/forget",
      headers={
          "Authorization": f"Bearer {os.environ['NIADRA_TOKEN']}",
          "Idempotency-Key": str(uuid.uuid4()),
      },
      json={
          "target": "handle",
          "handle": {"type": "phone_e164", "value": "+14155550123"},
      },
  )
  erasure = response.json()  # {"request_id": "...", "status": "pending", "target_kind": "handle", ...}
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch("https://acme-prod.us-east-1.api.niadra.com/v1/forget", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.NIADRA_TOKEN}`,
      "Idempotency-Key": crypto.randomUUID(),
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      target: "handle",
      handle: { type: "phone_e164", value: "+14155550123" },
    }),
  });
  const erasure = await response.json();
  ```
</CodeGroup>

The answer is 202 with a `request_id` and `status: "pending"`. Follow it with [`GET /v1/forget/{request_id}`](/en/api/forget-status) (`pending`, `running`, `completed` or `failed`, with what was `erased` and when it `completed_at`), or list every erasure of the space with [`GET /v1/forget`](/en/api/forget-list), filtered by `status`. The erasure walks the whole lineage, in this order:

1. The content of the events (a minimal tombstone stays).
2. Mentions, and the facts left without evidence, including facts about an account the person spoke about.
3. Episodes and open items.
4. Business objects owned by the handle.
5. The personal content of actions. Operation, amount and time stay only if you declared a legal retention duty.
6. Patterns, derived again without the erased evidence.
7. Links to accounts and partners, which are ended.
8. Measurement rows, review samples and trigger payloads.
9. Vectors, compiled context and files in storage.
10. Tombstones in the continuous export, and purged caches.

It ends with the **erasure receipt** (its hash comes back as `receipt_hash`), which also lists, in `export_run_ids`, the export runs that already contained the data, and with the `erasure.completed` webhook, so you can purge your own data lake. Niadra never enters your bucket to delete. Old read receipts keep only hashes: they prove a read happened without keeping the content.

Forgetting a person never erases the account it was linked to, and forgetting an account never erases its contacts' personal memory. See [Accounts and partners](/en/concepts/accounts).

## Where each copy lives, and how long it stays

| Storage                | Retention                                                | How forget reaches it                                       | Deadline |
| ---------------------- | -------------------------------------------------------- | ----------------------------------------------------------- | -------- |
| Live database          | The data class of your space                             | Deletion and tombstone                                      | 24 hours |
| Automatic backups      | Up to 35 days                                            | Expiry                                                      | 35 days  |
| Raw payloads and media | 30 to 90 days (unmapped types: 7 days)                   | Deletion by space and handle                                | 24 hours |
| Cold event archive     | Set by your space                                        | Only the affected rows are rewritten                        | 30 days  |
| Cache and recent turns | 24 hours after the context covers them, 72 hours at most | Keys purged; reads never serve erased data after a failover | Minutes  |
| AI providers           | Zero retention                                           | Nothing to erase                                            | None     |
| Logs and traces        | 30 days, with no content                                 | Nothing to erase, proven by a canary test                   | None     |
| Your bucket (export)   | Set by you, the controller                               | Tombstones and `erasure.completed`                          | Yours    |

## Export on demand

[`POST /v1/export`](/en/api/export) builds the access and portability package of one data subject, by `profile_id` or `handle`: events, facts, episodes, open items, objects, actions, patterns with their evidence, and links. It answers 201 with the `run_id`, the list of `files`, their `sha256`, and a short-lived `download_url` (until `download_expires_at`). [`GET /v1/exports/{run_id}/download`](/en/api/export-download) serves the package again with the same authorization. Both are `security` routes, and every download is recorded.

## Continuous export to your bucket

Besides the on-demand package, your space can schedule a continuous export that writes the memory, incrementally, to your own bucket. The data is yours; Niadra is not your data lake.

* **Destinations:** S3, GCS or Azure Blob, in the region of your space, checked at setup and on every run.
* **Credential:** write-only, provided by you (an assumed role or a write-only key), written from the Console, or with [`PUT /v1/exports/destinations/{schedule_id}/credential`](/en/api/export-destination-credential), straight into the vault of your cell; the answer carries only the new `version`. Never a read credential.
* **Format:** Parquet, one file per table and period, with a schema version, a JSON manifest and a SHA-256 per file.
* **Tables:** events, conversations, episodes, facts and mentions, open items, objects and object events, actions, patterns and evidence, receipts and context use, and the identity that ties it all to the customer (handles, profiles, links, assertions, merge log).
* **Incremental:** every row comes with `op` (`upsert` or `delete`); tombstones have a file of their own. Erased rows are skipped and listed as `erased` in the manifest, and a correction file closes any gap.
* **Frequency:** hourly or daily, one schedule per destination, with a minimum interval of one hour.

Content leaves decrypted only on its way to your bucket, which encrypts it with your key. A pseudonymized export is available for analytics. Every run, scheduled or on demand, is listed with its sequence range, status and manifest at [`GET /v1/exports/runs`](/en/api/export-runs).

## What stays protected by design

* Personal data never goes in a URL: phones, e-mails, document numbers and free text travel only in request bodies, so they never reach balancer logs or traces.
* Content is encrypted with AES-256-GCM under a key exclusive to your company, held in an HSM with FIPS 140-3 validation, on top of TLS 1.3 in transit.
* Sensitive data is masked before reaching any AI model that processes conversations; your agent receives it only after the verification your policy requires.
* Retention is configurable per data class, and expired data is erased for real.

## Next steps

<CardGroup cols={2}>
  <Card title="Receipts and audit" href="/en/concepts/receipts">
    the trail every erasure and read leaves.
  </Card>

  <Card title="Forget" href="/en/api/forget">
    the endpoint in detail.
  </Card>

  <Card title="Patterns" href="/en/concepts/patterns">
    objection to profiling and pattern retraction.
  </Card>

  <Card title="Security and privacy on the site" href="https://niadra.com/en/recursos">
    the six layers that protect the data.
  </Card>
</CardGroup>
