Crime & Justice Domain Classification Using Website Classification API
You need to detect and act on websites related to crime and justice—maybe to block them for brand safety, to flag them in a parental-control filter, or to enrich signups that originate from legal-services domains. By the end of this guide, you’ll have a working POST request to Klazify’s categorize endpoint, code that turns the response into a yes/no decision for “Crime & Justice,” and a clear plan for caching, batching, and mapping categories into your own taxonomy.
Why Klazify excels at classifying crime- and justice-related websites
Crime and justice content spans legal news, public records, court information, policy advocacy, and criminal law resources. Many of these pages are long-form, multilingual, and updated frequently. Klazify’s categorize endpoint is a good fit for this domain because it:
- Analyzes full website content using machine learning, which helps identify nuanced legal or judicial topics even when titles and metadata are minimal.
- Supports multilingual analysis, which matters for justice systems and public-safety content across regions and languages.
- Performs real-time classification for timely coverage of changing legal pages (e.g., newly posted court decisions or policy updates).
- Maps results to the IAB taxonomy so you can align classification with standard ad-tech and brand-safety workflows.
- Provides a simple, developer-friendly REST interface that’s straightforward to integrate into content filters, ad engines, or enrichment pipelines.
- Enables filtering, allowlisting, or blocklisting decisions based on consistent, machine-readable category names and confidences.
These traits help when you need a clear rule such as “block ads on criminal-justice pages,” “flag signups from legal-aid sites,” or “show different content experiences for law-enforcement domains.”
The scenario: blocking or flagging Crime & Justice pages in your pipeline
Suppose you operate an ad network and you want to prevent ads from appearing on crime-reporting or justice-system pages, or you want to route such pages to a special review queue. Your pipeline needs to:
- Send a page URL to Klazify.
- Receive categories and confidence scores in the response.
- Map those categories into your own “Crime & Justice” label.
- Return a yes/no decision in under a few hundred milliseconds, with smart caching to reduce API calls.
The sections below show a POST request, a realistic response example, and a minimal Python decision function that you can plug into your service.
Make a categorization request
Use the categorize endpoint with a POST request. You’ll pass the URL you want to classify in the JSON body. Authorization uses a Bearer token.
Example: classify a public justice website
curl -X POST "https://www.klazify.com/api/categorize" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.justice.gov/"}'
Notes:
- Replace YOUR_API_KEY with your token.
- The url field can be any publicly accessible page or domain. You can send homepage URLs (domain-level signals) or deep links (page-level context).
- For batch processing, call this endpoint per URL inside your job queue and implement caching (details below).
Understand the JSON response and what to use for Crime & Justice
Below is a sample response. Use this exact structure to build your parser. Values are representative of the fields and how you extract them; in production you will receive categories for the URL you sent.
{
"domain": {
"categories": [
{
"confidence": 0.92,
"name": "/Computers & Electronics/Consumer Electronics",
"IAB-632-596": "Consumer Electronics/Technology & Computing/Consumer Electronics"
},
{
"confidence": 0.89,
"name": "/Internet & Telecom/Mobile & Wireless/Mobile Phones"
}
],
"social_media": null,
"logo_url": "https://klazify.s3.amazonaws.com/2110787991611585019600ed5fb1d1300.04730104.png"
},
"success": true,
"objects": {
"company": {
"url": "https://www.apple.com/",
"name": "Apple",
"city": "Cupertino",
"stateCode": "CA",
"countryCode": "US",
"employeesRange": "100K+",
"revenue": 274515000000,
"raised": null,
"tags": [
"E-commerce",
"Consumer Electronics",
"Mobile",
"B2C"
],
"tech": [
"omniture_adobe_analytics",
"atlassian_confluence",
"successfactors",
"apache_apex",
"talend",
"oracle_peoplesoft",
"salesforce",
"stripe",
"dell_boomi_atomsphere",
"gigya",
"sage_50cloud",
"quickbooks",
"webmethods",
"apache_tomcat",
"alteryx",
"tibco_rendezvous",
"atlassian_jira",
"..."
]
}
},
"domain_registration_data": {
"domain_age_date": "1987-02-19",
"domain_age_days_ago": "13026",
"domain_expiration_date": "2030-02-20",
"domain_expiration_days_left": "123"
},
"similar_domains": [
"bestbuy.com",
"icloud.com",
"microsoft.com",
"macrumors.com",
"google.com",
"samsung.com",
"twitter.com",
"hp.com",
"bhphotovideo.com",
"dell.com"
]
}
How to use these fields for Crime & Justice workflows:
- domain.categories: The core of your decision. Parse each object for:
- name: Human-readable category path. Match this against your internal “Crime & Justice” mapping.
- confidence: Use as a threshold for automated actions (e.g., auto-block above a certain confidence, route to review below it).
- IAB-...: When present, a taxonomy code mapped to IAB. Use this for ad-tech alignment or if your taxonomy mirrors IAB.
- domain.logo_url: Useful to enrich UI dashboards, alerts, or moderation consoles when an item is flagged.
- objects.company: Helpful if you enrich signups or CRM records. For legal services or justice organizations, name, location, size, tags, and tech can guide routing or lead scoring.
- domain_registration_data: Can inform risk models. Extremely new domains might warrant additional scrutiny when categories suggest sensitive content.
- similar_domains: Seed allowlists or blocklists. If a confirmed justice-domain is flagged, you may review similar domains to expand coverage.
Turn categories into a yes/no decision for Crime & Justice
Below is a minimal Python example. It calls the same endpoint and checks if any returned category matches your curated set for “Crime & Justice.” Keep your category list centralized so multiple services can reuse it. Do not hardcode production taxonomies inside application code; load them from a configuration store to update without redeployment.
import json
import requests
from typing import List, Dict, Any
KLAZIFY_URL = "https://www.klazify.com/api/categorize"
API_KEY = "YOUR_API_KEY"
# Maintain your taxonomy in a config store or database.
# For illustration only: place the exact category names or IAB codes
# your team designates as "Crime & Justice" into the sets below.
CRIME_JUSTICE_CATEGORY_NAMES = {
# e.g., "/<Your Crime & Justice Category Path Here>"
}
CRIME_JUSTICE_IAB_CODES = {
# e.g., "IAB-XXX-YYY"
}
def is_crime_justice(categories: List[Dict[str, Any]], min_confidence: float = 0.60) -> bool:
"""
Returns True if any category or IAB code matches the team's "Crime & Justice" set,
and meets the confidence threshold.
"""
for cat in categories:
name = cat.get("name")
conf = float(cat.get("confidence", 0))
# Pick the first IAB key if present (keys follow the pattern "IAB-...")
iab_code = next((k for k in cat.keys() if k.startswith("IAB-")), None)
iab_val = cat.get(iab_code) if iab_code else None
if conf < min_confidence:
continue
if name and name in CRIME_JUSTICE_CATEGORY_NAMES:
return True
if iab_val and iab_val in CRIME_JUSTICE_IAB_CODES:
return True
return False
def categorize_url(url: str) -> Dict[str, Any]:
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {"url": url}
resp = requests.post(KLAZIFY_URL, headers=headers, json=payload, timeout=15)
resp.raise_for_status()
return resp.json()
def decide(url: str) -> Dict[str, Any]:
data = categorize_url(url)
domain = data.get("domain", {})
categories = domain.get("categories", [])
decision = is_crime_justice(categories)
result = {
"url": url,
"decision": "BLOCK" if decision else "ALLOW",
"categories": categories,
"logo_url": domain.get("logo_url"),
"company": (data.get("objects") or {}).get("company"),
"domain_registration_data": data.get("domain_registration_data"),
"similar_domains": data.get("similar_domains"),
}
return result
if __name__ == "__main__":
url_to_check = "https://www.justice.gov/"
print(json.dumps(decide(url_to_check), indent=2))
How to adapt this for production:
- Centralize your “Crime & Justice” taxonomy mapping in a versioned config store. Update the mapping without redeploying services.
- Implement multi-threshold logic. For example: auto-block if ≥ 0.85 confidence, send to review if between 0.60 and 0.85, allow otherwise.
- Log and store the original categories and confidences for auditability. Avoid reducing the response to a single label in your data lake.
Mapping categories into your own taxonomy
Teams often maintain a proprietary taxonomy that rolls up many granular categories into a few operational buckets like “Crime & Justice,” “Politics,” or “Health.” Here’s a simple approach to keep signal quality high:
- Build two maps:
- Category-name map: exact string matches of domain.categories[i].name to your internal labels.
- IAB-code map: matches of domain.categories[i]["IAB-..."] to your internal labels (when present).
- Prefer exact, case-sensitive matches on category name and IAB code. Avoid partial string matches unless you fully control the rule set.
- Include a “review” bucket for unrecognized categories with medium confidence so your moderation team can expand the mapping over time.
- Version the mapping. Keep a “mapping_version” field in your decision logs to correlate historical outcomes.
Operational guidance: latency, caching, batching, and unknown domains
To run at scale without surprises, wire in these practices:
Caching per domain or URL
- Cache by normalized URL for page-level decisions, or by registrable domain (e.g., example.com) for domain-level decisions.
- Maintain separate TTLs:
- Short TTL for dynamic news/legal pages (e.g., hours).
- Longer TTL for static institutional homepages (e.g., days).
- Store the full JSON response so future features can reuse it without another call.
Handling unknown or new domains
- If a domain is very new (see domain_registration_data.domain_age_date), consider stricter thresholds or manual review even when categories appear relevant.
- Fallback flows:
- No categories returned: default to “review” to avoid false allows, then recheck later.
- Low confidence across all categories: either backoff to a review queue or queue for recrawl after a delay.
Batching strategy
- Run parallel workers that each:
- Pop a URL from your queue.
- Check cache; if hit, skip network.
- Call the API; parse and store results alongside a decision record.
- Backpressure: cap the number of concurrent requests per worker and scale worker count horizontally to match throughput targets.
- Idempotency: deduplicate the same URL within a short window to avoid duplicate requests from concurrent jobs.
Rate limits and retries
- Implement exponential backoff and jitter for HTTP 429/5xx responses.
- Respect headers and guidance from the service regarding usage. Track request and error counts in your observability stack.
- Use a circuit breaker to avoid thundering herds during a transient outage.
Observability and QA
- Log inputs and outputs with request IDs. Mask or omit PII as required by your policies.
- Build a validation dashboard where reviewers can quickly:
- See the original URL, rendered title, and top categories with confidence.
- Override or confirm the decision.
- Extend your mapping to cover newly observed categories.
From fields to actions: what to do with the response
| Field | How to use it | Operational action | Notes |
|---|---|---|---|
| domain.categories[].name | Match to your “Crime & Justice” mapping | Block, allow, or review | Use exact string matches |
| domain.categories[].confidence | Set thresholds for automation vs. review | Auto-block above threshold | Log confidence for audits |
| domain.categories[].IAB-... | Align with IAB-based ad-tech rules | Contextual targeting or exclusion | Use when your taxonomy maps to IAB |
| objects.company.* | Enrich CRM, signup risk scoring | Route to legal/justice sales queues | Optional for content filtering |
| domain_registration_data.* | Assess domain freshness/tenure | Extra scrutiny for very new domains | Useful in trust/risk signals |
| similar_domains[] | Grow allow/block lists | Batch-validate related sites | Seed discovery jobs |
| domain.logo_url | Display in review and BI tools | Faster human triage | Cache to avoid hotlinking repeatedly |
End-to-end workflow example
- Receive a new publisher URL for ad serving.
- Normalize URL (scheme, trailing slashes, lowercase host). Check cache.
- If cache miss, POST to the categorize endpoint with the URL.
- Parse domain.categories and confidence values.
- Map to your “Crime & Justice” label using exact name and/or IAB-code matches.
- Apply a decision rule:
- If matched and confidence ≥ high threshold: BLOCK.
- If matched and confidence between low and high: REVIEW.
- Else: ALLOW.
- Persist the full JSON response, final decision, mapping_version, and thresholds used.
- Return the decision to your ad server within your SLA, using cached results for subsequent requests.
Security and compliance notes for sensitive content
- Minimize data collection: only store fields you need for decisions and audits.
- When enriching user-submitted domains, make sure your privacy policy discloses third-party categorization for risk and quality control.
- Keep an audit trail of your category mappings and threshold changes. For regulated environments, this helps explain historical decisions.
Common pitfalls and how to avoid them
- Over-reliance on a single category: Consider multiple categories and confidences. Some legal pages also cover policy or public safety; incorporate your team’s rules for overlaps.
- Ignoring page-level context: If a large site mixes topics, classify specific URLs, not just the root domain.
- Stale caches: Set TTLs suited to the content’s volatility. Recrawl news-heavy sections more often.
- Unversioned mappings: Always version your taxonomy mapping so you can reproduce past decisions.
Get started
To try the endpoint and see categories for your own list of URLs, you can start immediately. Create an account, grab your token, and plug it into the curl and Python snippets above.
FAQ
How do I decide between URL-level and domain-level classification?
Use URL-level classification for large publishers with diverse content sections (e.g., a court’s website that also hosts general news). Use domain-level classification for small sites with a single focus. You can maintain both: default to URL-level and fall back to the domain if the page lacks sufficient content.
What should I do if no categories are returned?
Place the item in a review queue and schedule a recheck. Some pages may be inaccessible at the time of crawl or have insufficient content. Keep a short retry schedule and a longer-term recrawl plan.
Can I combine category names and IAB codes in my decision?
Yes. Prefer exact string matches on names, and when an IAB mapping is present, use it to reinforce your decision or to align with ad-tech policies that are already IAB-based.
How do I handle rapidly changing legal news pages?
Use a shorter cache TTL and a secondary freshness trigger (e.g., if the URL’s last-modified timestamp changes). Reclassify when you detect significant content updates.
What’s a safe way to roll out new category mappings?
Use shadow mode first: compute decisions using the new mapping but don’t enforce. Compare outcomes over a defined window, then enable enforcement once metrics look good.
Ready to classify crime- and justice-related websites and automate your decisions? Create your account, connect to the categorize endpoint, and ship a production-ready integration today.
Ready to use Klazify?
Start classifying websites, enriching company data, and exploring web intelligence.
Get Started Free