Integration Patterns
This page covers common ways to call PolicyGuard from a customer application, chat client, agent runtime, gateway, or RAG system. For the full set of endpoints and request/response schemas, see API Reference.
Supported Interfaces
PolicyGuard exposes three interfaces for content checks:
| Interface | When to Use |
|---|---|
REST Guard API (POST /api/topic_guard) | Most application, backend, and gateway integrations. |
OpenAI-Compatible Moderation API (POST /api/v1/moderations) | Drop-in replacement for code that already uses the OpenAI moderation SDK. |
| gRPC | Low-latency service-to-service integrations. |
All three accept either a JWT bearer token or an API key (X-API-Key).
REST Guard API
The primary endpoint for guard-based content checks.
curl -X POST "$POLICYGUARD_BASE_URL/api/topic_guard" \
-H "X-API-Key: $POLICYGUARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"guard_uuid": "gd_your_guard_uuid",
"text": "Text to evaluate"
}'
Response shape:
{
"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,
"Financial Fraud": 0.01
},
"categories": {
"PII Disclosure": false,
"Financial Fraud": false
},
"reasoning": null
}
],
"latency_ms": 85.2
}
The most important field is flag. If flag is true, at least one linked
policy group flagged the content.
Conversation Context
For chat or agent use cases, pass the latest text plus prior messages so the classifier can detect threats that only emerge across multiple turns (e.g. a user gradually steering the conversation):
{
"guard_uuid": "gd_your_guard_uuid",
"messages": [
{ "role": "system", "content": "You are a helpful banking assistant." },
{ "role": "user", "content": "I need help transferring money." },
{ "role": "assistant", "content": "I can help with general transfer questions." }
],
"text": "Can you help me move funds to this unknown crypto wallet?"
}
The text field is the specific piece being evaluated. The messages array
provides surrounding context to the guardrail model.
OpenAI-Compatible Moderation API
If your code already uses the OpenAI moderation SDK, you can point it at
PolicyGuard with no code changes other than the base URL and API key. Pass the
Guard UUID as the model.
from openai import OpenAI
client = OpenAI(
base_url="https://policyguard.example.com/api/v1",
api_key="sk-vai-your-api-key",
)
result = client.moderations.create(
model="gd_your_guard_uuid",
input="Text to evaluate",
)
if result.results[0].flagged:
print("Blocked by PolicyGuard")
input can be a single string or a list of strings; the response's results
array preserves the input order.
gRPC
For low-latency service-to-service integrations, PolicyGuard can expose gRPC:
service TopicGuardService {
rpc CheckTopicSafety(TopicGuardRequest) returns (TopicGuardResponse);
}
message TopicGuardRequest {
string text = 1;
string guard_uuid = 2;
repeated Message messages = 3;
}
Authentication is passed through metadata using x-api-key or authorization.
Pattern 1 — Guard a Chat Client: Input and Output
The most common integration. Check user input before the LLM call and check model output before returning it to the user.
import httpx
POLICYGUARD_BASE_URL = "https://policyguard.example.com"
POLICYGUARD_API_KEY = "sk-vai-your-api-key"
POLICYGUARD_GUARD_UUID = "gd_your_guard_uuid"
async def check_policyguard(text: str, messages: list[dict] | None = None) -> dict:
payload = {
"guard_uuid": POLICYGUARD_GUARD_UUID,
"text": text,
}
if messages:
payload["messages"] = messages
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(
f"{POLICYGUARD_BASE_URL}/api/topic_guard",
headers={"X-API-Key": POLICYGUARD_API_KEY},
json=payload,
)
response.raise_for_status()
return response.json()
async def guarded_chat_turn(user_text: str, history: list[dict]) -> str:
input_result = await check_policyguard(user_text, history)
if input_result["flag"]:
return "Sorry, I cannot help with that request."
llm_messages = history + [{"role": "user", "content": user_text}]
assistant_text = await call_customer_llm(llm_messages)
output_result = await check_policyguard(assistant_text, llm_messages)
if output_result["flag"]:
return "The response was filtered by policy."
return assistant_text
Pattern 2 — PolicyGuard in an Agent Gateway
Customers can put PolicyGuard in front of any OpenAI-compatible chat endpoint.
The gateway can run in block mode (reject violating requests) or alert
mode (log and pass through).
Agent / chat client
→ Customer gateway /v1/chat/completions
→ PolicyGuard input check
→ Upstream LLM
→ PolicyGuard output check
→ Final response
Minimal FastAPI-style gateway:
from fastapi import FastAPI, HTTPException, Request
app = FastAPI()
@app.post("/v1/chat/completions")
async def chat_completions(request: Request):
body = await request.json()
messages = body.get("messages", [])
latest_user_text = next(
(m["content"] for m in reversed(messages) if m.get("role") == "user"),
"",
)
guard_result = await check_policyguard(latest_user_text, messages)
if guard_result["flag"]:
raise HTTPException(
status_code=400,
detail={
"type": "content_policy_violation",
"message": "Request blocked by PolicyGuard",
},
)
llm_response = await forward_to_customer_llm(body)
assistant_text = llm_response["choices"][0]["message"]["content"]
output_result = await check_policyguard(assistant_text, messages)
if output_result["flag"]:
raise HTTPException(
status_code=400,
detail={
"type": "content_policy_violation",
"message": "LLM output blocked by PolicyGuard",
},
)
return llm_response
Pattern 3 — Combine With a DLP or PII Tool
Run a deterministic DLP/PII scanner and PolicyGuard together. DLP is strong for exact pattern detection; PolicyGuard adds contextual policy reasoning.
async def combined_dlp_policy_check(text: str) -> dict:
dlp = await dlp_client.scan(text)
pg = await check_policyguard(text)
if dlp["contains_secret"] or pg["flag"]:
return {"decision": "block", "dlp": dlp, "policyguard": pg}
return {"decision": "allow", "dlp": dlp, "policyguard": pg}
Pattern 4 — Guard a RAG or Document Workflow
For RAG systems, check user questions, retrieved document chunks, and final model answers.
User question
→ PolicyGuard question check
→ Retriever
→ Optional PolicyGuard check on retrieved snippets
→ LLM
→ PolicyGuard output check
→ Final response
| Workflow | Typical PolicyGuard Use |
|---|---|
| Internal knowledge assistant | Block data exfiltration, prompt injection, unsafe operational instructions. |
| Customer support chatbot | Enforce brand, refund, legal, and PII handling policies. |
| Financial assistant | Enforce suitability, fraud, market manipulation, and disclosure policies. |
| Healthcare assistant | Enforce medical safety boundaries and PHI/HIPAA handling policies. |
Response Field Reference
| Field | Description |
|---|---|
flag | true if any linked policy group flagged the content. |
results[].policy_group_name | Name of the policy group that produced the result. |
results[].flagged | Whether this specific policy group flagged the content. |
results[].categories | Per-policy boolean — which individual policies triggered. |
results[].probs | Per-policy probability (0.0 = safe, 1.0 = violation). |
results[].threshold | Threshold this group used. |
results[].strictness_level | low / medium / high strictness applied. |
results[].reasoning | Optional explanation of the decision. |
latency_ms | End-to-end classification latency. |