API Reference
Complete API reference for all OGuardAI v1 endpoints including transform, rehydrate, detect, policy evaluation, health, and capabilities
All endpoints are served under the /v1 prefix. Request and response bodies are JSON (Content-Type: application/json).
Endpoint Table
| Method | Path | Description | Auth Required |
|---|---|---|---|
POST | /v1/transform | Transform text, replacing entities with semantic tokens | Yes (if enabled) |
POST | /v1/transform/stream | Streaming transform (SSE) | Yes (if enabled) |
POST | /v1/transform/file | Transform an uploaded file (multipart) | Yes (if enabled) |
POST | /v1/transform/image | Transform text detected in an image | Yes (if enabled) |
POST | /v1/rehydrate | Restore semantic tokens in LLM output to original values | Yes (if enabled) |
POST | /v1/rehydrate/stream | Streaming rehydrate (SSE) | Yes (if enabled) |
POST | /v1/rehydrate/file | Rehydrate an uploaded file (multipart) | Yes (if enabled) |
POST | /v1/detect | Detect entities without transforming | Yes (if enabled) |
POST | /v1/batch/transform | Batch transform multiple inputs in one request | Yes (if enabled) |
POST | /v1/batch/detect | Batch detect entities in multiple inputs | Yes (if enabled) |
POST | /v1/evaluate-policy | Evaluate policy against entities (dry run) | Yes (if enabled) |
POST | /v1/rag/ingest | Ingest a document for RAG with PII protection | Yes (if enabled) |
POST | /v1/rag/query | Query RAG index with PII-safe context | Yes (if enabled) |
POST | /v1/rag/context | Retrieve RAG context chunks (tokenized) | Yes (if enabled) |
POST | /v1/rag/answer | Generate a RAG answer with automatic rehydration | Yes (if enabled) |
POST | /v1/rag/delete | Delete ingested RAG documents | Yes (if enabled) |
POST | /v1/revoke | Revoke a single entity (makes it non-restorable) | Yes (if enabled) |
POST | /v1/revoke/bulk | Revoke multiple entities in one request | Yes (if enabled) |
GET | /v1/revocations/count | Get the count of revoked entities | Yes (if enabled) |
POST | /v1/redact/image | Redact PII regions in an image | Yes (if enabled) |
POST | /v1/admin/policy/validate | Validate policy configuration files | Yes (admin scope) |
GET | /v1/health | Health check | No (always public) |
GET | /v1/capabilities | List entity types, languages, detectors | No (always public) |
GET | /v1/diagnostics | Runtime diagnostics (detector mode, config, versions) | Yes (Admin scope required) |
GET | /metrics | Prometheus metrics endpoint | Yes (Admin scope required) |
Port note: Examples below use port 8080 (Docker quick start). For other deployments, use the appropriate port (default: 3000).
Authentication
API Key
Send the key in the X-API-Key header:
curl -H "X-API-Key: your-key-here" http://localhost:3000/v1/transform ...JWT Bearer Token
Send a JWT in the Authorization header:
curl -H "Authorization: Bearer eyJhbG..." http://localhost:3000/v1/transform ...JWT tokens are validated against the configured JWKS endpoint.
Scopes
The runtime currently supports 5 scopes:
| Scope | Grants Access To |
|---|---|
transform | /v1/transform, /v1/transform/stream, /v1/transform/file, /v1/transform/image, /v1/batch/transform |
rehydrate | /v1/rehydrate, /v1/rehydrate/stream, /v1/rehydrate/file |
detect | /v1/detect, /v1/batch/detect |
policy | /v1/evaluate-policy |
admin | All endpoints including /v1/admin/policy/validate and config management |
Note:
ragandrevokescopes are not yet implemented in the auth runtime. RAG and revoke endpoints currently require one of the existing scopes (typicallytransformoradmin).
When auth is disabled (default for development), all endpoints are accessible without credentials.
POST /v1/transform
Transform input text, replacing detected entities with semantic tokens.
Request
{
"input": "Contact Julia Schneider at julia@firma.de",
"input_type": "text",
"policy": "default",
"language": "de",
"session_state": "(optional sealed blob from previous transform)",
"detectors": ["builtin-regex"],
"context": {
"destination": "external_llm",
"provider": "openai",
"model": "gpt-4o"
}
}| Field | Type | Required | Description |
|---|---|---|---|
input | string | Yes (for text) | Raw input text |
input_type | string | No | "text" (default), "json", or "chat_messages" |
input_json | object | For JSON mode | Structured JSON with field-level transformation |
input_messages | array | For chat mode | OpenAI-format message array [{role, content}] |
language | string | No | ISO 639-1 hint (auto-detected if omitted) |
policy | string | No | Policy name (uses server default if omitted) |
session_id | string | No | Existing session ID for multi-turn continuity |
session_state | string | No | Sealed session blob from previous transform |
detectors | string[] | No | Explicit detector list (all if omitted) |
protection_overrides | object | No | Per-entity-type action overrides |
context | object | No | Destination, provider, model, max_tokens |
Exactly one input source is permitted: input (text), input_json, or input_messages.
Response
{
"safe_text": "Contact {{person:p_001}} at {{email:e_001}}",
"session_id": "01916a3e-7b2c-7000-8000-000000000001",
"session_state": "eyJ2IjoxLCJzaWQiOi...",
"entity_context": [
{
"token": "{{person:p_001}}",
"type": "person",
"gender": "female",
"formality": "formal",
"language": "de"
}
],
"entities": [
{
"token": "{{person:p_001}}",
"type": "person",
"protection_level": 2,
"action_applied": "full",
"confidence": 0.95,
"detector": "builtin-regex",
"metadata": { "gender": "female", "formality": "formal", "language": "de" },
"span": { "start": 8, "end": 24 }
}
],
"stats": {
"entities_detected": 2,
"entities_transformed": 2,
"entities_blocked": 0,
"detection_time_ms": 1.2,
"transform_time_ms": 0.3
}
}| Field | Description |
|---|---|
safe_text | Transformed text with semantic tokens. Send this to the LLM. |
session_id | Session identifier |
session_state | Sealed session blob. Pass this to rehydrate. |
entity_context | Safe metadata for the LLM system prompt. Never contains raw values. |
entities | Full diagnostic metadata. For debugging, NOT for the LLM. |
stats | Performance metrics |
POST /v1/rehydrate
Restore semantic tokens in LLM output to their original values.
Request
{
"output": "Dear {{person:p_001}}, your order {{order:o_001}} has shipped.",
"session_state": "eyJ2IjoxLCJzaWQiOi...",
"output_channel": "customer_email",
"restore_mode": "formatted",
"restore_overrides": {
"e_001": "none"
}
}| Field | Type | Required | Description |
|---|---|---|---|
output | string | Yes | LLM output containing {{type:id}} tokens |
session_id | string | No | Session ID from transform response |
session_state | string | No | Sealed session blob from transform response |
restore_mode | string | No | Default restore mode: full, partial, masked, formatted, abstract, none |
restore_overrides | object | No | Per-token overrides keyed by token ID |
output_channel | string | No | user_output, internal_summary, customer_email, tool_payload, export, log_safe |
Response
{
"restored_text": "Dear Frau Julia Schneider, your order ORD-2026-4892 has shipped.",
"tokens_resolved": 2,
"tokens_unresolved": [],
"stats": {
"rehydrate_time_ms": 0.8
}
}Restore Modes
| Mode | Behavior | Person Example | Email Example |
|---|---|---|---|
full | Complete original value | Julia Schneider | julia@firma.de |
partial | Deterministic subset | J. Schneider | j***@firma.de |
masked | Character masking | ******* ********* | j*******************e |
formatted | Original + contextual formatting | Frau Julia Schneider | julia@firma.de (email) |
abstract | Semantic description | (female customer) | (email on file) |
none | Removed / redacted | [REDACTED] | [REDACTED] |
POST /v1/detect
Detect entities in text without performing transformation.
Request
{
"input": "Email: test@example.com, SSN: 123-45-6789",
"language": "en",
"entity_types": ["email", "ssn"],
"threshold": 0.5
}Response
{
"entities": [
{
"type": "email",
"value": "test@example.com",
"span": { "start": 7, "end": 23 },
"confidence": 1.0,
"detector": "builtin-regex"
},
{
"type": "ssn",
"value": "123-45-6789",
"span": { "start": 30, "end": 41 },
"confidence": 1.0,
"detector": "builtin-regex"
}
],
"stats": {
"detection_time_ms": 0.9,
"detectors_used": ["builtin-regex"]
}
}POST /v1/evaluate-policy
Evaluate a policy against entities without performing transformation. Useful for previewing what actions would be taken.
Request
{
"policy": "strict-pii",
"entities": [
{ "type": "person", "value": "Julia Schneider" },
{ "type": "ssn", "value": "123-45-6789" }
]
}Response
{
"decisions": [
{
"entity_type": "person",
"action": "hard_mask",
"protection_level": 1,
"rule_matched": "strict-pii/person"
},
{
"entity_type": "ssn",
"action": "block",
"protection_level": 1,
"rule_matched": "strict-pii/ssn"
}
],
"policy_version": "1.0.0"
}GET /v1/health
Returns runtime health status. Always public (no auth required).
{
"status": "healthy",
"version": "0.1.0",
"uptime_seconds": 3600.5,
"components": {
"detector_builtin": { "status": "healthy" },
"session_backend": { "status": "healthy" },
"policy_engine": { "status": "healthy" }
}
}Status values: healthy, degraded, unhealthy.
GET /v1/capabilities
Returns supported entity types, languages, and available detectors. Always public.
{
"entity_types": [
{ "name": "person", "protection_level": 2, "id_prefix": "p_" },
{ "name": "email", "protection_level": 2, "id_prefix": "e_" },
{ "name": "ssn", "protection_level": 1, "id_prefix": "ss_" }
],
"languages": [
{ "code": "de", "name": "German", "detection_support": "full" }
],
"detectors": [
{ "name": "builtin-regex", "type": "builtin", "entity_types": ["email", "phone", "ssn"] }
],
"ner_active": true
}Error Codes
All error responses follow this format:
{
"error": "Human-readable description",
"code": "ERROR_CODE",
"details": "optional additional context"
}| Code | HTTP Status | Description |
|---|---|---|
GUARDAI_INVALID_INPUT | 400 | Malformed request, missing fields, type mismatch |
GUARDAI_AUTH_FAILED | 401 | Authentication is enabled but no credentials provided |
GUARDAI_POLICY_DENIED | 403 | Policy blocks the detected entity type or credentials lack required scope |
GUARDAI_SESSION_EXPIRED | 410 | Session TTL has elapsed or sealed blob failed integrity check |
GUARDAI_OUTPUT_BLOCKED | 422 | Output guard blocked the response due to hallucinated PII |
GUARDAI_TOKEN_REPAIR_FAILED | 422 | Token repair could not resolve tokens in LLM output |
GUARDAI_DETECTION_FAILED | 500 | Detector service is down or detection failed |
GUARDAI_INTERNAL_ERROR | 500 | Unexpected server error |
GUARDAI_BAD_REQUEST | 400 | Generic bad request (e.g., missing field) |
GUARDAI_PAYLOAD_TOO_LARGE | 413 | Request payload exceeds configured size limit |
For full JSON schemas, see the product specification.