APIValidate Rule Endpoint

Validate Rule Endpoint

The POST /api/validate-rule endpoint parses a single adblock filter rule and reports whether it is structurally valid. An optional URL match test lets you...

Validate Rule Endpoint

The POST /api/validate-rule endpoint parses a single adblock filter rule and reports whether it is structurally valid. An optional URL match test lets you quickly verify whether a rule would block a specific hostname.


Request

POST /api/validate-rule

By default, this endpoint is unauthenticated in the public Cloudflare Worker. In self-hosted or secured deployments, your API gateway or reverse proxy may require a Bearer token in the Authorization header.

Body

{
    "rule": "||example.com^",       // required — the rule string to validate
    "testUrl": "https://example.com/page",  // optional — check if the rule matches this URL
    "strict": false                 // optional — use the strict (non-tolerant) parser
}
FieldTypeRequiredDescription
rulestring✅The adblock filter rule to validate
testUrlstring❌A URL to test the rule against (hostname matching only)
strictboolean❌When true, uses the strict AGTree parser that rejects rules with unrecognised modifiers or malformed patterns. Default: false

Responses

Valid rule — 200

{
    "success": true,
    "valid": true,
    "rule": "||example.com^",
    "ruleType": "NetworkRule",
    "category": "blocking",
    "syntax": "AdGuard",
    "ast": { /* parsed AGTree node */ },
    "duration": "2ms"
}

Valid rule with URL match test — 200

{
    "success": true,
    "valid": true,
    "rule": "||example.com^",
    "ruleType": "NetworkRule",
    "category": "blocking",
    "syntax": "AdGuard",
    "ast": { /* ... */ },
    "testUrl": "https://example.com/page",
    "matchResult": true,
    "duration": "3ms"
}

matchResult is undefined (omitted) when the rule type does not carry enough structural information for a reliable hostname match (e.g., cosmetic or script rules).

Invalid rule — 200

The HTTP status is still 200; the valid field indicates the outcome.

{
    "success": true,
    "valid": false,
    "rule": "##bad selector{",
    "ruleType": "CosmeticRule",
    "error": "Unexpected end of selector",
    "duration": "1ms"
}

Schema validation error — 422

Returned when the request body fails schema validation. The error field contains the actual Zod validation message(s) joined by ; .

// Empty rule string
{ "success": false, "error": "Rule must not be empty" }

// Invalid testUrl
{ "success": false, "error": "testUrl must be a valid URL" }

Examples

cURL

# Basic validation
curl -X POST https://api.bloqr.dev/api/validate-rule \
  -H "Content-Type: application/json" \
  -d '{"rule":"||ads.example.com^"}'

# With URL match test
curl -X POST https://api.bloqr.dev/api/validate-rule \
  -H "Content-Type: application/json" \
  -d '{"rule":"||ads.example.com^","testUrl":"https://ads.example.com/banner.png"}'

# Strict mode
curl -X POST https://api.bloqr.dev/api/validate-rule \
  -H "Content-Type: application/json" \
  -d '{"rule":"||ads.example.com^$important","strict":true}'

TypeScript

const res = await fetch('/api/validate-rule', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ rule: '||ads.example.com^', testUrl: 'https://ads.example.com/' }),
});

const { valid, ruleType, matchResult } = await res.json();

Strict Mode

When strict: true, the endpoint runs the rule through the non-tolerant AGTree parser before the standard parse. The strict parser rejects:

  • Rules with unrecognised modifiers (e.g., $unknownModifier)
  • Malformed patterns that the tolerant parser silently accepts

Use strict mode when building validation tooling or CI pipelines that enforce a curated modifier allowlist.


Notes

  • URL matching uses hostname-only comparison (no path, query, or protocol checks). For production-grade matching, use a full DNS/network filtering engine.
  • The ast field contains the raw AGTree parse tree and is useful for debugging or building editor tooling.
  • Both ruleType and category use AGTree's terminology. See the AGTree Integration guide for a full taxonomy.