Base URL
https://tools.bd/api/v1
HTTP 403 with a contact message. All endpoints below are
fully functional and already power Tools.BD; public access will be enabled later for Free and Paid tiers
(API-key based). This page documents how each endpoint works so you can prepare for launch.
Authentication
Currently no authentication is required for internal/website use. For the upcoming public launch, access will use API keys:
- Free tier — API key, limited monthly quota.
- Paid tier — API key, higher quota, priority throughput, SLA.
Exact quotas and pricing will be announced at launch. Contact info@tools.bd for early access.
Rate Limiting
| Limit | 20 requests per minute per IP address |
| Window | 60 seconds (sliding window — only requests in the last 60s are counted) |
| Concurrent Scans | Maximum 5 simultaneous scans |
| Search-engine bots | Exempt (Googlebot, Bingbot, Yandex, …) so they can crawl and index |
| Rate Limit Response | 429 Too Many Requests with {"error":true,"message":"Please wait — too many requests. Try again in a few minutes."} |
Endpoints
Full Domain Scan
/api/v1/scan/{domain}
Perform a comprehensive DNS and WHOIS analysis for a domain. Returns all sections in a single JSON response.
Parameters
| domain | Required. Domain name to scan (e.g., google.com) |
| ?private=1 | Optional. Prevents the scan from being stored in the database |
Response
{
"domain": "example.com",
"scan_id": "example.com-1234567890",
"started_at": "2026-08-09T21:00:00Z",
"completed_at": "2026-08-09T21:00:02Z",
"rdap": { ... },
"dns_records": [ ... ],
"parent_ns": [ ... ],
"auth_ns": [ ... ],
"soa": { ... },
"mx": [ ... ],
"www": [ ... ],
"dnssec": { ... },
"spf": { ... },
"dmarc": { ... },
"caa": [ ... ],
"propagation": [ ... ],
"health": {
"score": 76,
"grade": "C",
"passes": 34,
"warnings": 6,
"failures": 0,
"infos": 6,
"total": 46
}
}
Sections Included
- rdap — Domain registration data (registrar, dates, status)
- dns_records — All DNS records (A, AAAA, NS, MX, SOA, TXT, CAA, DS, DNSKEY, SRV)
- parent_ns — Parent nameserver delegation info
- auth_ns — Authoritative nameserver tests (reachability, auth flag, recursion)
- soa — SOA record analysis
- mx — Mail server analysis
- www — WWW/CNAME analysis
- dnssec — DNSSEC chain validation
- spf — SPF record analysis
- dmarc — DMARC policy analysis
- caa — CAA records
- propagation — DNS propagation across resolvers
- health — Overall health score and grade
Stream Scan (SSE)
/api/v1/scan/{domain}/stream
Same as full scan but returns results as Server-Sent Events (SSE) for real-time updates.
Parameters
| domain | Required. Domain name to scan |
| ?private=1 | Optional. Prevents storage |
SSE Events
event: start
data: {"domain":"example.com","scan_id":"..."}
event: section:rdap
data: { ... RDAP data ... }
event: section:dns_records
data: [ ... DNS records ... ]
event: section:parent_ns
data: [ ... nameserver data ... }
event: section:auth_ns
data: [ ... auth NS tests ... ]
event: section:soa
data: { ... SOA data ... }
event: section:mx
data: [ ... MX data ... }
event: section:www
data: [ ... WWW data ... }
event: section:dnssec
data: { ... DNSSEC data ... }
event: section:security
data: {"spf":{...},"dmarc":{...},"caa":[...]}
event: section:propagation
data: [ ... propagation data ... ]
event: complete:all
data: { ... health score ... }
event: done
data: {"domain":"example.com"}
Domain RDAP / WHOIS
/api/v1/domain/{domain}
Fast RDAP/WHOIS lookup only. Returns registration data without DNS analysis.
Parameters
| domain | Required. Domain name to lookup |
Response
{
"domain": "example.com",
"registry": "Verisign",
"registrar": "Example Registrar Inc.",
"registrar_id": "1234",
"created_date": "1995-08-14T04:00:00Z",
"updated_date": "2023-08-14T04:00:00Z",
"expires_date": "2028-08-13T04:00:00Z",
"status": ["client delete prohibited", "client transfer prohibited"],
"nameservers": ["ns1.example.com", "ns2.example.com"],
"dnssec": "unsigned",
"rdap_server": "https://rdap.verisign.com",
"available": false,
"privacy_guard": false
}
DNS Records
/api/v1/dns/{domain}
Returns raw DNS records for a domain without the full analysis.
Parameters
| domain | Required. Domain name to lookup |
Response
{
"domain": "example.com",
"dns_records": [
{ "type": "A", "name": "example.com", "value": "93.184.216.34", "ttl": 300 },
{ "type": "NS", "name": "example.com", "value": "ns1.example.com", "ttl": 86400 },
{ "type": "MX", "name": "example.com", "value": "mail.example.com", "ttl": 3600 },
{ "type": "TXT", "name": "example.com", "value": "v=spf1 ...", "ttl": 3600 }
]
}
SSL/TLS Certificate Check
/api/v1/tls/{domain}
Checks the TLS certificate presented on port 443 for a domain. Returns certificate details, protocol support (TLS 1.0-1.3), HTTP/HSTS behavior, a security grade (A+ to F) and a list of test results.
Parameters
| domain | Required. Domain name to check (e.g., google.com) |
Response
{
"domain": "example.com",
"reachable": true,
"grade": "A+",
"score": 100,
"cert": {
"subject_cn": "example.com",
"issuer_cn": "Google Trust Services",
"not_after": "2026-11-01T00:00:00Z",
"days_remaining": 66,
"key_type": "ECDSA",
"key_bits": 256
},
"protocols": [ { "version": "TLS 1.3", "supported": true } ],
"http": { "https_status": 200, "hsts_present": true },
"tests": [ { "name": "Valid Certificate", "status": "PASS" } ]
}
DNSBL / RBL Blacklist Check
/api/v1/blacklist/{query}
Checks whether a domain or IP address is listed on major DNS blocklists. For domains, A/AAAA and MX IPs are resolved and checked. Returns per-list verdicts and a listed count.
Parameters
| query | Required. Domain name or IP address (e.g., example.com or 8.8.8.8) |
Response
{
"query": "8.8.8.8",
"input_type": "ip",
"ips": ["8.8.8.8"],
"listed": 0,
"tested": 10,
"results": [
{ "ip": "8.8.8.8", "list": "zen.spamhaus.org", "name": "Spamhaus Zen", "status": "CLEAN" }
]
}
ASN Lookup
/api/v1/asn/{asn}
Look up an Autonomous System Number. Returns registration details, announcing prefixes, routing relationships and RPKI status.
Parameters
| asn | Required. Autonomous System Number with or without the AS prefix (e.g., AS15169 or 15169) |
Response
{
"asn": 15169,
"as_name": "GOOGLE",
"organization": "Google LLC",
"country": "US",
"registry": "ARIN",
"allocated_at": "2000-03-30T00:00:00Z",
"updated_at": "2023-05-15T00:00:00Z",
"asn_type": "CONTENT",
"website": "https://www.google.com",
"ipv4_prefixes": ["8.8.8.0/24", "..."],
"ipv6_prefixes": ["2607:f8b0::/32", "..."],
"ipv4_count": 123456,
"ipv6_count": 7890,
"prefixes": [ ... ],
"peers": [ ... ],
"upstreams": [ ... ],
"downstreams": [ ... ],
"rpki": { "valid": 42, "invalid": 0, "unknown": 3 },
"whois": "AS15169 GOOGLE - Google LLC, US",
"scanned_at": "2026-08-27T10:00:00Z"
}
IP Lookup
/api/v1/ip/{ip}
Look up a single IPv4 or IPv6 address. Returns ASN/ISP ownership, geolocation, network type, PTR, port/risk intelligence and WHOIS.
Parameters
| ip | Required. IPv4 or IPv6 address (e.g., 8.8.8.8) |
Response
{
"ip": "8.8.8.8",
"is_v6": false,
"is_private": false,
"is_reserved": false,
"asn": 15169,
"as_name": "GOOGLE",
"organization": "Google LLC",
"isp": "Google",
"prefix": "8.8.8.0/24",
"netblock": "8.8.8.0/24",
"country": "US",
"registry": "ARIN",
"network_type": "CONTENT",
"hostname": "dns.google",
"ptr": "dns.google",
"latency_ms": 12.3,
"open_ports": [53, 443],
"port_scan_count": 2,
"https_status": 200,
"is_hosting": false,
"is_proxy": false,
"is_tor": false,
"is_vpn": false,
"is_datacenter": true,
"is_residential": false,
"is_mobile": false,
"is_cdn": true,
"risk_score": 5,
"risk_flags": [],
"whois": "NetName: GOGL ..."
}
Subnet / Prefix Lookup
/api/v1/prefix/{prefix}
Look up a CIDR subnet (IPv4 or IPv6). Returns the owning ASN/organization, allocation, geolocation, BGP/RPKI status and WHOIS.
Parameters
| prefix | Required. CIDR notation (e.g., 8.8.8.0/24 or 2607:f8b0::/32) |
Response
{
"prefix": "8.8.8.0/24",
"ip_version": 4,
"ip_count": 256,
"asn": 15169,
"as_name": "GOOGLE",
"organization": "Google LLC",
"country": "US",
"registry": "ARIN",
"allocated_at": "2000-03-30T00:00:00Z",
"bgp_status": "ROUTED",
"whois": "NetRange: 8.8.8.0 - 8.8.8.255 ...",
"source": "rdap"
}
Generate Share Link
/api/v1/share/{domain}
Generates (or returns existing) share token for a domain. The domain must have been scanned first.
Parameters
| domain | Required. Domain name to generate share link for |
Response
{
"share_token": "abc123def456...",
"share_url": "https://tools.bd/share/abc123def456..."
}
Get Shared Scan
/api/v1/share/{token}
Retrieves a scan by its share token. Returns full scan result.
Parameters
| token | Required. Share token (32 character hex string) |
Response
Same as full scan response. Returns 404 if token not found or expired.
Error Responses
All errors follow this format:
{
"error": true,
"message": "Description of the error"
}
HTTP Status Codes
| 200 | Success |
| 400 | Bad request (invalid domain, missing parameters) |
| 404 | Not found (invalid share token) |
| 403 | Public API disabled (external request) — {"error":true,"message":"currently API is off, contact info@tools.bd for more info."} |
| 429 | Rate limit exceeded (20 requests/minute per IP) |
| 500 | Internal server error |
Response Headers
| X-Cache | HIT if response served from cache |
| Content-Type | application/json for all endpoints |
| Cache-Control | no-store for scan results (always fresh) |
Caching
- Scan results — Cached in Redis for 2 minutes. Subsequent requests for the same domain return cached results.
- Shared scans — Cached for 1 hour.
Usage Examples
cURL
# Full domain scan curl https://tools.bd/api/v1/scan/google.com # Domain RDAP / WHOIS only curl https://tools.bd/api/v1/domain/google.com # DNS records only curl https://tools.bd/api/v1/dns/google.com # ASN lookup curl https://tools.bd/api/v1/asn/AS15169 # IP lookup curl https://tools.bd/api/v1/ip/8.8.8.8 # Subnet / prefix lookup curl https://tools.bd/api/v1/prefix/8.8.8.0/24 # Stream scan (SSE) curl -N https://tools.bd/api/v1/scan/google.com/stream # Generate share link curl -X POST https://tools.bd/api/v1/share/google.com # Private scan (not stored) curl "https://tools.bd/api/v1/scan/google.com?private=1"
JavaScript (fetch)
// Full domain scan
const response = await fetch('https://tools.bd/api/v1/scan/google.com');
const data = await response.json();
console.log(data.health.grade); // "C"
// ASN lookup
const asn = await (await fetch('https://tools.bd/api/v1/asn/AS15169')).json();
console.log(asn.organization); // "Google LLC"
// IP lookup
const ip = await (await fetch('https://tools.bd/api/v1/ip/8.8.8.8')).json();
console.log(ip.as_name, ip.country); // "GOOGLE" "US"
// Subnet lookup
const pfx = await (await fetch('https://tools.bd/api/v1/prefix/8.8.8.0/24')).json();
console.log(pfx.asn, pfx.bgp_status); // 15169 "ROUTED"
// Stream scan (SSE)
const eventSource = new EventSource('https://tools.bd/api/v1/scan/google.com/stream');
eventSource.addEventListener('section:rdap', (e) => {
const rdap = JSON.parse(e.data);
console.log('RDAP:', rdap);
});
eventSource.addEventListener('complete:all', (e) => {
const health = JSON.parse(e.data);
console.log('Grade:', health.grade);
eventSource.close();
});
Python
import requests
# Full domain scan
data = requests.get('https://tools.bd/api/v1/scan/google.com').json()
print(f"Grade: {data['health']['grade']}")
# ASN
asn = requests.get('https://tools.bd/api/v1/asn/AS15169').json()
print(asn['organization'], asn['country'])
# IP
ip = requests.get('https://tools.bd/api/v1/ip/8.8.8.8').json()
print(ip['as_name'], ip['is_datacenter'])
# Subnet
pfx = requests.get('https://tools.bd/api/v1/prefix/8.8.8.0/24').json()
print(pfx['asn'], pfx['ip_count'])
# Stream scan
import sseclient
r = requests.get('https://tools.bd/api/v1/scan/google.com/stream', stream=True)
for event in sseclient.SSEClient(r):
print(f"{event.event}: {event.data[:50]}...")
Data Retention
- Public scans are stored for 30 days
- Private scans (
?private=1) are not stored - Share tokens are valid for 30 days
- Expired data is automatically cleaned up
Contact
For API questions, early-access or pricing: