API Documentation

REST API for Domain Analyzer Tools — programmatic access to domain, ASN, IP and subnet intelligence

Base URL

https://tools.bd/api/v1
⚠ Current availability: The public REST API is temporarily disabled for external consumers. Requests made from outside Tools.BD currently return 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

Limit20 requests per minute per IP address
Window60 seconds (sliding window — only requests in the last 60s are counted)
Concurrent ScansMaximum 5 simultaneous scans
Search-engine botsExempt (Googlebot, Bingbot, Yandex, …) so they can crawl and index
Rate Limit Response429 Too Many Requests with {"error":true,"message":"Please wait — too many requests. Try again in a few minutes."}

Endpoints

Full Domain Scan

GET
/api/v1/scan/{domain}

Perform a comprehensive DNS and WHOIS analysis for a domain. Returns all sections in a single JSON response.

Parameters

domainRequired. Domain name to scan (e.g., google.com)
?private=1Optional. 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)

GET
/api/v1/scan/{domain}/stream

Same as full scan but returns results as Server-Sent Events (SSE) for real-time updates.

Parameters

domainRequired. Domain name to scan
?private=1Optional. 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

GET
/api/v1/domain/{domain}

Fast RDAP/WHOIS lookup only. Returns registration data without DNS analysis.

Parameters

domainRequired. 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

GET
/api/v1/dns/{domain}

Returns raw DNS records for a domain without the full analysis.

Parameters

domainRequired. 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

GET
/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

domainRequired. 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

GET
/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

queryRequired. 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

GET
/api/v1/asn/{asn}

Look up an Autonomous System Number. Returns registration details, announcing prefixes, routing relationships and RPKI status.

Parameters

asnRequired. 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

GET
/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

ipRequired. 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

GET
/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

prefixRequired. 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

POST
/api/v1/share/{domain}

Generates (or returns existing) share token for a domain. The domain must have been scanned first.

Parameters

domainRequired. Domain name to generate share link for

Response

{
  "share_token": "abc123def456...",
  "share_url": "https://tools.bd/share/abc123def456..."
}

Get Shared Scan

GET
/api/v1/share/{token}

Retrieves a scan by its share token. Returns full scan result.

Parameters

tokenRequired. 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

200Success
400Bad request (invalid domain, missing parameters)
404Not found (invalid share token)
403Public API disabled (external request) — {"error":true,"message":"currently API is off, contact info@tools.bd for more info."}
429Rate limit exceeded (20 requests/minute per IP)
500Internal server error

Response Headers

X-CacheHIT if response served from cache
Content-Typeapplication/json for all endpoints
Cache-Controlno-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: