> 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.xyz/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.xyz/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/>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.veilio.xyz/documentation/getting-started/sdk-python.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
