Metadata-Version: 2.1
Name: aitoolsblocklist
Version: 1.1.2
Summary: Python client for the AI Tools Blocklist API: 20,000+ classified AI-tool domains with vendor training-on-your-data verdicts, for web filtering, DNS security and DLP.
Home-page: https://www.aitoolsblocklist.com
Author: Alpha Quantum
Author-email: info@alpha-quantum.com
License: MIT
Project-URL: Homepage, https://www.aitoolsblocklist.com
Project-URL: API Documentation, https://www.aitoolsblocklist.com/ai-blocklist-api.php
Project-URL: Source, https://github.com/explainableaixai/aitoolsblocklist
Project-URL: Tracker, https://www.aitoolsblocklist.com/contact.php
Project-URL: Shadow AI Tools, https://www.shadowaitools.com
Project-URL: Resume Reader API, http://resumereaderapi.com
Project-URL: AI Agent Allow List, https://www.aiagentallowlist.com
Keywords: ai tools blocklist,web filtering,dns filtering,content filtering,ai domain classification,shadow ai,data loss prevention,dlp,cipa,acceptable use policy,ai governance,domain categorization
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: Proxy Servers
Classifier: Topic :: Security
Classifier: Topic :: System :: Networking :: Firewalls
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests >=2.20.0

# aitoolsblocklist

`aitoolsblocklist` gives Python code a direct line to [AI blocking](https://www.aitoolsblocklist.com) 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

```bash
pip install aitoolsblocklist
```

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

## Quick start

```python
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

```python
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.

```python
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:

```json
{
  "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:

```python
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

```python
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:

```python
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:

```python
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`](https://pypi.org/project/aiblocklist/).

Before writing rules, most teams want to know where they stand. The hosted audit lets you [find the AI tools employees use](https://www.shadowaitools.com) 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](https://www.aitoolsblocklist.com) 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](https://www.webfilteringdatabase.com) 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](https://www.cipawebfiltering.com) 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](https://www.phishingdetectionapi.com) 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](https://www.aitoolsblocklist.com), 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](https://www.cipawebfiltering.com).

**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](https://www.webfilteringdatabase.com) and the [website categorization API](https://www.websitecategorizationapi.com), plus the [AI agent allow list](https://www.aiagentallowlist.com), 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](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](https://www.piidetectionapi.com) service scans prompts, chat exports and DLP logs for personal data before it reaches an outside model. Pair a [daily-refreshed AI tool blocklist](https://www.aitoolsblocklist.com) with automated [PII removal](https://www.piidetectionapi.com), 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](https://www.aiagentallowlist.com) 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](https://www.aiagentallowlist.com) covers both directions.

## Related packages

- [`aiblocklist`](https://pypi.org/project/aiblocklist/) on PyPI and [on npm](https://www.npmjs.com/package/aiblocklist), the enforcement-point client for the same API
- [`aitoolsblocklist` on npm](https://www.npmjs.com/package/aitoolsblocklist), the Node.js version of this package
- [`shadowaitools`](https://pypi.org/project/shadowaitools/) on PyPI and [on npm](https://www.npmjs.com/package/shadowaitools), local log scanner for [shadow AI tools](https://www.shadowaitools.com)
- [`aiagentallowlist`](https://pypi.org/project/aiagentallowlist/) on PyPI and [on npm](https://www.npmjs.com/package/aiagentallowlist), client for the AI agent allow list
- [`phishingdetectionapi`](https://pypi.org/project/phishingdetectionapi/) on PyPI and [on npm](https://www.npmjs.com/package/phishingdetectionapi), from [phishingdetectionapi.com](https://www.phishingdetectionapi.com)
- [`webfilteringdatabase`](https://www.npmjs.com/package/webfilteringdatabase) on npm, from [webfilteringdatabase.com](https://www.webfilteringdatabase.com)
- [`websiteclassificationapi`](https://pypi.org/project/websiteclassificationapi/) on PyPI and [`websitecategorization`](https://www.npmjs.com/package/websitecategorization) on npm, from [websitecategorizationapi.com](https://www.websitecategorizationapi.com)
- [`cipawebfiltering`](https://pypi.org/project/cipawebfiltering/) on PyPI and [on npm](https://www.npmjs.com/package/cipawebfiltering), from [cipawebfiltering.com](https://www.cipawebfiltering.com)
- [PII detection API](https://www.piidetectionapi.com)

The Python source is kept in [the explainableaixai GitHub repository](https://github.com/explainableaixai/aitoolsblocklist), and [a GitLab copy](https://gitlab.com/url-classifications/aitoolsblocklist) mirrors it.
