All endpoints (except auth and health) require a JWT Bearer token:
Authorization: Bearer <token>
Authentication
| Method | Path | Description |
| POST | /api/auth/register | Register a new user |
| POST | /api/auth/login | Login and receive JWT token |
| GET | /api/auth/me | Get current user info |
| PUT | /api/auth/profile | Update display name or password |
| GET | /api/auth/capabilities | Check available features (SMTP, OAuth) |
| POST | /api/auth/forgot-password | Request password reset email |
| POST | /api/auth/reset-password | Reset password with token |
| GET | /api/auth/google/login | Initiate Google OAuth flow |
| GET | /api/auth/google/callback | Google OAuth callback |
Register
curl -X POST http://localhost:8000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "securepass", "display_name": "Alice"}'
Response: {"access_token": "eyJ...", "token_type": "bearer"}
Login
curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "securepass"}'
Chat
| Method | Path | Description |
| POST | /api/chat | Send a message (SSE streaming) |
| POST | /api/chat/with-document | Chat with file attachment |
Send Message
curl -N http://localhost:8000/api/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Summarize this for John Smith at john@acme.com",
"conversation_id": null,
"provider": "openai",
"model": "gpt-4o-mini"
}'
Returns Server-Sent Events (SSE) with data: lines containing JSON chunks.
Chat with Document
Upload a file alongside a message. The document text is extracted, sanitized, and prepended as context for the LLM.
curl -N http://localhost:8000/api/chat/with-document \
-H "Authorization: Bearer $TOKEN" \
-F "message=Summarize the key points in this document" \
-F "provider=openai" \
-F "model=gpt-4o-mini" \
-F "file=@report.pdf"
Supported file types: PDF, DOCX, TXT, CSV, XLSX (max 10 MB).
Sanitize (Detection Only)
| Method | Path | Description |
| POST | /api/sanitize | Sanitize a single text (no LLM call) |
| POST | /api/sanitize/batch | Sanitize multiple texts in one request |
No LLM call, no token cost. Ideal for corpus testing, CI/CD integration, and detection benchmarking.
Sanitize Single Text
curl -X POST http://localhost:8000/api/sanitize \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"text": "Contact John Smith at john@acme.com or 555-123-4567"}'
{
"sanitized_text": "Contact PERSON_001 at EMAIL_001 or PHONE_001",
"entity_count": 3,
"entities": [
{
"entity_type": "PERSON",
"placeholder": "PERSON_001",
"confidence": 0.85,
"detection_method": "ner"
},
{
"entity_type": "EMAIL",
"placeholder": "EMAIL_001",
"confidence": 0.95,
"detection_method": "regex"
},
{
"entity_type": "PHONE",
"placeholder": "PHONE_001",
"confidence": 0.85,
"detection_method": "regex"
}
],
"processing_ms": 3
}
Set return_original: true to include original values (admin/owner roles only).
Batch Sanitize
curl -X POST http://localhost:8000/api/sanitize/batch \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"texts": [
"Email john@acme.com about the project",
"Call Jane Doe at 555-987-6543"
]
}'
Entity placeholders are consistent across all texts in the batch (shared mapper).
Conversations
| Method | Path | Description |
| GET | /api/conversations | List conversations (search/sort) |
| GET | /api/conversations/{id} | Get conversation with messages |
| PUT | /api/conversations/{id} | Rename conversation |
| DELETE | /api/conversations/{id} | Delete conversation |
| GET | /api/conversations/{id}/export | Export as JSON or Markdown |
Gateway API (OpenAI-Compatible)
| Method | Path | Description |
| POST | /v1/chat/completions | OpenAI-compatible chat completion |
Requires an API key (created via the API Keys endpoint). Works with any OpenAI SDK by changing the base URL:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="vk-your-api-key")
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}]
)
Provider Routing
Prefix the model name to route to a specific provider:
| Model Prefix | Provider |
gpt-*, o3-* | OpenAI |
claude-* | Anthropic |
ollama/* or unmatched | Ollama |
Document Scanner
| Method | Path | Description |
| POST | /api/documents/scan | Upload and scan a document for PII |
No LLM call — pure detection. Upload a file via multipart form data. Supported: PDF, DOCX, TXT, CSV, XLSX (max 10 MB). Files are processed in-memory and discarded.
Models
| Method | Path | Description |
| GET | /api/models | List available models and provider status |
Rules (Custom Detection)
| Method | Path | Description |
| GET | /api/rules | List all detection rules |
| POST | /api/rules | Create a custom rule |
| PUT | /api/rules/{id} | Update a rule |
| DELETE | /api/rules/{id} | Delete a custom rule |
| POST | /api/rules/test | Test a rule against sample text |
Create Rule
curl -X POST http://localhost:8000/api/rules \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Internal Project Code",
"pattern": "PROJ-[A-Z]{3}-\\d{4}",
"entity_type": "PROJECT_CODE",
"description": "Internal project identifiers"
}'
Policies
| Method | Path | Description |
| GET | /api/policies | List all policies |
| POST | /api/policies | Create a policy |
| PUT | /api/policies/{id} | Update a policy |
| DELETE | /api/policies/{id} | Delete a policy |
Policy Actions
| Action | Behavior |
redact | Replace entity with placeholder (default) |
block | Reject the message entirely |
warn | Allow but flag in the sanitization panel |
allow | Pass through without modification |
API Keys
| Method | Path | Description |
| GET | /api/api-keys | List API keys (hashed) |
| POST | /api/api-keys | Create a new API key |
| DELETE | /api/api-keys/{id} | Revoke an API key |
Webhooks
| Method | Path | Description |
| GET | /api/webhooks | List webhooks |
| POST | /api/webhooks | Create a webhook |
| PUT | /api/webhooks/{id} | Update a webhook |
| DELETE | /api/webhooks/{id} | Delete a webhook |
Settings
| Method | Path | Description |
| GET | /api/settings | Get organization settings |
| PUT | /api/settings | Update organization settings |
Admin
| Method | Path | Description |
| GET | /api/admin/dashboard | Dashboard stats |
| GET | /api/admin/usage | Usage records |
| GET | /api/admin/entities | Entity detection stats |
| GET | /api/admin/audit | Audit log entries |
| GET | /api/admin/users | List users (admin only) |
| POST | /api/admin/users/invite | Invite a user |
| PUT | /api/admin/users/{id} | Update user role/status |
Usage Quota
| Method | Path | Description |
| GET | /api/usage/quota | Current usage vs tier limits |
Licensing
| Method | Path | Description |
| GET | /api/licensing/status | Current license status and tier |
| GET | /api/licensing/tiers | Available tiers and limits |
| POST | /api/licensing/activate | Activate a license key |
| POST | /api/licensing/deactivate | Deactivate current license |
Health
| Method | Path | Description |
| GET | /api/health | Basic health check |
| GET | /api/health/live | Liveness probe (Kubernetes) |
| GET | /api/health/ready | Readiness probe (checks DB) |
Error Responses
All errors follow a consistent format:
{
"detail": "Description of the error"
}
| Code | Meaning |
401 | Missing or invalid authentication |
403 | Insufficient permissions or license tier |
404 | Resource not found |
422 | Validation error (invalid input) |
429 | Rate limited |