> For the complete documentation index, see [llms.txt](https://docs.veilio.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.veilio.xyz/documentation/basics/data-lifecycle.md).

# Data Lifecycle: Retention and Crypto Shredding

Veilio supports lifecycle control for tokenized data through retention metadata and irreversible crypto shredding.

> **Important:** setting `retention` at tokenize time only **schedules** destruction. Tokens are shredded automatically **only if** a job calls `/api/internal/tokens/auto-shred` on a schedule. Without that job, expired tokens remain detokenizable.

***

#### Retention at tokenization time

When tokenizing data, you can define retention via:

| Field            | Type         | Description                                           |
| ---------------- | ------------ | ----------------------------------------------------- |
| `ttlDays`        | positive int | Shred after N days from tokenization                  |
| `retentionUntil` | ISO datetime | Absolute shred date (e.g. `2027-01-01T00:00:00.000Z`) |

Provide **one** of the two. Example:

```bash
curl -s -X POST "$VEILIO_BASE_URL/tokenize" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "john@example.com",
    "type": "email",
    "retention": { "ttlDays": 90 }
  }'
```

Response includes the resolved date:

```json
{
  "token": "tok_abc123...",
  "createdAt": "2026-07-26T08:00:00.000Z",
  "retentionUntil": "2026-10-24T08:00:00.000Z"
}
```

The same `retention` object works with `/tokenize/bulk`, `/tokenize/format`, and the JS/Python SDKs.

***

#### Auto-shredding (required for TTL / retentionUntil)

Internal route processes expired tokens in batches:

|          |                                               |
| -------- | --------------------------------------------- |
| Endpoint | `POST /api/internal/tokens/auto-shred`        |
| Auth     | `Authorization: Bearer $VEILIO_CRON_SECRET`   |
| Query    | `limit` (optional, default `500`, max `5000`) |

**What it does:** finds tokens where `retentionUntil <= now` and `shreddedAt` is null, then crypto-shreds them (encrypted payload cleared, detokenization returns `410 TOKEN_SHREDDED`).

**Configure the secret**

In your environment (required on **on-premise**; already set on Veilio SaaS):

```bash
VEILIO_CRON_SECRET=$(openssl rand -base64 32)
```

**Schedule the job**

Recommended: **hourly**. Example crontab on the host:

```cron
0 * * * * curl -fsS -X POST "https://your-domain.com/api/internal/tokens/auto-shred?limit=500" \
  -H "Authorization: Bearer $VEILIO_CRON_SECRET" \
  >> /var/log/veilio-auto-shred.log 2>&1
```

One-shot test:

```bash
curl -s -X POST "https://your-domain.com/api/internal/tokens/auto-shred?limit=500" \
  -H "Authorization: Bearer $VEILIO_CRON_SECRET"
```

Success response:

```json
{
  "processed": 12,
  "limit": 500,
  "executedAt": "2026-07-26T09:00:01.000Z"
}
```

If more than `limit` tokens expire at once, the next cron run continues the backlog.

| Environment                | Who runs the cron?                                      |
| -------------------------- | ------------------------------------------------------- |
| **SaaS** (`app.veilio.fr`) | Veilio — you only pass `retention` when tokenizing      |
| **On-premise**             | **You** — set `VEILIO_CRON_SECRET` and schedule the job |

See also: [Installation guide](https://docs.veilio.xyz/documentation/on-premise/installation-guide) (on-premise env + ops checklist).

***

#### On-demand shredding

Use `POST /api/tokens/shred` to shred a token immediately with an API key (GDPR erasure, early deletion, etc.).

```bash
curl -X POST "https://app.veilio.fr/api/tokens/shred" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"token": "tok_xxxxxxxxxxxx", "reason": "GDPR - user deletion request"}'
```

On-premise: replace the host with your instance URL (`https://your-domain.com/api/tokens/shred`).

> Do **not** use `DELETE /api/tokens/[id]` — that route is dashboard-only (browser session required) and will always return `401` when called with an API key.

**Request body**

| Field    | Type   | Required | Description                                       |
| -------- | ------ | -------- | ------------------------------------------------- |
| `token`  | string | Yes      | The `tok_...` value returned at tokenization time |
| `reason` | string | No       | Audit log label (max 500 chars)                   |

**Success (`200`)**

```json
{
  "token": "tok_xxxxxxxxxxxx",
  "shreddedAt": "2026-05-06T16:13:00.000Z"
}
```

**Error codes**

| HTTP | Code               | Cause                                       |
| ---- | ------------------ | ------------------------------------------- |
| 401  | `AUTH_ERROR`       | Missing, invalid, or revoked API key        |
| 404  | `NOT_FOUND`        | Token not found                             |
| 403  | `FORBIDDEN`        | Token belongs to a different organization   |
| 400  | `VALIDATION_ERROR` | Missing `token` field or invalid body shape |

SDK equivalents: `client.shredToken({ token, reason })` (JS) / `client.shred_token(token, reason=...)` (Python).

***

#### Detokenization behavior after shredding

Once shredded, detokenization returns:

* HTTP status: `410`
* code: `TOKEN_SHREDDED`

The operation is irreversible: encrypted data and search index are cleared.

***

#### Operational guidance

* Use retention defaults for sensitive classes (email / phone / ID).
* Keep shred `reason` values meaningful for auditability.
* On-premise: treat auto-shred as a **production go-live requirement** if you use `ttlDays` / `retentionUntil`.
* Monitor cron logs (`processed` count) so a silent auth failure (`401`) does not leave expired data live.
* Prefer hourly (or more frequent) runs for predictable compliance; increase `limit` if you ingest large batches with short TTLs.

***

#### Related links

* [SDK Javascript](https://docs.veilio.xyz/documentation/getting-started/sdk-js)
* [SDK Python](https://docs.veilio.xyz/documentation/getting-started/sdk-python)
* [HTTP Integration](https://docs.veilio.xyz/documentation/getting-started/http-integration)
* [Installation guide (on-premise)](https://docs.veilio.xyz/documentation/on-premise/installation-guide)
* [Go-live Checklist](https://docs.veilio.xyz/documentation/help/golive-check)
