Ana içeriğe geç

AI Topic Guard Policy

General Information​

Policy Type​

ai-topic-guard

Endpoints​

List Policies​

GET /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/

Add Policy​

POST /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/

Update Policy​

PUT /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/

Delete Policy​

DELETE /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/

Topic Matching​

The prompt is embedded and compared, by cosine similarity, against the descriptions in allowedTopics and deniedTopics. A denied-topic match is evaluated before allowedTopics, and wins — a prompt matching a denied topic is flagged/blocked even if it would otherwise pass the allow list.

Fields​

FieldTypeRequiredDescription
allowedTopicsarray of stringsNoAdmin-defined descriptions of the topics the traffic is allowed to be about.
similarityThresholdnumberNoMinimum cosine similarity, -1.0 to 1.0, for the prompt to be considered on-topic against allowedTopics.
actionstringNoFLAG or BLOCK on an off-topic (allow-list) detection.
deniedTopicsarray of stringsNoAdmin-defined descriptions of topics that are never allowed, regardless of allowedTopics. Can be populated by hand, or copied from the platform's built-in content-safety category catalog (Guardrails hub → Content Safety tab, MLCommons AILuminate hazard categories) — either way, this field stores plain text; no catalog reference is retained.
deniedSimilarityThresholdnumberNoMinimum cosine similarity, -1.0 to 1.0, for a deniedTopics match. null falls back to similarityThreshold.
deniedActionstringNoFLAG or BLOCK on a denied-topic match. null falls back to action.
embeddingProviderNamestringNoName of the LLM provider connection config used to compute embeddings.
embeddingModelIdstringNoEmbedding model identifier.
embeddingDimensionintegerNoExpected embedding vector dimension.

Evaluation Timing​

FieldTypeRequiredDescription
latencyModestringNoINLINE (default) or ASYNC. INLINE blocks the request thread for the embed + similarity check; ASYNC runs it bounded by maxWaitMs.
maxWaitMsintegerConditionalMax wait in milliseconds under ASYNC. Must be positive if set.
failOpenOnErrorbooleanNoWhether an embedding-call failure lets the request pass (true, default) or blocks it (false).

External Guardrail​

engine decides which decision sources feed the policy's verdict.

ValueBehaviour
BUILTIN (default)Only the embedding similarity check (allowedTopics/deniedTopics) is evaluated.
BUILTIN_PLUS_EXTERNALThe similarity check and the external adapter both run. Either one can trigger a block.
EXTERNAL_ONLYOnly the external adapter is evaluated.

failMode governs what happens when the external adapter call itself errors or times out:

ValueBehaviour
FAIL_CLOSED (default)The request is blocked.
FAIL_OPENThe request continues; a FAIL_OPEN signal is recorded so the bypass is visible.

externalGuardrail Fields​

Only the llm-judge adapter is supported on this policy.

FieldTypeRequiredDescription
typestringYesMust be llm-judge.
llmProviderNamestringYesName of the LLM provider connection config used to run the judge call. Required whenever externalGuardrail is present, regardless of type.
promptTemplatestringConditionalJudge prompt template. Required, non-blank, for this policy — unlike the Prompt Guard policy, a blank template here falls back to a generic native safety judge that does not actually answer a topic-relevance question, so it is rejected at save time instead.
modelIdstringNoJudge model identifier.
jsonModebooleanNoWhether the judge is asked to respond in JSON mode.
maxOutputTokensintegerNoJudge max output tokens. Must be positive if set.
timeoutMsintegerNoHTTP call timeout in milliseconds. Must be positive if set.
maxInputCharsintegerNoMax input characters sent to the judge. Must be positive if set.

Other Fields​

FieldTypeRequiredDescription
decodeEncodedContentbooleanNoDecodes base64/hex/URL/unicode segments before embedding. Default false.
includeSystemPromptsbooleanNoAlso embeds system-role messages in the topic comparison. null means false — only the last user message is embedded by default.
includeAssistantPromptsbooleanNoAlso embeds assistant-role messages. null means false.
includeToolPromptsbooleanNoAlso embeds tool-role messages. null means false.
Opt-in, not opt-out

Unlike the role-scope fields on the Prompt Guard policy, includeSystemPrompts/includeAssistantPrompts/includeToolPrompts here default to embedding only the last user message. Turning any of them on switches this guard to whole-conversation scanning, which changes embedding size, cost and similarity scores — opt in deliberately.


List Policies​

Endpoint​

GET /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/

Request​

Headers​

HeaderValue
AuthorizationBearer {token}
Content-Typeapplication/json

Path Parameters​

ParameterTypeRequiredDescription
projectNamestringYesProject name
apiProxyNamestringYesAPI Proxy name

Response​

Success Response (200 OK)​

{
"status": "SUCCESS",
"resultList": [
{
"apiProxy": {
"name": "MyAiProxy",
"requestPolicyList": [
{
"type": "ai-topic-guard",
"name": "support-scope-guard",
"description": "Keeps the support assistant on billing/account topics",
"active": true,
"allowedTopics": [
"billing and invoices",
"account settings and password resets"
],
"similarityThreshold": 0.78,
"action": "BLOCK",
"deniedTopics": [
"medical advice or diagnosis"
],
"deniedSimilarityThreshold": 0.7,
"deniedAction": "BLOCK",
"embeddingProviderName": "internal-embedding-model",
"embeddingModelId": "text-embedding-3-small",
"embeddingDimension": 1536,
"latencyMode": "INLINE",
"failOpenOnError": true,
"engine": "BUILTIN"
}
],
"responsePolicyList": [],
"errorPolicyList": []
}
}
],
"resultCount": 1
}

cURL Example​

curl -X GET \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAiProxy/policies/" \
-H "Authorization: Bearer YOUR_TOKEN"

Add Policy​

Endpoint​

POST /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/

Request​

Headers​

HeaderValue
AuthorizationBearer {token}
Content-Typeapplication/json

Path Parameters​

ParameterTypeRequiredDescription
projectNamestringYesProject name
apiProxyNamestringYesAPI Proxy name
policyNamestringYesPolicy name

Request Body​

Full JSON Body Example — Allow List Plus Denied Topics​
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "ai-topic-guard",
"description": "Keeps the support assistant on billing/account topics",
"active": true,
"allowedTopics": [
"billing and invoices",
"account settings and password resets"
],
"similarityThreshold": 0.78,
"action": "BLOCK",
"deniedTopics": [
"medical advice or diagnosis"
],
"deniedSimilarityThreshold": 0.7,
"deniedAction": "BLOCK",
"embeddingProviderName": "internal-embedding-model",
"embeddingModelId": "text-embedding-3-small",
"embeddingDimension": 1536,
"latencyMode": "ASYNC",
"maxWaitMs": 1000,
"failOpenOnError": true
}
}
Full JSON Body Example — With an External LLM-Judge​
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 2
},
"policy": {
"type": "ai-topic-guard",
"description": "Embedding similarity plus a judge model as a second opinion",
"active": true,
"allowedTopics": ["billing and invoices"],
"similarityThreshold": 0.78,
"action": "BLOCK",
"embeddingProviderName": "internal-embedding-model",
"engine": "BUILTIN_PLUS_EXTERNAL",
"failMode": "FAIL_CLOSED",
"externalGuardrail": {
"type": "llm-judge",
"llmProviderName": "internal-guard-model",
"promptTemplate": "Is the following user message strictly about billing, invoices, or account settings? Answer YES or NO.\n\nMessage: {{input}}",
"timeoutMs": 2000
}
}
}

Request Body Fields​

See Topic Matching, Evaluation Timing, External Guardrail and Other Fields above. type (ai-topic-guard), description and active follow the common policy contract; name comes from the path parameter.

Response​

Success Response (200 OK)​

{
"status": "SUCCESS",
"deploymentResult": {
"success": true,
"deploymentResults": [
{
"environmentName": "production",
"success": true,
"message": "Deployment successful"
}
]
}
}

Error Responses​

CodeReason
400Blank name; similarityThreshold/deniedSimilarityThreshold outside -1.0–1.0; maxWaitMs not positive; engine is not BUILTIN but externalGuardrail is missing; externalGuardrail.type/llmProviderName blank; blank promptTemplate for an llm-judge adapter; timeoutMs/maxOutputTokens/maxInputChars not positive; proxy not found.
401Missing or invalid token.
403The token's account lacks permission on the project.

cURL Example​

curl -X POST \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAiProxy/policies/support-scope-guard/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "ai-topic-guard",
"description": "Keeps the support assistant on billing/account topics",
"active": true,
"allowedTopics": ["billing and invoices"],
"similarityThreshold": 0.78,
"action": "BLOCK",
"embeddingProviderName": "internal-embedding-model"
}
}'

Update Policy​

Endpoint​

PUT /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/

Request​

The body is the same shape as Add Policy. The update replaces the policy, so send the fields you want to keep — including every entry in allowedTopics and deniedTopics.

Full JSON Body Example — Adding a Denied Topic​
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "ai-topic-guard",
"description": "Keeps the support assistant on billing/account topics",
"active": true,
"allowedTopics": ["billing and invoices"],
"similarityThreshold": 0.78,
"action": "BLOCK",
"deniedTopics": [
"medical advice or diagnosis",
"legal advice"
],
"deniedAction": "BLOCK",
"embeddingProviderName": "internal-embedding-model"
}
}

Response​

Success Response (200 OK)​

{
"status": "SUCCESS",
"deploymentResult": {
"success": true,
"deploymentResults": [
{
"environmentName": "production",
"success": true,
"message": "Deployment successful"
}
]
}
}

cURL Example​

curl -X PUT \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAiProxy/policies/support-scope-guard/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"]
},
"policy": {
"type": "ai-topic-guard",
"active": true,
"allowedTopics": ["billing and invoices"],
"similarityThreshold": 0.78,
"action": "BLOCK",
"deniedTopics": ["medical advice or diagnosis", "legal advice"],
"embeddingProviderName": "internal-embedding-model"
}
}'

Delete Policy​

Endpoint​

DELETE /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/

Request​

Headers​

HeaderValue
AuthorizationBearer {token}

Path Parameters​

ParameterTypeRequiredDescription
projectNamestringYesProject name
apiProxyNamestringYesAPI Proxy name
policyNamestringYesPolicy name

Response​

Success Response (200 OK)​

{
"status": "SUCCESS"
}

cURL Example​

curl -X DELETE \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAiProxy/policies/support-scope-guard/" \
-H "Authorization: Bearer YOUR_TOKEN"

Notes and Warnings​

  • A denied-topic match always wins. deniedTopics is evaluated before allowedTopics, so a prompt matching a denied topic is flagged/blocked even if it would also match an allowed topic.
  • deniedSimilarityThreshold/deniedAction left null track similarityThreshold/action dynamically, not a frozen copy taken at save time — changing the allow-list threshold later also changes the effective denied-topic threshold, unless you set the denied fields explicitly.
  • An embed-call failure passes the request through by default (failOpenOnError: true). Set it to false only if blocking on an embedding-provider outage is the safer failure mode for this traffic.
  • promptTemplate is mandatory for an llm-judge external adapter on this policy — unlike the Prompt Guard policy, a blank template is rejected rather than silently falling back to a generic judge that can't answer a topic-relevance question.
  • includeSystemPrompts/includeAssistantPrompts/includeToolPrompts default to off — enabling any of them switches this guard from "last user message only" to whole-conversation embedding, which changes cost and similarity scores; opt in deliberately.
  • deniedTopics entries copied from the built-in content-safety catalog carry no back-reference. Editing the catalog category later does not update a policy that already copied its description — re-copy it by hand if you want the update.