AI Tools Blocklist
Home AI Tools Database Taxonomy Pricing
Solutions
Enterprise IT & CISO Education Firewall Admins Shadow AI Prevention
Integrations
Palo Alto Networks FortiGate Cisco Umbrella pfSense REST API
Download Free Sample
REST API

REST API for AI Domain
Lookups & Feed Integration

Query 16,024+ classified AI domains programmatically. Single lookups under 50ms, bulk queries up to 1,000 per request, and daily delta sync — all via authenticated JSON endpoints.

16,024+AI Domains
<50msLookup Latency
6Endpoints
JSONResponse Format
Request API Key View Pricing
Overview

API Architecture and Base URL

The REST API provides programmatic access to every AI-tool domain identified through our 102-million-domain classification pipeline. Each response returns structured JSON with rich classification data.

Category

Primary + subcategory from 18-category taxonomy

Confidence

0.0–1.0 classification confidence score

Risk Tier

Low, medium, or high risk classification

Data Handling

Cloud-processed, on-device, or hybrid posture

Timestamps

First-seen and last-verified dates per domain

Status

Active or inactive domain tracking

The base URL for all requests is https://api.aitoolsblocklist.com, versioned under /v1/. When v2 ships, v1 continues for at least 12 months.

API Specifications

HTTPS only — plain HTTP rejected with 301
JSON responses with Content-Type: application/json
UTF-8 encoding on all responses
Gzip compression with Accept-Encoding: gzip

The API is designed for machine-to-machine integration — firewall scripts, SOAR playbooks, SIEM pipelines, and security dashboards. For a pre-built file your firewall polls directly, see our External Dynamic List (EDL) guide.

# Base URL and versioning
https://api.aitoolsblocklist.com/v1/

# Available endpoints:
GET  /v1/lookup/{domain}     # Single domain classification
GET  /v1/domains             # Full domain list with filters
GET  /v1/delta               # Changes since a timestamp
POST /v1/bulk-lookup         # Classify up to 1,000 domains
GET  /v1/taxonomy            # Category tree with IDs
GET  /v1/stats               # Database statistics
Authentication

API Key Authentication

Every request requires a valid API key in the Authorization header using the Bearer scheme. Keys are generated in your account dashboard after subscribing to any paid plan.

Key Format & Limits

Bearer token authentication
64-character alphanumeric string
atb_ prefix for easy log identification
Up to 5 active keys per account

Keys are scoped to your subscription plan — upgrading automatically upgrades all active keys. Revoked keys return 401 within 60 seconds.

Key Management Best Practices

Rotate keys every 90 days
Use separate keys per environment
Monitor last-used timestamp and source IP in dashboard
Revoke immediately if key is exposed
# Authentication: pass your API key as a Bearer token
curl -H "Authorization: Bearer atb_your_api_key_here" \
     "https://api.aitoolsblocklist.com/v1/stats"

# Missing or invalid key returns 401:
{
  "error": "unauthorized",
  "message": "Invalid or missing API key. Include a valid key in the Authorization header.",
  "status": 401
}

# Expired or revoked key returns 403:
{
  "error": "forbidden",
  "message": "API key has been revoked. Generate a new key in your dashboard.",
  "status": 403
}
Endpoints

Endpoint Reference

1. Single Domain Lookup — GET /v1/lookup/{domain}

Check whether a domain is in the AI Tools Blocklist and get its full classification. Ideal for real-time workflows — SOAR playbooks, proxy plugins, and custom DNS resolvers.

<50ms at P95 latency
Auto subdomain resolution
Both found/not-found return 200

Pass the bare domain name without protocol or path — e.g. claude.ai, not https://claude.ai/chat. Looking up chat.openai.com returns the classification for openai.com.

# Lookup a single domain
curl -H "Authorization: Bearer atb_your_api_key_here" \
     "https://api.aitoolsblocklist.com/v1/lookup/claude.ai"

# Response (200 OK) — domain is in the blocklist:
{
  "domain": "claude.ai",
  "in_blocklist": true,
  "primary_category": "Text & Language",
  "subcategory": "General assistants & chatbots",
  "confidence": 0.99,
  "risk_tier": "high",
  "data_handling": "cloud-processed",
  "status": "active",
  "first_seen": "2023-07-11T00:00:00Z",
  "last_verified": "2026-07-09T06:00:00Z"
}

# Response (200 OK) — domain is NOT in the blocklist:
{
  "domain": "example.com",
  "in_blocklist": false
}

The in_blocklist boolean tells you whether the domain is classified as an AI tool. Your integration checks one field — no ambiguity between "not found" and "invalid request."

2. Full Domain List — GET /v1/domains

Returns the complete classified domain list with optional filters for category, confidence, risk tier, and status. Use this for initial data loads into a local cache, DNS sinkhole, or firewall EDL.

~15 MB gzip-compressed
Cursor-based pagination
5,000 records per page default
# Full list — first page, default filters
curl -H "Authorization: Bearer atb_your_api_key_here" \
     "https://api.aitoolsblocklist.com/v1/domains"

# With filters — only high-confidence Text & Language domains
curl -H "Authorization: Bearer atb_your_api_key_here" \
     "https://api.aitoolsblocklist.com/v1/domains?category=Text+%26+Language&min_confidence=0.9&status=active"

# Response:
{
  "domains": [
    {
      "domain": "openai.com",
      "primary_category": "Text & Language",
      "subcategory": "General assistants & chatbots",
      "confidence": 0.99,
      "risk_tier": "high",
      "status": "active"
    },
    // ... up to 5,000 records per page
  ],
  "pagination": {
    "cursor": "eyJpZCI6NTAwMH0=",
    "has_more": true,
    "total": 16024
  }
}

Pass the cursor value as a query parameter to get the next page. Cursors expire after 24 hours — adjust page size with limit (min 100, max 10,000).

3. Delta Updates — GET /v1/delta

Returns only domains added, removed, or reclassified since a given timestamp. This is the backbone of any automated sync workflow after your initial full load.

50–500 changes per day
ISO-8601 since parameter
30-day max lookback
# Fetch changes since yesterday
curl -H "Authorization: Bearer atb_your_api_key_here" \
     "https://api.aitoolsblocklist.com/v1/delta?since=2026-07-08T00:00:00Z"

# Response:
{
  "added": [
    {
      "domain": "newaitool.com",
      "primary_category": "Code & Development",
      "confidence": 0.92,
      "risk_tier": "medium"
    },
    {
      "domain": "anotherbot.io",
      "primary_category": "Agents & Automation",
      "confidence": 0.87,
      "risk_tier": "high"
    }
  ],
  "removed": [
    { "domain": "defunct-tool.com", "reason": "domain_inactive" }
  ],
  "reclassified": [
    {
      "domain": "multipurpose-app.com",
      "old_category": "Data & Analytics",
      "new_category": "Agents & Automation",
      "confidence": 0.88
    }
  ],
  "since": "2026-07-08T00:00:00Z",
  "until": "2026-07-09T06:00:00Z",
  "total_changes": 127
}

4. Bulk Lookup — POST /v1/bulk-lookup

Classify up to 1,000 domains in a single request. Ideal for processing firewall logs, DNS query logs, or proxy access logs in batch.

Performance Comparison

Bulk: 1,000 domains in ~500ms (single request)
Sequential: 1,000 domains in ~50 seconds (1,000 requests)
# Bulk lookup — classify multiple domains in one request
curl -X POST \
     -H "Authorization: Bearer atb_your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "domains": [
         "openai.com",
         "claude.ai",
         "example.com",
         "midjourney.com",
         "jasper.ai"
       ]
     }' \
     "https://api.aitoolsblocklist.com/v1/bulk-lookup"

# Response:
{
  "results": [
    { "domain": "openai.com",    "in_blocklist": true,  "primary_category": "Text & Language",   "confidence": 0.99 },
    { "domain": "claude.ai",     "in_blocklist": true,  "primary_category": "Text & Language",   "confidence": 0.99 },
    { "domain": "example.com",   "in_blocklist": false },
    { "domain": "midjourney.com", "in_blocklist": true,  "primary_category": "Image & Visual",    "confidence": 0.99 },
    { "domain": "jasper.ai",     "in_blocklist": true,  "primary_category": "Text & Language",   "confidence": 0.97 }
  ],
  "queried": 5,
  "matched": 4
}

5. Taxonomy — GET /v1/taxonomy

Returns the complete category tree with stable IDs, human-readable names, and subcategories. Cache aggressively — updates happen at most once per quarter.

6. Database Statistics — GET /v1/stats

Returns aggregate database stats: total domains, category breakdown, last update timestamp, 24-hour additions, and 7-day trends. Use it for dashboard widgets and health checks.

# Database statistics
curl -H "Authorization: Bearer atb_your_api_key_here" \
     "https://api.aitoolsblocklist.com/v1/stats"

# Response:
{
  "total_domains": 16024,
  "active_domains": 15684,
  "categories": 18,
  "subcategories": 182,
  "last_updated": "2026-07-09T06:00:00Z",
  "added_last_24h": 87,
  "removed_last_24h": 12,
  "top_categories": [
    { "name": "Text & Language",   "count": 9842 },
    { "name": "Image & Visual",    "count": 7215 },
    { "name": "Code & Development", "count": 5631 }
  ]
}
Rate Limits

Rate Limits and Throttling

Rate limits are enforced per API key and vary by plan. Exceeding your limit returns a 429 Too Many Requests response with retry headers.

Advanced

500

requests / hour

10 bulk lookups/hr
2 full downloads/day

Business

5,000

requests / hour

100 bulk lookups/hr
24 full downloads/day

Enterprise

50,000

requests / hour

Unlimited bulk lookups
Unlimited downloads

Every response includes IETF-standard rate-limit headers so your client can track its budget without a local counter.

# Rate limit headers included in every response
HTTP/1.1 200 OK
X-RateLimit-Limit: 5000          # Your hourly limit
X-RateLimit-Remaining: 4872      # Requests remaining this window
X-RateLimit-Reset: 1752055200     # Unix timestamp when window resets
Retry-After: 0                   # Seconds to wait (0 = you're fine)

# When rate limited (429):
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1752055200
Retry-After: 342                # Wait 342 seconds before retrying

{
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Retry after 342 seconds.",
  "status": 429,
  "retry_after": 342
}

Exponential Backoff Strategy

1

Read the Retry-After header value from the 429 response.

2

Wait the specified number of seconds before retrying.

3

If the retry also returns 429, double the wait time.

4

Cap the maximum backoff at 5 minutes. Tight retry loops can trigger temporary key suspension.

Integration

Integration Examples

Complete, copy-pasteable implementations for the three most common patterns. Each includes authentication, error handling, and rate-limit awareness.

Python — Daily Sync with Delta Updates

Fetches delta updates, applies changes to a local domain set, and persists state. Drop into a SOAR playbook, Airflow DAG, or standalone cron script.

import requests
import json
import time
from datetime import datetime, timedelta

API_KEY = "atb_your_api_key_here"
BASE_URL = "https://api.aitoolsblocklist.com/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

def sync_blocklist(last_sync_file="last_sync.json"):
    # Load last sync state
    try:
        with open(last_sync_file) as f:
            state = json.load(f)
            domains = set(state["domains"])
            since = state["last_sync"]
    except FileNotFoundError:
        # First run — do a full load
        domains = set()
        since = None

    if since is None:
        # Full load with pagination
        cursor = None
        while True:
            params = {"limit": 10000}
            if cursor:
                params["cursor"] = cursor
            resp = requests.get(f"{BASE_URL}/domains",
                               headers=HEADERS, params=params)
            resp.raise_for_status()
            data = resp.json()
            for rec in data["domains"]:
                domains.add(rec["domain"])
            if not data["pagination"]["has_more"]:
                break
            cursor = data["pagination"]["cursor"]
        print(f"Full load complete: {len(domains)} domains")
    else:
        # Delta sync
        resp = requests.get(f"{BASE_URL}/delta",
                            headers=HEADERS,
                            params={"since": since})
        if resp.status_code == 429:
            retry = int(resp.headers.get("Retry-After", 60))
            print(f"Rate limited. Retrying in {retry}s.")
            time.sleep(retry)
            return sync_blocklist(last_sync_file)
        resp.raise_for_status()
        delta = resp.json()
        for rec in delta.get("added", []):
            domains.add(rec["domain"])
        for rec in delta.get("removed", []):
            domains.discard(rec["domain"])
        print(f"Delta sync: +{len(delta.get('added',[]))} "
              f"-{len(delta.get('removed',[]))} = {len(domains)} total")

    # Persist state
    with open(last_sync_file, "w") as f:
        json.dump({
            "domains": sorted(domains),
            "last_sync": datetime.utcnow().isoformat() + "Z"
        }, f)
    return domains

JavaScript / Node.js — Real-Time Domain Check

Checks a domain in real time for proxy middleware, extension backends, or serverless enrichment functions. Returns the classification object or null.

const API_KEY = 'atb_your_api_key_here';
const BASE    = 'https://api.aitoolsblocklist.com/v1';

async function checkDomain(domain) {
  const res = await fetch(
    `${BASE}/lookup/${encodeURIComponent(domain)}`,
    { headers: { 'Authorization': `Bearer ${API_KEY}` } }
  );

  if (res.status === 429) {
    const retry = parseInt(res.headers.get('Retry-After') || '60', 10);
    await new Promise(r => setTimeout(r, retry * 1000));
    return checkDomain(domain);
  }

  if (!res.ok) throw new Error(`API error: ${res.status}`);

  const data = await res.json();
  return data.in_blocklist ? data : null;
}

// Usage
const result = await checkDomain('claude.ai');
if (result) {
  console.log(`Blocked: ${result.domain} — ${result.primary_category}`);
} else {
  console.log('Domain is not an AI tool.');
}

// Bulk check from Node.js
async function bulkCheck(domains) {
  const res = await fetch(`${BASE}/bulk-lookup`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ domains })
  });
  const data = await res.json();
  return data.results.filter(r => r.in_blocklist);
}

Shell — Cron-Based Feed Download for Firewalls

Downloads the full domain list in plain-text format for firewall or DNS resolver consumption. Validates the download before overwriting the live file.

#!/bin/bash
# Daily AI blocklist sync — add to crontab:
# 0 3 * * * /opt/scripts/sync-ai-blocklist.sh

API_KEY="atb_your_api_key_here"
FEED_URL="https://api.aitoolsblocklist.com/v1/domains?format=plain&status=active"
LIVE_FILE="/etc/blocklists/ai-tools-domains.txt"
TEMP_FILE="/tmp/ai-blocklist-download.txt"

# Download to temp file
curl -sf -H "Authorization: Bearer $API_KEY" \
     -o "$TEMP_FILE" "$FEED_URL"

if [ $? -ne 0 ]; then
    echo "[ERROR] Download failed. Keeping existing list."
    exit 1
fi

# Validate: must have at least 10,000 lines
LINE_COUNT=$(wc -l < "$TEMP_FILE")
if [ "$LINE_COUNT" -lt 10000 ]; then
    echo "[ERROR] Only $LINE_COUNT lines — expected 10,000+. Aborting."
    exit 1
fi

# Atomic swap and reload
mv "$TEMP_FILE" "$LIVE_FILE"
echo "[OK] Updated AI blocklist: $LINE_COUNT domains."

# Reload your DNS resolver or firewall
# systemctl reload unbound
# pfctl -t ai_block -T replace -f /etc/blocklists/ai-tools-domains.txt
Error Handling

HTTP Status Codes and Error Responses

Every error response includes a JSON body with error, message, and status fields. Handle each code explicitly — a 429 needs backoff, a 400 needs a request fix.

Success Codes

200Request succeeded. Response body contains data.
204Success, no content (used for key revocation confirmation).

Error Codes

400Bad request — invalid parameter, malformed JSON, or missing required field.
401Unauthorized — missing or invalid API key.
403Forbidden — key revoked, plan expired, or endpoint not included in your plan.
429Rate limit exceeded — wait and retry per Retry-After header.
500Server error — retry after 30 seconds. If persistent, contact support.

Partial Results in Bulk Lookups

If some domains in a bulk request fail validation (e.g. IP addresses or unsupported TLDs), those entries return with an error field while valid domains are classified normally. The HTTP status code is still 200 — check individual result entries for per-domain errors.

Architecture

Common Integration Architectures

Three patterns for different security stacks and operational cadences.

Cache + Daily Delta Sync

Load the full list once into Redis, SQLite, or a flat file. Run a daily cron job with the delta endpoint to stay current. Supports millions of local lookups from a 500 req/hr plan.

Real-Time Inline Lookup

Call the single-domain endpoint from SOAR playbooks, SIEM enrichment, or proxy middleware. Under 50ms latency. Requires Business or Enterprise plan for higher rate limits.

Batch Log Enrichment

Extract unique domains from logs, classify via bulk lookup in batches of 1,000. Feed results into your SIEM for dashboards and alerting. Run hourly, daily, or on-demand.

Pagination

Cursor-Based Pagination

The /v1/domains endpoint uses opaque cursors rather than page offsets. Cursors are stable across dataset changes — no duplicates or gaps within a pagination run.

Default page size: 5,000 records
Adjustable via limit param (100–10,000)
Cursors expire after 24 hours
Each page counts as one API call

Changing a filter parameter invalidates existing cursors — restart from the first page with the new filter.

Best Practices

API Integration Best Practices

Operational practices from production integrations across hundreds of deployments — firewall teams, SOC analysts, and security vendors consuming the API at scale.

1

Cache Locally, Sync Daily

Load the full list into a local cache (Redis, file, or in-memory set) and resolve lookups locally. Refresh via delta once per day — supports millions of lookups from a 500 req/hr plan.

2

Validate Before Swapping

Never overwrite your live blocklist without checking line count and format first. A truncated download can block nothing or block everything.

3

Use Separate Keys per Environment

Generate distinct keys for production, staging, and dev. If a dev key leaks, revoke it instantly without interrupting production sync.

4

Monitor the Stats Endpoint

Add a health check that verifies last_updated is within 48 hours. Alert if stale — it means either our pipeline or your sync script has an issue.

Ready to Integrate the AI Blocklist API?

Request an API key to start querying 16,024+ classified AI domains. All plans include full API access — the difference is rate limits and refresh frequency.

View Plans & Pricing Browse Database

Request API Access

Tell us about your integration — platform, expected query volume, and preferred plan. We will provision API credentials within 24 hours.