> 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/sdk-python.md).

# SDK Python Integration

Install:

```bash
pip install veilio-sdk
```

Example:

```python
import os
from veilio_sdk import VeilioClient

veilio = VeilioClient(
    api_key=os.getenv("VEILIO_API_KEY"),
    base_url=os.getenv("VEILIO_BASE_URL", "https://app.veilio.fr/api"),
)

def create_customer(email: str):
    result = veilio.tokenize(
        data=email,
        type="email",
    )

    # Store token in your DB, not the raw email.
    return {"email_token": result["token"]}

def send_welcome_email(email_token: str):
    original = veilio.detokenize(
        token=email_token,
        reason="Send welcome email",
    )
    return original["data"]

# Call when a user requests account deletion (GDPR right to erasure)
def delete_user_data(email_token: str):
    veilio.shred_token(
        token=email_token,
        reason="GDPR - user deletion request",
    )
```

#### Client configuration

```python
veilio = VeilioClient(
    api_key: str,              # Required — your Veilio API key
    base_url: str = "https://app.veilio.fr/api",
    timeout: int = 30,         # Request timeout in seconds
    max_retries: int = 3,      # Retries on rate limits / network errors
)
```

For **on-premise** deployments, point `base_url` to your instance:

```python
veilio = VeilioClient(
    api_key=os.environ["VEILIO_API_KEY"],
    base_url="https://your-domain.com/api",
)
```

Environment variables:

| Variable          | Description                               |
| ----------------- | ----------------------------------------- |
| `VEILIO_API_KEY`  | API key from the Veilio dashboard         |
| `VEILIO_BASE_URL` | API base URL (optional, defaults to SaaS) |

#### API reference

**`tokenize(data, type=None, metadata=None, retention=None)`**

Tokenize a single field.

```python
result = veilio.tokenize(
    data="john@example.com",
    type="email",                          # Optional: email, phone, ssn, etc.
    metadata={"source": "signup"},         # Optional
    retention={                            # Optional — automatic shredding
        "ttlDays": 30,                     # Shred after N days
        # or "retentionUntil": "2026-12-31T23:59:59.000Z"
    },
)

# Returns: {"token": str, "createdAt": str, "retentionUntil": str | None}
```

**`tokenize_bulk(fields)`**

Tokenize multiple fields in one request.

```python
result = veilio.tokenize_bulk([
    {"data": "john@example.com", "type": "email"},
    {"data": "+33612345678", "type": "phone", "retention": {"ttlDays": 365}},
])

# Returns: {"tokens": [...], "summary": {"total", "success", "failed"}, "errors"?, "createdAt"}
```

**`detokenize(token, reason=None)`**

```python
result = veilio.detokenize(
    token="tok_abc123...",
    reason="Send email",  # Optional — logged for audit
)

# Returns: {"data": str, "accessedAt": str}
```

**`detokenize_bulk(tokens, reason=None)`**

```python
result = veilio.detokenize_bulk(
    [
        {"token": "tok_abc123...", "reason": "Profile view"},
        {"token": "tok_def456...", "reason": "Profile view"},
    ],
    reason="Profile view",  # Optional — one audit log line for the whole batch
)

# Returns: {"results": [...], "summary": {...}, "errors"?, "accessedAt"}
```

**`shred_token(token, reason=None)`**

Immediately and irreversibly destroy a token (cryptographic erasure).

```python
result = veilio.shred_token(
    token="tok_abc123...",
    reason="GDPR delete request",  # Optional
)

# Returns: {"token": str, "shreddedAt": str}
```

**`tokenize_format(data, format=None, options=None)`**

Tokenize structured data (JSON, CSV, or SQL).

```python
import json

result = veilio.tokenize_format(
    data=json.dumps({"email": "john@example.com", "phone": "+33612345678"}),
    format="json",  # Optional — auto-detected if omitted ("json", "csv", "sql")
    options={
        "fields": ["email"],              # Optional — tokenize only specific paths
        "retention": {"ttlDays": 365},    # Optional
        "csv": {                          # CSV-specific options
            "delimiter": ",",
            "hasHeaders": True,
        },
    },
)

# Returns: {"format", "tokenizedData", "tokens": [{"path", "token", "type?"}], "summary", "metadata"?}
```

**`detokenize_format(tokenized_data, format, tokens)`**

Restore original values in structured data.

```python
result = veilio.detokenize_format(
    tokenized_data='{"email": "tok_abc123..."}',
    format="json",
    tokens=[{"path": "email", "token": "tok_abc123..."}],
)

# Returns: {"format", "detokenizedData", "summary": {"tokensProcessed"}}
```

#### Bulk operations

For imports, migrations, or high-throughput jobs:

* `tokenize_bulk`
* `detokenize_bulk`

Use batching and retry logic for `429` responses. The SDK retries automatically (respecting `Retry-After` headers) up to `max_retries` times.

```python
fields = [
    {"data": "alice@example.com", "type": "email"},
    {"data": "+33612345678", "type": "phone"},
]

bulk = veilio.tokenize_bulk(fields=fields)

if bulk["summary"]["failed"] > 0:
    print("Partial failure:", bulk.get("errors", []))

tokens = [
    {"token": t["token"], "reason": "Migration verification"}
    for t in bulk["tokens"]
]
values = veilio.detokenize_bulk(tokens=tokens)
```

#### Retention and shredding

Schedule automatic shredding at tokenization time, or shred immediately:

```python
# Automatic shredding after 30 days
tokenized = veilio.tokenize(
    data="delete-me@example.com",
    type="email",
    retention={"ttlDays": 30},
)

# Immediate shredding (irreversible)
veilio.shred_token(
    token=tokenized["token"],
    reason="User deletion request",
)
```

#### Error handling

Handle Veilio SDK errors explicitly:

```python
from veilio_sdk import (
    VeilioClient,
    VeilioError,
    AuthenticationError,
    RateLimitError,
    PlanLimitError,
    TokenShreddedError,
)

try:
    result = veilio.detokenize(token="tok_abc123...", reason="Support case")
except AuthenticationError as e:
    print(f"Auth error: {e}")
except RateLimitError as e:
    print(f"Rate limit reached, retry after: {getattr(e, 'retry_after', None)}s")
except PlanLimitError as e:
    print(f"Plan limit exceeded: {e}")
except TokenShreddedError:
    print("Token has been shredded and cannot be detokenized.")
except VeilioError as e:
    print(f"Veilio API error [{e.code}]: {e.message}")
```

**Error codes**

| Code               | HTTP | Description                               |
| ------------------ | ---- | ----------------------------------------- |
| `AUTH_ERROR`       | 401  | Invalid or missing API key                |
| `VALIDATION_ERROR` | 400  | Invalid request data                      |
| `PLAN_LIMIT`       | 403  | Plan quota exceeded                       |
| `RATE_LIMIT_ERROR` | 429  | Rate limit exceeded                       |
| `TOKEN_SHREDDED`   | 410  | Token has been cryptographically shredded |
| `TIMEOUT_ERROR`    | 408  | Request timed out                         |
| `INTERNAL_ERROR`   | 5xx  | Server error                              |

#### Requirements

* Python 3.8+
* `requests` library (installed automatically with `veilio-sdk`)
* A valid Veilio API key

**Links**

* PyPI package: <https://pypi.org/project/veilio-sdk/>
* SDK style reference: <https://docs.veilio.xyz/documentation/getting-started/>
