> 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/getting-started/http-integration.md).

# HTTP Integration

Use direct HTTP calls if you need full control.

Use direct HTTP calls when you need full control, a language without an official SDK, or custom retry/idempotency logic.

#### Authentication

Pass your API key in one of the following headers:

* `Authorization: Bearer <API_KEY>`
* `X-API-Key: <API_KEY>`

Never expose the key in browser code, mobile apps, or public repositories.

#### Base URL

| Environment       | URL                         |
| ----------------- | --------------------------- |
| SaaS production   | `https://app.veilio.fr/api` |
| On-premise        | `https://<your-domain>/api` |
| Local development | `http://localhost:3000/api` |

> Use `https://app.veilio.fr/api`, not `api.veilio.com`.

#### Supported data types (`type` field)

The `type` field is optional but recommended for audit, SIEM events, and dashboard filtering.

| Type                     | Example                              |
| ------------------------ | ------------------------------------ |
| `email`                  | `john@example.com`                   |
| `phone`                  | `+33612345678`                       |
| `ssn`                    | `123-45-6789`                        |
| `iban`                   | `FR7630006000011234567890189`        |
| `address`                | `10 rue de la Paix, Paris`           |
| `firstName` / `lastName` | Personal names                       |
| `birthdate`              | `1990-01-15`                         |
| Custom string            | Any label your app uses consistently |

***

#### Core endpoints

| Method | Path                 | Description                |
| ------ | -------------------- | -------------------------- |
| POST   | `/tokenize`          | Single field               |
| POST   | `/tokenize/bulk`     | Batch fields               |
| POST   | `/tokenize/format`   | JSON / CSV / SQL in-place  |
| POST   | `/detokenize`        | Reveal one token           |
| POST   | `/detokenize/bulk`   | Reveal many tokens         |
| POST   | `/detokenize/format` | Restore structured data    |
| POST   | `/tokens/shred`      | Irreversible crypto-shred  |
| POST   | `/flows/ingest`      | Form / lead JSON ingestion |

See the full API Reference for dashboard, dataset, and compliance routes.

***

#### Tokenize

```bash
curl -s -X POST "$VEILIO_BASE_URL/tokenize" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "support@veilio.fr",
    "type": "email",
    "metadata": { "entityId": "customer_42", "source": "signup" },
    "retention": { "ttlDays": 365 }
  }'
```

**Request body**

| Field       | Required | Description                                                               |
| ----------- | -------- | ------------------------------------------------------------------------- |
| `data`      | Yes      | Sensitive string to tokenize                                              |
| `type`      | No       | Data category (see table above)                                           |
| `metadata`  | No       | Arbitrary JSON (e.g. `entityId` for profile grouping)                     |
| `retention` | No       | `{ "ttlDays": 30 }` or `{ "retentionUntil": "2026-12-31T23:59:59.000Z" }` |

**Response `200`**

```json
{
  "token": "tok_abc123...",
  "createdAt": "2026-03-26T10:00:00.000Z",
  "retentionUntil": "2027-03-26T10:00:00.000Z"
}
```

***

#### Detokenize

```bash
curl -s -X POST "$VEILIO_BASE_URL/detokenize" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "tok_abc123...",
    "reason": "Support ticket resolution"
  }'
```

**Response `200`**

```json
{
  "data": "support@veilio.fr",
  "accessedAt": "2026-03-26T10:01:00.000Z"
}
```

**Response `410`** — token was cryptographically shredded (`TOKEN_SHREDDED`).

***

#### Bulk tokenize

```bash
curl -s -X POST "$VEILIO_BASE_URL/tokenize/bulk" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": [
      { "data": "support@veilio.fr", "type": "email" },
      { "data": "+33601020304", "type": "phone", "retention": { "ttlDays": 90 } }
    ]
  }'
```

**Response `200`**

```json
{
  "tokens": [
    { "token": "tok_...", "type": "email", "createdAt": "...", "retentionUntil": null },
    { "token": "tok_...", "type": "phone", "createdAt": "...", "retentionUntil": "..." }
  ],
  "summary": { "total": 2, "success": 2, "failed": 0 },
  "createdAt": "2026-03-26T10:00:00.000Z"
}
```

Partial failures include an `errors` array with `{ "field": 0, "error": "..." }`.

***

#### Bulk detokenize

```bash
curl -s -X POST "$VEILIO_BASE_URL/detokenize/bulk" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tokens": [
      { "token": "tok_abc...", "reason": "Profile view" },
      { "token": "tok_def...", "reason": "Profile view" }
    ],
    "reason": "Profile view"
  }'
```

The top-level `reason` is optional — it creates one audit log line for the whole batch.

**Response `200`**

```json
{
  "results": [
    { "token": "tok_abc...", "data": "support@veilio.fr", "accessedAt": "..." }
  ],
  "summary": { "total": 2, "success": 2, "failed": 0 },
  "accessedAt": "2026-03-26T10:01:00.000Z"
}
```

***

#### Tokenize format (JSON, CSV, SQL)

```bash
curl -s -X POST "$VEILIO_BASE_URL/tokenize/format" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "{\"email\":\"john@example.com\",\"phone\":\"+33612345678\"}",
    "format": "json",
    "options": {
      "fields": ["email"],
      "retention": { "ttlDays": 365 }
    },
    "entityId": "customer_42"
  }'
```

**Response `200`**

```json
{
  "format": "json",
  "tokenizedData": "{\"email\":\"tok_...\",\"phone\":\"+33612345678\"}",
  "tokens": [
    { "path": "email", "token": "tok_...", "type": "email" }
  ],
  "summary": { "totalFields": 2, "tokenizedFields": 1 }
}
```

CSV options: `options.csv.delimiter`, `options.csv.hasHeaders`.

***

#### Detokenize format

```bash
curl -s -X POST "$VEILIO_BASE_URL/detokenize/format" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tokenizedData": "{\"email\":\"tok_abc123...\"}",
    "format": "json",
    "tokens": [{ "path": "email", "token": "tok_abc123..." }]
  }'
```

**Response `200`**

```json
{
  "format": "json",
  "detokenizedData": "{\"email\":\"john@example.com\"}",
  "summary": { "tokensProcessed": 1 }
}
```

***

#### Shred a token

Immediately and irreversibly destroy a token (GDPR erasure, right to be forgotten).

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

**Response `200`**

```json
{
  "token": "tok_xxxxxxxxxxxx",
  "shreddedAt": "2026-03-26T10:05:00.000Z"
}
```

***

#### Flow ingest (form / lead payloads)

Tokenize a JSON object in one call — useful for signup forms, CRM webhooks, or lead capture. Uses the tokenization schema attached to your API key (if configured).

```bash
curl -s -X POST "$VEILIO_BASE_URL/flows/ingest" \
  -H "Authorization: Bearer $VEILIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flowId": "signup-v1",
    "source": "website",
    "entityId": "lead_9912",
    "data": {
      "email": "john@example.com",
      "phone": "+33612345678",
      "company": "Acme Corp"
    },
    "metadata": { "utm_source": "google" }
  }'
```

**Response `201`**

```json
{
  "flowId": "signup-v1",
  "protectedData": {
    "email": "tok_...",
    "phone": "tok_...",
    "company": "Acme Corp"
  },
  "tokens": [
    { "path": "email", "token": "tok_...", "type": "email" },
    { "path": "phone", "token": "tok_...", "type": "phone" }
  ],
  "lookup": {
    "email_hash": "...",
    "phone_hash": "..."
  },
  "policyApplied": "api_key_schema",
  "metadata": { "source": "website", "originalMetadata": { "utm_source": "google" } }
}
```

Store `protectedData` in your database. Fields not covered by your API key schema remain in plaintext.

***

#### Response and retry strategy

| HTTP | Code               | Action                                   |
| ---- | ------------------ | ---------------------------------------- |
| 401  | `AUTH_ERROR`       | Fix or rotate API key                    |
| 400  | `VALIDATION_ERROR` | Fix request body                         |
| 403  | `PLAN_LIMIT`       | Check usage / upgrade plan               |
| 410  | `TOKEN_SHREDDED`   | Data is gone — do not retry              |
| 429  | `RATE_LIMIT_ERROR` | Honor `Retry-After`, exponential backoff |
| 5xx  | `INTERNAL_ERROR`   | Retry with backoff                       |

* Handle `429` with exponential backoff.
* Read the `Retry-After` header before retrying.
* Use bulk endpoints for high-throughput imports.
* Add idempotency in your app for replayed business operations.

**Related links**

* SDK Javascript · SDK Python
* API Reference
* Troubleshooting
