Skip to content

Content Filters

Content Filters provide a rule-based content moderation layer that runs independently of the DLP pipeline. You can block requests containing specific keywords or topics, or prepend custom instructions to the system prompt for all requests in a given scope.

Filters are evaluated in ascending priority order (lower number = higher priority). The first matching block filter wins — once a request is blocked, remaining filters are not evaluated. Custom instruction filters are not blocking; they accumulate and all apply.

Type Slug Behavior Config schema
Keyword Block keyword_block Blocks requests containing any of the listed keywords (case-insensitive substring match) {"keywords": ["term1", "term2"], "message": "..."}
Topic Block topic_block Blocks requests matching any of the listed topics (case-insensitive substring match) {"topics": ["topic1", "topic2"], "message": "..."}
Custom Instruction custom_instruction Prepends the instruction to the system prompt for all requests in scope {"instruction": "Always respond in formal English."}

The message field in block filters is optional. When omitted, the platform returns a default message:

  • Keyword block: “Request blocked: contains prohibited content.”
  • Topic block: “Request blocked: topic not allowed.”

Each filter has a scope that determines which requests it applies to:

Scope Behavior
global Applies to all requests in the organization
group Applies only to requests from users in the specified group. Requires group_id.

Global filters always evaluate. Group-scoped filters evaluate only when the requesting user belongs to the filter’s target group.

  1. All enabled filters are loaded from the database, sorted by priority ascending (lower = higher priority, default is 100).
  2. Each filter is checked for scope applicability (global or matching group).
  3. For keyword_block and topic_block filters: if the user’s input matches, the request is blocked immediately. No further filters are evaluated.
  4. For custom_instruction filters: the instruction is collected. All matching custom instruction filters contribute their instructions, which are prepended to the system prompt before the model call.

All endpoints require admin authentication. Base path: /api/v1/admin/content-filters/.

Method Path Description
GET /api/v1/admin/content-filters/ List all content filters (ordered by priority)
GET /api/v1/admin/content-filters/{filter_id} Get a single content filter by ID
POST /api/v1/admin/content-filters/ Create a new content filter
PUT /api/v1/admin/content-filters/{filter_id} Update an existing content filter
DELETE /api/v1/admin/content-filters/{filter_id} Delete a content filter
Terminal window
curl -X POST https://platform.arbitex.ai/api/v1/admin/content-filters/ \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Block competitor mentions",
"description": "Prevent users from discussing competitor products",
"filter_type": "keyword_block",
"config": {
"keywords": ["CompetitorX", "RivalProduct", "AltVendor"],
"message": "Competitor discussions are not permitted in this channel."
},
"scope": "global",
"enabled": true,
"priority": 10
}'

Response (201 Created):

{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Block competitor mentions",
"description": "Prevent users from discussing competitor products",
"filter_type": "keyword_block",
"config": {
"keywords": ["CompetitorX", "RivalProduct", "AltVendor"],
"message": "Competitor discussions are not permitted in this channel."
},
"scope": "global",
"group_id": null,
"enabled": true,
"priority": 10,
"created_at": "2026-04-08T20:00:00Z",
"updated_at": "2026-04-08T20:00:00Z"
}
Terminal window
curl -X POST https://platform.arbitex.ai/api/v1/admin/content-filters/ \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Legal team compliance instruction",
"description": "Remind AI to include legal disclaimers",
"filter_type": "custom_instruction",
"config": {
"instruction": "You are assisting a legal professional. Always include appropriate legal disclaimers and note that your responses do not constitute legal advice."
},
"scope": "group",
"group_id": "f0e1d2c3-b4a5-6789-0123-456789abcdef",
"enabled": true,
"priority": 50
}'
Terminal window
curl https://platform.arbitex.ai/api/v1/admin/content-filters/ \
-H "Authorization: Bearer $ADMIN_TOKEN"

Returns all filters for the organization, sorted by priority ascending.

Terminal window
curl -X PUT https://platform.arbitex.ai/api/v1/admin/content-filters/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"enabled": false
}'

Partial updates are supported. Only include the fields you want to change.

Terminal window
curl -X DELETE https://platform.arbitex.ai/api/v1/admin/content-filters/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $ADMIN_TOKEN"

Returns 204 No Content on success.

Validate a rule configuration and test it against sample content without saving.

Terminal window
POST /api/v1/admin/content-filters/test
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"rule": {
"filter_type": "keyword_block",
"config": {
"keywords": ["confidential", "internal-only"]
}
},
"sample_text": "This document is confidential — do not distribute."
}

Response 200 OK:

{
"matched": true,
"action": "block",
"matches": [
{
"match": "confidential",
"start": 18,
"end": 30
}
],
"execution_time_ms": 0.4
}

Import multiple rules from a JSON array. Existing rules are not affected unless upsert: true is set and name matches.

Terminal window
POST /api/v1/admin/content-filters/bulk-import
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"upsert": false,
"rules": [
{ ... rule object without id ... },
{ ... }
]
}

Response 200 OK:

{
"created": 5,
"updated": 0,
"errors": []
}

Content filter trigger events appear in audit logs with action content_filter.triggered:

{
"action": "content_filter.triggered",
"details": {
"rule_id": "cfr_01HXYZ",
"rule_name": "Block Competitor Mentions",
"filter_action": "block",
"scope": "request",
"match_count": 1
}
}

Query recent trigger events:

Terminal window
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://platform.arbitex.ai/api/v1/admin/audit-logs?action=content_filter.triggered&limit=50"

The API enforces the following validation:

  • keyword_block requires a non-empty keywords list in config
  • topic_block requires a non-empty topics list in config
  • custom_instruction requires a non-empty instruction string in config
  • group scope requires a group_id
  • Invalid combinations return 400 Bad Request
Field Type Required Default Description
name string (max 255) yes Human-readable label
description string (max 1000) no null Purpose description
filter_type enum yes keyword_block, topic_block, or custom_instruction
config object yes Type-specific configuration (see Filter Types above)
scope enum no global global or group
group_id UUID conditional null Required when scope is group
enabled boolean no true Whether the filter is active
priority integer no 100 Evaluation order (lower = higher priority)