Browse the API reference
Get started
Recipes
Five patterns that cover almost every integration built on this data.
Watch for new hosts every hour
Poll the global discovery feed on a schedule and act on anything first seen since your last run.
# cron: 5 * * * * curl -s "$BASE/subdomains/new?hours=1&limit=2000" \ -H "Authorization: Bearer $CHAOS_TOKEN" \ | jq -r '.data[].host' >> new-hosts.txt
Page through a large discovery window
Cursor pagination never skips or repeats rows, even while new hosts are landing mid-run.
import requests
base = "https://chaos.thescope.top/api/v1"
headers = {"Authorization": f"Bearer {TOKEN}"}
params = {"hours": 24, "limit": 2000}
hosts = []
while True:
r = requests.get(f"{base}/subdomains/new", headers=headers, params=params, timeout=60)
r.raise_for_status()
body = r.json()
hosts += [row["host"] for row in body["data"]]
cursor = body["meta"].get("next_cursor")
if not cursor or not body["data"]:
break
params.update(cursor)
print(len(hosts), "hosts")Fetch one program by name (any platform)
Pass the program name as the program filter on the platform feed to get just that program's subdomains — works on hackerone, bugcrowd, intigriti, yeswehack and self. The name matches any program domain containing the text.
# every tesla.com subdomain tracked on hackerone BASE="https://chaos.thescope.top/api/v1" curl -s "$BASE/platforms/hackerone/subdomains?program=tesla&limit=10000" \ -H "Authorization: Bearer $CHAOS_TOKEN" | jq -r '.data[].host' > tesla.txt # plain host list, one line per host curl -s "$BASE/platforms/bugcrowd/subdomains?program=binance&format=txt" \ -H "Authorization: Bearer $CHAOS_TOKEN" > binance.txt wc -l tesla.txt binance.txt
Collect every subdomain on a platform (all programs)
Walk one platform program by program with the cursor until it returns null. There is no rate limit, so you can run it as fast as your network allows.
# every host tracked on bugcrowd, in one file BASE="https://chaos.thescope.top/api/v1" CURSOR="" : > bugcrowd-all.txt while :; do URL="$BASE/platforms/bugcrowd/subdomains?limit=10000" [ -n "$CURSOR" ] && URL="$URL&cursor=$CURSOR" BODY=$(curl -s "$URL" -H "Authorization: Bearer $CHAOS_TOKEN") echo "$BODY" | jq -r '.data[].host' >> bugcrowd-all.txt CURSOR=$(echo "$BODY" | jq -r '.meta.next_cursor // empty') [ -z "$CURSOR" ] && break done wc -l bugcrowd-all.txt
Export 100k+ hosts for a whole program
The export endpoint streams, so memory stays flat no matter how large the program is.
curl -N "$BASE/export?platform=bugcrowd&scope=all&format=txt" \ -H "Authorization: Bearer $CHAOS_TOKEN" \ -o bugcrowd-hosts.txt
Queue a re-scan and poll for the result
Queueing returns 202 immediately; large domains finish in the background across worker ticks.
curl -s -X POST "$BASE/scans" \
-H "Authorization: Bearer $CHAOS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"domain":"lovable.app"}'
# then poll history for the freshest scan of that domain
curl -s "$BASE/scans?domain=lovable.app&limit=1" \
-H "Authorization: Bearer $CHAOS_TOKEN" | jq '.data[0]'Keep a local mirror in sync
Full snapshot once, then hourly deltas — the cheapest way to stay current.
# 1. one-time snapshot curl -N "$BASE/export?format=csv" -H "Authorization: Bearer $CHAOS_TOKEN" -o all.csv # 2. hourly delta curl -s "$BASE/subdomains/new?hours=1&limit=2000" \ -H "Authorization: Bearer $CHAOS_TOKEN" | jq -r '.data[] | [.host,.domain,.first_seen_at] | @csv' >> all.csv
Set these once
BASE and CHAOS_TOKEN in your shell and each snippet runs as-is.