Skip to main content

aitoolsblocklist

aitoolsblocklist gives Python code a direct line to AI blocking data. You pass it a domain, and it tells you whether that domain is an AI tool, what the tool does, and what its vendor promises about training on your data. It also downloads the whole classified list for systems that need to match locally.

Who reaches for it: security engineers writing proxy plugins, network admins seeding a DNS sinkhole, compliance analysts building an AI inventory in a notebook, and school IT staff scripting a filtering policy. The list behind it holds more than 20,000 AI tool domains, sorted into 18 functional categories with subcategories, so a rule can separate a tutoring assistant from a voice cloner rather than treating "AI" as one thing. Each record also carries the vendor's training terms and the date they were checked.


Installation

pip install aitoolsblocklist

It needs Python 3.7 or later and pulls in one dependency, the requests library.

Quick start

from aitoolsblocklist import AIToolsBlocklistClient

client = AIToolsBlocklistClient("YOUR_API_KEY")

# Single lookup: is this domain an AI tool, and what kind?
result = client.lookup("chatgpt.com")
print(result["blocked"])             # True
print(result["primary_category"])    # "Text & Language"
print(result["ai_type"])             # "ai_native"
print(result["categories"])          # [{"category": "Text & Language", "subcategory": "General assistants & chatbots"}]
print(result["trains_on_data"])      # "opt_out_default"
print(result["terms_checked"])       # "2026-09-17"

# A convenience boolean for policy gates
if client.is_blocked("midjourney.com"):
    enforce_block_policy("midjourney.com")

Every paid plan comes with a key, which you copy from your account page. The client puts it in the X-API-Key header for you. Billing counts calls to lookup() only: stats(), taxonomy() and clause() are free and work without a key at all.

Three ways people use it

Per request. A proxy add-on, a browser extension backend or a SOAR playbook calls lookup() when a new domain appears and caches the answer. This suits low volume and moments when a decision has to be current.

In batches. An analyst has a spreadsheet of domains from a log export, a vendor questionnaire or an M&A due-diligence list. bulk_lookup() walks the list, skips duplicates and returns rows in the original order, ready for pandas.

From a local copy. Anything that sees every DNS query, such as a resolver, sinkhole or firewall, should never call out per query. Feed and database plans let download_database() fetch the full CSV, and matching happens in your own memory, SQLite or Redis.

The sections below cover each path.

Client reference

Constructor

client = AIToolsBlocklistClient(
    api_key="YOUR_API_KEY",
    base_url="https://www.aitoolsblocklist.com",  # default
    timeout=30,        # per-request timeout, seconds; downloads use at least 300
    max_retries=3,     # automatic backoff on 429, 503 and network errors
)

Retries use exponential backoff and respect a Retry-After header if the server sends one. Only throttling (429), temporary unavailability (503) and network faults are retried. A rejected key fails at once, since repeating the call cannot help.

Methods at a glance

Method Endpoint Key Purpose
lookup(domain) GET /api/check?domain= yes Classify one domain
is_blocked(domain) same yes Convenience boolean
bulk_lookup(domains, pause) same, sequential yes Deduplicated lookups, {"results": [...]} in input order
bulk_lookup_all(domains, pause) same yes The flat list
data_use(domain) same yes The five vendor data-use fields
stats() GET /api/stats.php no Totals and the 18 categories with counts
taxonomy() same no {name: {total, subcategories}}
clause(domain, field) GET /api/data-use-clause.php no Verbatim vendor clause with URL
database_status() GET /api/database/?action=status feed or database plan Plan and file state
database_info() GET /api/database/?action=database_info feed or database plan File name, timestamp, size
download_database(path) GET /api/database/?action=download_database feed or database plan Stream the full CSV to disk
download_categories(path) GET /api/database/?action=download_categories feed or database plan Stream the category tree CSV

Input handling and responses

You can hand lookup() anything from chatgpt.com to a full link with a path. The client removes the scheme, the path and any leading www. before sending. A subdomain is judged by its registrable parent, which is why chat.openai.com comes back with the record for openai.com. Unknown domains are not an error: they return HTTP 200 with blocked: false, so your code branches on one boolean.

report = client.bulk_lookup(["openai.com", "github.com", "notion.so"], pause=0.05)
for row in report["results"]:
    print(row["domain"], row["blocked"], row.get("primary_category"), row.get("trains_on_data"))

Here is what a hit looks like:

{
  "domain": "chatgpt.com",
  "blocked": true,
  "primary_category": "Text & Language",
  "ai_type": "ai_native",
  "categories": [{"category": "Text & Language", "subcategory": "General assistants & chatbots"}],
  "trains_on_data": "opt_out_default",
  "opt_out_available": "yes",
  "enterprise_no_training": "yes",
  "api_no_training": "yes",
  "terms_checked": "2026-09-17",
  "quota_remaining": 9999986
}

The four data-use fields take one of yes, no, opt_out_default or unstated. unstated is a result, not a gap: the terms were read and say nothing on that point. ai_type separates products whose core is AI (ai_native) from ordinary products that have added an AI feature (ai_enabled). For a domain outside the list, categories is empty.

Working from a local copy

On a feed or database plan, pull the whole classified CSV once and do the matching in memory:

info = client.database_info()
print(info["database_file"], info["last_updated"], info["file_size_human"])

client.download_database("/var/lib/atb/ai_tools_full.csv")
client.download_categories("/var/lib/atb/ai_tools_categories.csv")

import csv
blocked = {row["domain"] for row in csv.DictReader(open("/var/lib/atb/ai_tools_full.csv", encoding="utf-8"))
           if row["primary_category"] in {"Image & Visual", "Audio & Voice"}}

The file is rebuilt every day, so schedule the download for the night. After that, lookups cost nothing, however many millions your network makes. If your firewall or resolver prefers to fetch its own list, the account area also offers hosted EDL, PAC, hosts and DNS feeds.

Quoting the vendor's own words

c = client.clause("chatgpt.com", "trains_consumer_default")
if c:
    print(c["clause"], c["url"])

Pick one of four fields: trains_consumer_default, optout_available, enterprise_no_training or api_no_training. You get back the exact wording from the vendor's terms plus the URL of that page, ready to paste into a procurement or security review.

Exceptions

Each failure type has its own class, so an except clause can target exactly the case it handles:

from aitoolsblocklist import (
    AIToolsBlocklistError, AuthenticationError, QuotaError,
    PlanError, RateLimitError, NotFoundError,
)

try:
    result = client.lookup("example.com")
except AuthenticationError:
    ...   # 401: rotate or renew the key
except QuotaError:
    ...   # 403: inactive account or monthly quota exhausted
except PlanError as exc:
    ...   # 403 on the database endpoints: lookup-only plan, exc.body["plan"] names it
except RateLimitError:
    ...   # 429 after retries: back off or upgrade the plan
except AIToolsBlocklistError:
    ...   # any other API or network failure

Use a with block and the HTTP session closes itself:

with AIToolsBlocklistClient("YOUR_API_KEY") as client:
    print(client.stats()["total_tools"])

Background: the problem this data addresses

AI tools outnumber the rules written for them

Every week brings new AI products, each on its own domain and each happy to accept whatever a user pastes: a contract, a spreadsheet, a block of source code. Rules written by hand name the famous services and miss the long tail. A single "block AI" switch breaks tools the organisation has approved. What remains is shadow AI: tools nobody signed off on, handling data nobody meant to share.

What leaves the building

The risk is simple. Text submitted to an unfamiliar service may be stored, reviewed by staff, or used to train future models, depending on that vendor's terms. The NIST AI Risk Management Framework names confidentiality and third-party dependencies among the risks organisations should map, and it recommends an inventory of AI systems in actual use. Building that inventory starts with recognising which destinations in your traffic are AI tools. That is exactly what a domain classification provides, and the training fields turn a yes-or-no question into a more useful one: allowed, and on which plan?

Schools carry an extra duty

US districts that receive E-rate funding must filter under the Children's Internet Protection Act, as the FCC describes in its CIPA guidance. Generative AI makes that harder. A district may welcome an approved tutoring tool, reject essay generators on integrity grounds, and keep companion chat apps away from minors. That policy needs subcategories. One "AI" label cannot express it. University teaching centres have moved the same way, asking which tools suit which assignments instead of banning AI outright.

Why a separate, daily feed

Topic databases sort the web into shopping, news, social media and so on. Those labels change slowly, and they were never meant to tell a code assistant from a voice cloner. AI tools, by contrast, launch and vanish within weeks. A dedicated list rebuilt daily catches new tools soon after launch and organises them around the distinctions a policy needs. Digital-rights groups such as the Electronic Frontier Foundation have long argued that filtering must be precise and accountable to be legitimate. Precise categories let an admin block a real risk without breaking the tools people depend on.

How the pieces connect

Put lookup() wherever a live decision happens, and put download_database() in the nightly job that refreshes your resolver or firewall list. Heavy matching stays local, so the same code works for a hobby script and for a network making millions of queries. If you want an enforcement-oriented client instead, with a feeds sub-client, a Lookup object and a command line tool, see aiblocklist.

Before writing rules, most teams want to know where they stand. The hosted audit lets you find the AI tools employees use from a DNS, proxy or firewall export. It lists each AI tool seen, who reached it and whether the vendor trains on inputs, and delivers the results as a dated CSV and PDF, checked against the same list this package queries.

When you are ready to enforce, the AI Tools Blocklist lookup API supplies the data and this package connects it to Python.

AI rules rarely live alone. The same firewalls and resolvers usually enforce acceptable-use and security categories too, and our internet filtering database covers 120 million domains in 59 categories as a download for exactly those devices. With both lists loaded, one policy engine handles AI tools, acceptable use and security blocking.

For schools, the school web filtering solution provides the wider CIPA category coverage, refreshed daily and multi-labelled to cut over-blocking of learning material. Phishing is a constant threat on school networks, and an anti-phishing threat feed of 390,000+ DNS-verified active phishing domains lets the resolver that blocks AI tools stop credential theft pages as well.


Frequently asked questions

What exactly does this Python package query? It queries the classified register of AI tool domains, a list of more than 20,000 domains rebuilt every day. Each domain sits in one or more of 18 categories with subcategories, from chat assistants and coding tools to image and video generators, voice cloning, autonomous agents, companion apps and research tools. Besides the API used here, the same data ships as EDL, PAC, hosts and DNS feeds for firewalls, resolvers, gateways and DLP tools.

Which Python code blocks ChatGPT or Midjourney on my network? None on its own: this package informs the device that enforces. Load the feed into your firewall (EDL), browsers (PAC), resolver (DNS feed) or hosts file, then allow the categories you approve. For decisions made in code, for instance in a proxy add-on, lookup() or is_blocked() gives the answer in one call.

Is it all or nothing, or can a policy be selective? Selective. Because a lookup returns the main category, the full category list, the AI type and the training terms, your code can let an approved coding assistant through and still stop voice cloning or companion chat. Paid plans add 15 sector profiles, each with a Block, Controls or Allow verdict for every tool, if you would rather start from a ready policy.

Will I learn whether a tool uses my prompts for training? Five fields in every lookup cover it: trains_on_data, opt_out_available, enterprise_no_training, api_no_training and terms_checked. When you need proof rather than a flag, clause() fetches the relevant sentence of the terms together with its source URL.

My filter already has a generative AI category. Why add this? A topic-based filter usually lumps every AI site into one bucket and refreshes it when the vendor gets round to it. Here you get 18 categories with subcategories, AI types and training verdicts, rebuilt daily so new launches show up fast. It is sold as data, which means it sits next to whatever filter you run instead of replacing it.

How fresh is the data? It is rebuilt once a day. Call stats() (no key needed) for current totals, or database_info() for the timestamp of your downloadable file, and let a nightly job keep your copy in step.

Does it help a school district meet CIPA duties? It covers the AI slice of the problem. Districts and libraries use the categories to stop essay writers, deepfake apps and companion bots while keeping approved tutoring tools open. For the rest of a CIPA filtering policy, pair it with a general filtering database built for schools.

Which delivery formats can I choose from? This JSON lookup API, a firewall External Dynamic List, a PAC file, a hosts file, DNS feeds, and full CSV or JSON exports with every category attached.

Which company maintains it? Alpha Quantum. The same team runs the web filtering database and the website categorization API, plus the AI agent allow list, which handles the reverse problem: which web pages an organisation's own AI agents may open.

Further reading

  • Product site and API documentation: https://www.aitoolsblocklist.com
  • NIST AI Risk Management Framework (AI RMF 1.0)
  • FCC guidance on the Children's Internet Protection Act (CIPA)
  • NVIDIA NeMo Guardrails, programmable rails for LLM applications
  • OWASP Top 10 for Large Language Model Applications

License

MIT

Blocking tools solves half of shadow AI. The other half is what people paste into the tools that stay open. A GDPR PII detection service scans prompts, chat exports and DLP logs for personal data before it reaches an outside model. Pair a daily-refreshed AI tool blocklist with automated PII removal, and a compliance team controls both which AI services can be reached and what data may go into them.

Governance also runs the other way. Your own AI agents browse the web, and an AI agent allow list marks verified page-type URLs on 40 million+ domains, up to 28 page types each, so agents can read freely while login and payment pages stay off limits. Tool blocking plus agent access policy data covers both directions.

The Python source is kept in the explainableaixai GitHub repository, and a GitLab copy mirrors it.

Release files for aitoolsblocklist 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aitoolsblocklist 1.1.2
File Size Uploaded
aitoolsblocklist-1.1.2.tar.gz 20.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aitoolsblocklist 1.1.2
File Interpreter ABI Platform
aitoolsblocklist-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 34.6 kB

Release files / aitoolsblocklist-1.1.2.tar.gz

Download URL aitoolsblocklist-1.1.2.tar.gz
Size 20.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4b155a3aa21afb33a19604baa32931d647ad49c45d1b37ea454f2fa1658bce15
BLAKE2b-256 checksum
How to use checksums
6dfcf8c92d83539daff971f706697b6ee5a183a2f9eea75ed2a3966a5a1e3073
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.8.10

Release files / aitoolsblocklist-1.1.2-py3-none-any.whl

Download URL aitoolsblocklist-1.1.2-py3-none-any.whl
Size 13.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f487dee7056636639f9dd361f9b24b1db97a2e07ca212e689ee49fe07a2a8141
BLAKE2b-256 checksum
How to use checksums
5de6f06294db86f1513e8545319a46e1a69c7039fb77d1033058144bc2853c7a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.8.10

Release history Release notifications | RSS feed

This release

1.1.2 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page