TokenVeil API v1
Interactive reference: browse the endpoints, schemas, error codes and code examples, generated from the product’s OpenAPI specification.
The v1 API exposes TokenVeil’s reversible anonymization as a service. You send text, you get back a tokenized version plus an opaque session id, you use the tokenized text wherever you want (your own LLM, a data pipeline, a third party), then you call back with the session id to restore the real values.
The token-to-value mapping never leaves the server. It is encrypted at rest and can only be addressed through the session id, a 256-bit capability token that is not enumerable. TokenVeil does not send your real data anywhere: your infrastructure holds it, the API only moves tokenized text and opaque ids.
Base URL
Section titled “Base URL”https://<your-tokenveil-host>/api/v1The API is served by your own TokenVeil instance. There is no shared TokenVeil cloud: the base URL is the host where you deployed TokenVeil (Community or Enterprise).
Authentication
Section titled “Authentication”Every call requires an API key in the X-TV-API-Key header.
Create a key from the TokenVeil UI: Preferences > “API key” tab > Generate an API key. A key carries an optional expiry and a daily quota, and can be revoked at any time. Store it like a password: it grants anonymization and de-anonymization on your account.
X-TV-API-Key: tkv_xxxxxxxxxxxxxxxxxxxxxxxxAll sessions are scoped to the account that owns the key. A key can only read and de-anonymize the sessions it created. Another account’s session id returns 404, even if you somehow hold it.
Endpoints
Section titled “Endpoints”POST /api/v1/anonymize
Section titled “POST /api/v1/anonymize”Anonymize a text and open a mapping session.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
text | string | yes | Text to anonymize. Max 100000 characters. |
expires_in_hours | integer or null | no | Session lifetime, 1 to 2160 hours (90 days). Default 24. null never expires. |
title | string or null | no | Internal label to find the session again. Never sent to any LLM. Max 80 characters. |
curl -X POST https://<host>/api/v1/anonymize \ -H "X-TV-API-Key: $TV_KEY" \ -H "Content-Type: application/json" \ -d '{"text": "Contact Jean Dupont at 06 12 34 56 78, IBAN FR76 3000 6000 0112 3456 7890 189."}'Response 200:
{ "session_id": "TV-9f2c8a1b...", "anonymized_text": "Contact <PERSON_1> at <PHONE_NUMBER_1>, IBAN <IBAN_CODE_1>.", "detected": { "PERSON": 1, "PHONE_NUMBER": 1, "IBAN_CODE": 1 }, "expires_at": 1793894400.0}detected reports the entity types and counts only, never the real values. Keep session_id: it is the only way to restore the real values later.
POST /api/v1/deanonymize
Section titled “POST /api/v1/deanonymize”Restore the real values in a tokenized text, using its session id. Typically you pass an LLM reply that still carries the tokens.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
session_id | string | yes | The id returned by /anonymize. |
text | string | yes | Tokenized text to translate back. Max 500000 characters. Tokens not present in the mapping are left as is. |
curl -X POST https://<host>/api/v1/deanonymize \ -H "X-TV-API-Key: $TV_KEY" \ -H "Content-Type: application/json" \ -d '{"session_id": "TV-9f2c8a1b...", "text": "I called <PERSON_1> at <PHONE_NUMBER_1>."}'Response 200:
{ "text": "I called Jean Dupont at 06 12 34 56 78." }Every de-anonymization is audited (re-identification event) and increments the session use counter.
GET /api/v1/sessions/{session_id}
Section titled “GET /api/v1/sessions/{session_id}”Return a session’s status without ever decrypting the mapping.
Response 200:
{ "session_id": "TV-9f2c8a1b...", "title": null, "status": "active", "created_at": 1793808000.0, "expires_at": 1793894400.0, "uses": 3, "last_used_at": 1793820000.0}status is active, expired, or revoked.
DELETE /api/v1/sessions/{session_id}
Section titled “DELETE /api/v1/sessions/{session_id}”Destroy a session’s mapping immediately and irreversibly. Any tokenized text already emitted can no longer be translated back. Returns 204 with no body.
Errors
Section titled “Errors”| Status | Meaning |
|---|---|
401 | Missing or invalid API key. |
403 | TokenVeil license expired on the instance. |
404 | Unknown session id, or a session that belongs to another account. |
410 | Session expired or revoked. |
422 | Invalid body (for example text over the size limit). |
429 | Daily key quota or burst rate limit reached. |
Error bodies follow the standard shape {"detail": "..."}.
Security model
Section titled “Security model”- The mapping is stored encrypted at rest (AES via Fernet) and is only reachable through the session id.
- The session id is a 256-bit opaque capability token, not a database row id, so it cannot be guessed or enumerated.
- Sessions are isolated per key: a key never sees or restores another account’s sessions.
- The public API never exposes the cleartext mapping. There is no export-key endpoint on
/api/v1. - Keys expire, carry a daily quota, are rate limited, and can be revoked. Revocation and license state are enforced on every call.
- Anonymization records entity type counts, and de-anonymization records a re-identification event, both without the real values, for audit.
Stability
Section titled “Stability”/api/v1 is a stable, versioned surface. Breaking changes go to a new version (/api/v2); v1 keeps working. A curated, machine-readable OpenAPI spec is served at /api/v1/openapi.json, and an interactive Swagger UI at /api/v1/docs. Both are limited to the public /api/v1 surface (the internal routes are not exposed).