Skip to main content

API Reference

This page covers the public PolicyGuard HTTP API. Where a deployment exposes interactive docs, you can also browse them at:

  • OpenAPI JSON: GET /openapi.json
  • Swagger UI: GET /docs
  • ReDoc: GET /redoc

Authentication​

PolicyGuard accepts either of:

  • JWT (Bearer): Authorization: Bearer <jwt>
  • API key: X-API-Key: <api_key> (format: sk-vai-...)
Endpoint GroupAccepts
Content safety (/api/topic_guard, /api/topic_guard_oneshot, /api/v1/moderations)JWT or API key
CRUD endpoints (guards, policy groups, policies, templates)JWT only

When auth is disabled (local testing), anonymous access is allowed.


API Keys​

API keys are managed through the Virtue Auth integration and require a JWT for management endpoints.

GET /api/api-keys​

List API keys for the current user.

POST /api/api-keys​

Create a new API key. The full key value is only returned once — store it securely.

Request:

{
"name": "my-key",
"expires_at": "2026-12-31T00:00:00Z",
"scope": "all"
}

Response:

{
"id": "string",
"name": "my-key",
"key": "sk-vai-xxxxxxxxxxxxxxxxxxxxxxxx",
"key_prefix": "sk-vai-xxxx",
"scope": "all",
"expires_at": "2026-12-31T00:00:00Z",
"created_at": "2026-01-15T10:30:00Z"
}

DELETE /api/api-keys/{key_id}​

Delete an API key by ID.


Policy Groups​

Policy groups bundle individual policies and define the threshold and strictness applied when those policies are evaluated. All endpoints require JWT.

GET /api/policy_groups​

List policy groups owned by the current user, including available templates.

GET /api/policy_groups/{group_uuid}​

Get a policy group by UUID. Templates are readable by all users.

POST /api/policy_groups​

Create a policy group with one or more policies.

Request:

{
"name": "Customer Support Safety",
"threshold": 0.5,
"strictness_level": "medium",
"is_template": false,
"policies": [
{
"name": "PII Disclosure",
"description": "Block disclosure of personal information.",
"block_activities": ["sharing SSN", "sharing credit card numbers"],
"safe_activities": ["general account questions"],
"enabled": true
}
]
}
FieldTypeDefaultDescription
namestringrequiredPolicy group name
thresholdfloat0.5Classification threshold 0.0–1.0
strictness_levelstringmediumlow / medium / high
is_templatebooleanfalseMark as a shared template
policiesarray[]Initial policies

PUT /api/policy_groups/{group_uuid}​

Update a policy group. Replaces the full policy list.

DELETE /api/policy_groups/{group_uuid}​

Delete a policy group.

GET /api/policy_groups/{group_uuid}/history​

Get version history for a policy group.

Query params: limit (int, default 10).

POST /api/policy_groups/{group_uuid}/copy​

Copy a policy group. The copy's name defaults to <original name>_copy. Pass ?name= to override.


Policies​

Individual policies within a policy group. All endpoints require JWT.

POST /api/policy_groups/{group_uuid}/policies​

Add a policy to a policy group.

Request body:

{
"name": "Financial Fraud",
"description": "Block content that facilitates financial fraud.",
"block_activities": [
"wire transfers to unknown accounts",
"sharing bank credentials"
],
"safe_activities": ["general banking education"],
"enabled": true
}

PUT /api/policy_groups/{group_uuid}/policies/{policy_id}​

Update a policy by _id. Partial fields are allowed.

DELETE /api/policy_groups/{group_uuid}/policies/{policy_id}​

Delete a policy by _id.


Templates​

Pre-built policy groups available to all users.

GET /api/templates​

List all template policy groups.

POST /api/templates/{template_id}/copy​

Copy a template to create a new policy group owned by the current user. Pass ?name= to override the default copy name.


Policy Extraction​

POST /api/policy_extraction​

Upload a PDF policy document and have PolicyGuard automatically extract policies from it using AI.

Request: multipart/form-data with a file field containing the PDF.

Response: a PolicyGroupOutput with extracted policies populated.


Guards​

Guards link one or more policy groups into a single classifier endpoint that customer applications call by UUID. All endpoints require JWT.

GET /api/guards​

List guards owned by the current user, including performance metrics.

GET /api/guards/{guard_uuid}​

Get a guard by UUID.

POST /api/guards​

Create a guard. Returns 201 Created.

Request:

{
"name": "Customer Support Guard",
"description": "Used by the customer support chatbot.",
"policy_group_uuids": ["pg_uuid_1", "pg_uuid_2"],
"enabled": true,
"settings": {
"max_text_length": 128000,
"cache_enabled": true,
"log_requests": true,
"overflow": "truncate"
}
}
FieldTypeDefaultDescription
namestringrequiredGuard name (1–255 chars)
descriptionstring—Optional description
policy_group_uuidsarray[]UUIDs of policy groups to link
enabledbooleantrueEnable/disable the guard
settings.max_text_lengthint—Max characters accepted
settings.cache_enabledboolean—Cache classification results
settings.log_requestsboolean—Log requests to observability
settings.overflowstringtruncatetruncate or throw when text exceeds limit

PUT /api/guards/{guard_uuid}​

Update a guard. Only provided fields are changed.

DELETE /api/guards/{guard_uuid}​

Delete a guard.


Content Safety​

These endpoints accept either a JWT or an API key.

POST /api/topic_guard​

Classify text using a saved guard. All policy groups linked to the guard are evaluated in parallel; the content is flagged if any group flags it.

Request body:

{
"text": "Text to evaluate",
"guard_uuid": "gd_your_guard_uuid",
"messages": [
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "earlier user message" }
]
}
FieldTypeRequiredDescription
textstringYesText to classify
guard_uuidstringYesGuard UUID
messagesarrayNoConversation history (role: system / user / assistant)

Response:

{
"flag": false,
"id": "gd_your_guard_uuid",
"guard": "Customer Support Guard",
"results": [
{
"policy_group_uuid": "pg_example",
"policy_group_name": "Customer Support Safety",
"flagged": false,
"threshold": 0.5,
"strictness_level": "medium",
"probs": { "PII Disclosure": 0.03 },
"categories": { "PII Disclosure": false },
"reasoning": null
}
],
"latency_ms": 85.2
}

POST /api/topic_guard_oneshot​

Classify text with ad-hoc policies that are not saved to the database. Useful for testing policies before creating a guard.

Request:

{
"text": "Text to classify",
"policies": [
{
"name": "Example Policy",
"description": "Block X, allow Y.",
"block_activities": ["X"],
"safe_activities": ["Y"],
"enabled": true
}
],
"threshold": 0.5,
"strictness_level": "medium"
}
FieldTypeDefaultDescription
textstringrequiredText to classify (min 1 char)
policiesarrayrequiredPolicies to evaluate (1–50 items)
thresholdfloat0.5Classification threshold
strictness_levelstringmediumlow / medium / high

Response:

{
"flag": false,
"threshold": 0.5,
"strictness_level": "medium",
"probabilities": { "Example Policy": 0.07 },
"results": { "Example Policy": false },
"reasoning": "string",
"latency_ms": 85.2,
"timestamp": "2026-01-15T10:30:00Z"
}

GET /api/cache/stats​

Return cache stats. Fields depend on the cache backend.

POST /api/cache/clear​

Clear the classification cache.


OpenAI Compatibility​

PolicyGuard provides a drop-in replacement for the OpenAI Moderation API. Point your existing OpenAI SDK at PolicyGuard's base URL — no other code changes required.

POST /api/v1/moderations​

Classify one or more texts using a guard.

Request:

{
"input": "string or array of strings",
"model": "gd_your_guard_uuid"
}
FieldTypeRequiredDescription
inputstring or string[]YesText(s) to classify
modelstringYesGuard UUID to use as the classifier

Response:

{
"id": "modr-abc123",
"model": "gd_your_guard_uuid",
"results": [
{
"flagged": true,
"categories": { "violence": true, "harassment": false },
"category_scores": { "violence": 0.94, "harassment": 0.08 },
"reasoning": [
"The text expresses intent to cause physical harm to another person."
]
}
]
}

Each item in results corresponds to one input string in the same order.

Python SDK Example​

from openai import OpenAI

client = OpenAI(
base_url="https://policyguard.example.com/api/v1",
api_key="sk-vai-your-api-key",
)

response = client.moderations.create(
input="I want to hurt someone",
model="gd_your_guard_uuid",
)

result = response.results[0]
print(result.flagged) # True
print(result.categories) # {"violence": True, ...}
print(result.category_scores) # {"violence": 0.94, ...}

Health and Metrics​

GET /health​

No authentication required.

{
"status": "healthy",
"version": "2.0.0",
"environment": "development"
}

GET /metrics​

Prometheus metrics endpoint. Enabled by metrics.enabled in the deployment config and mounted at metrics.path (default /metrics).