Skip to content

API Reference: Content Filter Rules

Base path: /api/admin/content-filters

Content filter rules are custom allowlist/blocklist rules evaluated in the Arbitex DLP pipeline alongside built-in pattern matching. Rules can block or flag specific regex patterns, keyword lists, or topic categories in both request and response payloads.

Content filters differ from DLP rules in scope: DLP rules govern sensitive data detection and redaction; content filters govern topic-level policy (e.g., block competitor mentions, flag financial advice, block off-topic queries).


{
"rule_id": "cfr_01HXYZ",
"name": "Block Competitor Mentions",
"description": "Block requests that mention competitor product names",
"enabled": true,
"rule_type": "keyword_list",
"scope": "request",
"action": "block",
"config": {
"keywords": ["CompetitorAlpha", "CompetitorBeta"],
"case_sensitive": false,
"match_whole_word": true
},
"group_ids": ["grp_01HXYZ"],
"priority": 100,
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-03-01T09:00:00Z",
"stats": {
"trigger_count_7d": 42,
"last_triggered_at": "2026-03-12T08:00:00Z"
}
}
FieldTypeDescription
rule_idstringUnique rule identifier
namestringHuman-readable rule name
enabledbooleanWhether rule is active
rule_typestringregex | keyword_list | topic_classifier
scopestringrequest | response | both
actionstringblock | flag | redact | require_approval
configobjectType-specific configuration (see below)
group_idsarrayGroups this rule applies to. Empty = all groups
priorityintegerEvaluation order (lower = higher priority, 1–1000)

regex config:

{
"pattern": "\\b(internal|confidential|proprietary)\\s+project\\s+\\w+\\b",
"flags": "i",
"capture_group": 0
}

keyword_list config:

{
"keywords": ["word1", "phrase one", "another phrase"],
"case_sensitive": false,
"match_whole_word": true
}

topic_classifier config:

{
"topics": ["financial_advice", "medical_advice", "legal_advice"],
"confidence_threshold": 0.85,
"model": "arbitex-topic-v2"
}

Available built-in topics: financial_advice, medical_advice, legal_advice, adult_content, violence, hate_speech, competitor_comparison, pii_request.


GET /api/admin/content-filters
Authorization: Bearer <admin-token>

Query parameters:

ParameterTypeDescription
enabledbooleanFilter by enabled state
rule_typestringFilter by type: regex | keyword_list | topic_classifier
scopestringFilter by scope: request | response | both
group_idstringFilter rules that apply to a specific group
limitintegerMax results (default: 50, max: 200)
offsetintegerPagination offset

Response 200 OK:

{
"rules": [...],
"total": 18,
"limit": 50,
"offset": 0
}

GET /api/admin/content-filters/{rule_id}
Authorization: Bearer <admin-token>

Response 200 OK: Rule object. 404 if not found.


POST /api/admin/content-filters
Authorization: Bearer <admin-token>
Content-Type: application/json

Example — block competitor keywords for all groups:

{
"name": "Block Competitor Mentions",
"description": "Block requests mentioning direct competitors",
"enabled": true,
"rule_type": "keyword_list",
"scope": "request",
"action": "block",
"config": {
"keywords": ["CompetitorAlpha", "CompetitorBeta"],
"case_sensitive": false,
"match_whole_word": true
},
"group_ids": [],
"priority": 100
}

Example — flag financial advice via topic classifier:

{
"name": "Flag Financial Advice",
"rule_type": "topic_classifier",
"scope": "response",
"action": "flag",
"config": {
"topics": ["financial_advice"],
"confidence_threshold": 0.80,
"model": "arbitex-topic-v2"
},
"group_ids": [],
"priority": 200
}

Example — regex pattern to redact internal project names:

{
"name": "Redact Internal Project Names",
"rule_type": "regex",
"scope": "both",
"action": "redact",
"config": {
"pattern": "Project (Nighthawk|Falcon|Zeus)",
"flags": "i"
},
"priority": 50
}

Response 201 Created: Full rule object with generated rule_id.

Validation errors:

{
"error": "validation_error",
"details": [
{"field": "config.pattern", "message": "Invalid regex: unterminated group"},
{"field": "priority", "message": "Must be between 1 and 1000"}
]
}

PUT /api/admin/content-filters/{rule_id}
Authorization: Bearer <admin-token>
Content-Type: application/json

Full replacement of the rule. All fields except rule_id, created_at, and stats may be updated.

Response 200 OK: Updated rule object.


PATCH /api/admin/content-filters/{rule_id}
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"enabled": false
}

Patchable fields: enabled, priority, group_ids, description

Response 200 OK.


DELETE /api/admin/content-filters/{rule_id}
Authorization: Bearer <admin-token>

Response 204 No Content.


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

POST /api/admin/content-filters/test
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"rule": {
"rule_type": "regex",
"scope": "request",
"action": "block",
"config": {
"pattern": "\\bSSN\\b.*\\d{3}-\\d{2}-\\d{4}",
"flags": "i"
}
},
"sample_text": "My SSN is 123-45-6789, please don't share it."
}

Response 200 OK:

{
"matched": true,
"action": "block",
"matches": [
{
"match": "SSN is 123-45-6789",
"start": 3,
"end": 21
}
],
"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.

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

Response 200 OK:

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

Rules are evaluated in ascending priority order (1 = first). When a rule fires and its action is block, evaluation stops and the request/response is blocked immediately. flag and redact rules continue evaluation — multiple flags can accumulate.

Evaluation pipeline:

request → [priority 1 rule] → [priority 2 rule] → ... → response

If a block fires mid-pipeline, the request is rejected and a DLP audit log entry is created with action=block and the matching rule_id.


Content filter trigger events appear in audit logs:

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

Query recent triggers:

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

StatusCodeDescription
400invalid_requestMalformed JSON
404not_foundRule not found
422validation_errorInvalid regex, unknown topic, or out-of-range priority
409name_conflictRule with this name already exists (on bulk import without upsert)