> 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/great-to-know/migration.md).

# Historical Migration Mode

Import a large existing database (e.g. 150k contacts from a CRM export) without consuming your monthly plan quota. Day-to-day operations after migration still use your normal plan limits (Starter, Pro

### When to use it

| Scenario                                         | Use migration mode?                 |
| ------------------------------------------------ | ----------------------------------- |
| One-time CSV/JSON import of historical PII       | ✅ Yes                               |
| Ongoing tokenization in production (forms, APIs) | ❌ No — use a standard API key       |
| GDPR full export when leaving Veilio             | ❌ No — export is already quota-free |

### How it works

1. **Activate migration** from the dashboard (`/dashboard/onboarding` → « Migration mode » card, or `POST /api/onboarding/migration`).
2. Veilio creates a **one-shot budget** on your subscription: `migrationAllowance`, `migrationTokensUsed`, `migrationExpiresAt`.
3. A dedicated API key with `purpose = MIGRATION` is generated (**shown once**).
4. Requests signed with this key (or dataset uploads with `migration=true`) consume the **migration budget**, not monthly tokens/requests.
5. When the budget is exhausted or expired, migration calls are **rejected explicitly** (no silent fallback to monthly quota).

### Option A — Reusable script (`veilio-migrate.mjs`)

Download from your app (no login required):

```bash
curl -O https://app.veilio.fr/veilio-migrate.mjs
```

Run on a CSV export:

```bash
export VEILIO_API_KEY="sk_..._MIGRATION_KEY"
export VEILIO_BASE_URL="https://app.veilio.fr"

node veilio-migrate.mjs \
  --in customers.csv \
  --out customers.tokenized.csv \
  --columns email,phone,full_name \
  --types email=email,phone=phone \
  --entity-id-col customer_id \
  --retention-days 3650 \
  --batch 100 \
  --resume
```

| Flag              | Description                                                          |
| ----------------- | -------------------------------------------------------------------- |
| `--columns`       | Comma-separated sensitive columns to tokenize                        |
| `--types`         | Optional `col=type` mapping (`email`, `phone`, …)                    |
| `--entity-id-col` | Business id column kept in clear (for `entityId` / profile grouping) |
| `--resume`        | Resume from last checkpoint after interruption                       |
| `--dry-run`       | Parse only, no API calls                                             |

The script uses `POST /api/tokenize/bulk` with your migration key and backs off on HTTP 429.

### Option B : Dataset upload (dashboard)

1. Create an organization (required for team sharing; optional for solo import).
2. Upload CSV/JSON from **Datasets** with migration mode enabled (`migration=true` on the upload API).
3. Cell count is debited from the migration budget after successful tokenization.

### API behaviour with a migration key

| Endpoint                               | Monthly quota | Migration budget             |
| -------------------------------------- | ------------- | ---------------------------- |
| `POST /tokenize`, `/bulk`, `/format`   | Skipped       | Consumes tokens created      |
| `POST /flows/ingest`                   | Skipped       | Consumes tokens created      |
| `POST /detokenize` (migration key)     | Skipped       | Not consumed (no new tokens) |
| `POST /datasets` with `migration=true` | Skipped       | Consumes tokenized cells     |

Standard keys (`purpose = STANDARD`) always use monthly plan limits.

### Check migration status

Authenticated dashboard or API:

```bash
GET /api/onboarding/migration
```

Response includes `allowance`, `used`, `remaining`, `expiresAt`, and active migration keys (prefix only).

### Requirements

* Active paid plan (**Starter, Pro, or Enterprise**) — migration is **not** available on Freemium.
* Organization **OWNER** or **DPO** to activate.
* Plan your `migrationAllowance` to cover worst-case cell count (non-empty cells in the export).
