Security Accelerated

Documentation

Domain Intelligence

Concurrent WHOIS, DNS, SSL, HTTP header, screenshot, reputation, email security, subdomain, certificate transparency, BGP/ASN, technology fingerprinting, and threat intelligence lookups for any domain.

https://api.securityaccelerated.com v0.51.0
support@securityaccelerated.com

Authentication

All requests require an API key passed via the X-API-Key header:

X-API-Key: your-api-key-here
ScenarioResponse
Missing API key401 Unauthorized
Invalid API key401 Unauthorized
Feature not included in plan403 Forbidden

Plans

Feature access and limits are determined by your API key's plan.

FreeBasicPro
Rate limit5 req/min30 req/min120 req/min
Max domains per request1520
WHOIS, DNS, SSL, HeadersIncludedIncludedIncluded
Email SecurityIncludedIncludedIncluded
SubdomainsIncludedIncludedIncluded
CT LogsIncludedIncludedIncluded
BGP / ASNIncludedIncludedIncluded
FingerprintIncludedIncludedIncluded
Screenshot----Pro
Reputation----Pro
Threat Intelligence----Pro

Pricing

Get started with a free plan or upgrade for higher limits and premium features.

PlanFeatures
Free 5 req/min, 1 domain/request, core lookups Included with any API key
Basic 30 req/min, 5 domains/request, core lookups + email security, subdomains, CT logs, BGP, fingerprint Subscribe
Pro 120 req/min, 20 domains/request, all lookups including screenshot, reputation, and threat intel Subscribe
After subscribing, your API key will be shown on a one-time confirmation page. Save it immediately -- it cannot be retrieved again.

Already a subscriber? Manage your subscription

Rate Limiting

Requests are rate-limited per API key using a sliding window. Every response includes rate limit headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRequests remaining in the current window
Retry-AfterSeconds until the window resets (only present on 429 responses)

When the limit is exceeded, the API returns 429 Too Many Requests. Wait until the Retry-After period expires before retrying.

Domain Intelligence

POST /v1/domain/lookup

Look up one or more domains concurrently. Returns WHOIS, DNS, SSL, and HTTP header data by default for each domain. Optional flags enable additional lookups. All lookups run concurrently with a 30-second timeout.

Request Body

FieldTypeRequiredDefaultDescription
domains string[] Required -- Domain names to look up. Max count depends on plan (1 / 5 / 20).
screenshot bool Optional false Capture a page screenshot. Pro
reputation bool Optional false Check domain against threat blocklists. Pro
email_security bool Optional false Check SPF, DMARC, and DKIM records.
subdomains bool Optional false Enumerate subdomains via Certificate Transparency logs.
ct_logs bool Optional false Query Certificate Transparency logs for issued certificates.
bgp bool Optional false Look up BGP/ASN information for the domain's IP addresses.
fingerprint bool Optional false Detect web technologies from HTTP response headers.
threat_intel bool Optional false Query threat intelligence feeds (VirusTotal, URLhaus, AlienVault OTX). Pro

Domain Normalization

Domain names are normalized automatically. You can pass bare domains or full URLs with any scheme — the API extracts the hostname by stripping scheme prefixes, userinfo, ports, paths, query strings, and fragments. The result is lowercased. The domain field in the response shows exactly what was looked up. Raw IP addresses are rejected — use the IP Intelligence endpoint instead.

You sendWe look up
example.comexample.com
https://example.com/path?q=1example.com
ftp://example.comexample.com
example.com:8080example.com
user:pass@example.comexample.com
Example.COM/example.com

Example

curl -X POST https://api.securityaccelerated.com/v1/domain/lookup \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: your-api-key' \
  -H 'X-Client-Request-ID: req-001' \
  -d '{
    "domains": ["example.com"],
    "email_security": true,
    "subdomains": true
  }'
import requests

resp = requests.post(
    "https://api.securityaccelerated.com/v1/domain/lookup",
    headers={
        "X-API-Key": "your-api-key",
        "X-Client-Request-ID": "req-001",
    },
    json={
        "domains": ["example.com"],
        "email_security": True,
        "subdomains": True,
    },
)

if resp.status_code != 200:
    print("Error:", resp.json()["error"])
else:
    results = resp.json()
    for result in results:
        print(result["domain"], result["dns"]["a"])
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    body, _ := json.Marshal(map[string]any{
        "domains":        []string{"example.com"},
        "email_security": true,
        "subdomains":     true,
    })

    req, _ := http.NewRequest("POST",
        "https://api.securityaccelerated.com/v1/domain/lookup",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-API-Key", "your-api-key")
    req.Header.Set("X-Client-Request-ID", "req-001")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        var apiErr map[string]string
        json.NewDecoder(resp.Body).Decode(&apiErr)
        fmt.Println("Error:", apiErr["error"])
        return
    }

    var results []map[string]any
    json.NewDecoder(resp.Body).Decode(&results)
    fmt.Println(results[0]["domain"])
}

Response Structure

The response is always a JSON array, even for single-domain requests. Each element contains the core lookup results plus any optional fields that were requested.

[
  {
    "domain": "example.com",
    "cache_hit": false,
    "whois": { ... },
    "dns": { ... },
    "ssl": { ... },
    "headers": { ... },
    "email_security": { ... },
    "subdomains": { ... },
    "threat_intel": { ... },
    "errors": []
  }
]

Optional fields (screenshot, reputation, email_security, subdomains, ct_logs, bgp, fingerprint, threat_intel) are only present in the response when requested.

Invalid Domains

Invalid domains in a multi-domain request do not fail the entire request. They are included in the response with a validation error while valid domains return normally:

[
  {
    "domain": "example.com",
    "cache_hit": false,
    "whois": { "domain_name": "example.com", ... },
    "dns": { ... },
    "ssl": { ... },
    "headers": { ... }
  },
  {
    "domain": "notadomain",
    "errors": [{ "lookup": "validation", "message": "invalid domain name" }]
  }
]

Response Fields

whois -- Domain Registration

FieldTypeDescription
domain_namestringThe registered domain name
registrarstringRegistrar (e.g., GoDaddy, Namecheap)
created_datestringRegistration date -- new domains are higher risk
updated_datestringLast modification date
expiry_datestringExpiration date -- expiring domains are red flags
statusstring[]EPP status codes (e.g., clientTransferProhibited)
name_serversstring[]Authoritative DNS servers
registrantobjectRegistrant contact (name, organization, country, email)
adminobjectAdministrative contact
techobjectTechnical contact
{
  "domain_name": "example.com",
  "registrar": "RESERVED-Internet Assigned Numbers Authority",
  "created_date": "1995-08-14T04:00:00Z",
  "updated_date": "2024-08-14T07:01:38Z",
  "expiry_date": "2025-08-13T04:00:00Z",
  "status": ["clientDeleteProhibited", "clientTransferProhibited"],
  "name_servers": ["a.iana-servers.net", "b.iana-servers.net"],
  "registrant": { "organization": "REDACTED FOR PRIVACY", "country": "US" }
}
Contact fields are often redacted by WHOIS privacy services.

dns -- DNS Records

FieldTypeDescription
astring[]IPv4 addresses
aaaastring[]IPv6 addresses
mxobject[]Mail servers (host, priority)
nsstring[]Name servers
txtstring[]TXT records (SPF, verification tokens, etc.)
cnamestringCanonical name alias
{
  "a": ["93.184.216.34"],
  "aaaa": ["2606:2800:220:1:248:1893:25c8:1946"],
  "mx": [{ "host": "mail.example.com", "priority": 10 }],
  "ns": ["a.iana-servers.net", "b.iana-servers.net"],
  "txt": ["v=spf1 -all"]
}

ssl -- TLS Certificate

FieldTypeDescription
subjectstringEntity the certificate was issued to
issuerstringCertificate authority
not_beforestringStart of validity period
not_afterstringEnd of validity period
expiredboolWhether the certificate has expired
days_until_expiryintDays remaining until expiration
sansstring[]Subject Alternative Names -- all hostnames the cert covers
serial_numberstringCertificate serial number
signature_algorithmstringCryptographic algorithm (e.g., SHA-256)
{
  "subject": "www.example.org",
  "issuer": "DigiCert Global G2 TLS RSA SHA256 2020 CA1",
  "not_before": "2024-01-30T00:00:00Z",
  "not_after": "2025-03-01T23:59:59Z",
  "expired": false,
  "days_until_expiry": 142,
  "sans": ["www.example.org", "example.net", "example.org"],
  "serial_number": "0F:BE:08:B0:85:4D:05:73:8A:B0...",
  "signature_algorithm": "SHA256-RSA"
}

headers -- HTTP Response

FieldTypeDescription
status_codeintHTTP status code (200, 301, 404, etc.)
headersobjectRaw response headers as key-value pairs
security_headersobjectSecurity header audit (see below)

Security Headers Checked

FieldHTTP Header
strict_transport_securityStrict-Transport-Security (HSTS)
content_security_policyContent-Security-Policy (CSP)
x_frame_optionsX-Frame-Options
x_content_type_optionsX-Content-Type-Options
x_xss_protectionX-XSS-Protection
referrer_policyReferrer-Policy
permissions_policyPermissions-Policy
{
  "status_code": 200,
  "headers": {
    "Server": "ECAcc (dcd/7D5A)",
    "Content-Type": "text/html; charset=UTF-8",
    "Cache-Control": "max-age=604800"
  },
  "security_headers": {
    "strict_transport_security": "max-age=31536000",
    "x_content_type_options": "nosniff",
    "x_frame_options": "DENY"
  }
}

screenshot -- Page Screenshot Pro

FieldTypeDescription
status_codeintHTTP status code from probing the domain
pngstringBase64-encoded PNG image (empty for non-200 responses)
{
  "status_code": 200,
  "png": "iVBORw0KGgoAAAANSUhEUgAA..."
}
Tries HTTPS first, then falls back to HTTP. Captured at 1280x720 with headless Chrome.

reputation -- Domain Reputation Pro

FieldTypeDescription
scoreintRisk score from 0 (clean) to 100 (maximum risk)
riskstringclean, low, medium, or high
providersarrayPer-provider results

Provider Result

FieldTypeDescription
listedboolWhether the domain appears on this blocklist
categorystringClassification if listed (e.g., phishing, malware)
providerstringBlocklist name
return_codestringRaw DNS return code (only when listed)
{
  "score": 35,
  "risk": "medium",
  "providers": [
    { "listed": true, "category": "phishing", "provider": "spamhaus_dbl", "return_code": "127.0.1.4" },
    { "listed": false, "provider": "surbl" },
    { "listed": false, "provider": "uribl" },
    { "listed": false, "provider": "spamhaus_zen" }
  ]
}

Providers

The following blocklists are checked: Spamhaus DBL, SURBL, URIBL, and Spamhaus ZEN.

Risk Levels

RiskScore Range
clean0
low1 -- 29
medium30 -- 59
high60 -- 100

email_security -- Email Authentication

spf -- Sender Policy Framework

FieldTypeDescription
rawstringFull SPF TXT record
versionstringSPF version (typically spf1)
mechanismsstring[]Parsed mechanisms (include:, ip4:, etc.)
allstringTerminal qualifier: -all, ~all, ?all, or +all

dmarc -- DMARC Policy

FieldTypeDescription
rawstringFull DMARC TXT record
versionstringDMARC version (typically DMARC1)
policystringnone, quarantine, or reject
pctintPercentage of messages the policy applies to
ruastringAggregate report destination
rufstringForensic report destination
spstringSubdomain policy

dkim -- DKIM Records

FieldTypeDescription
selectorstringSelector name probed
foundboolWhether a DKIM record exists for this selector
rawstringFull DKIM TXT record (only when found)
{
  "spf": {
    "raw": "v=spf1 include:_spf.google.com -all",
    "version": "spf1",
    "mechanisms": ["include:_spf.google.com"],
    "all": "-all"
  },
  "dmarc": {
    "raw": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com",
    "version": "DMARC1",
    "policy": "reject",
    "rua": "mailto:dmarc@example.com"
  },
  "dkim": [
    { "selector": "google", "found": true, "raw": "v=DKIM1; k=rsa; p=MIGf..." },
    { "selector": "default", "found": false }
  ]
}
DKIM probes 8 common selectors: google, default, selector1, selector2, k1, s1, mail, dkim.

subdomains -- Subdomain Enumeration

FieldTypeDescription
countintNumber of subdomains returned
cappedbooltrue if results were truncated at the cap (500)
subdomainsarrayDiscovered subdomains

Subdomain Entry

FieldTypeDescription
domainstringThe subdomain
sourcestringData source (crt.sh)
{
  "count": 3,
  "capped": false,
  "subdomains": [
    { "domain": "www.example.com", "source": "crt.sh" },
    { "domain": "mail.example.com", "source": "crt.sh" },
    { "domain": "api.example.com", "source": "crt.sh" }
  ]
}

ct_logs -- Certificate Transparency Logs

FieldTypeDescription
countintNumber of certificate entries returned
cappedbooltrue if results were truncated at the cap (100)
entriesarrayCertificate log entries, sorted newest-first

CT Log Entry

FieldTypeDescription
logged_atstringWhen the certificate was logged to CT
not_beforestringCertificate validity start
not_afterstringCertificate validity end
issuerstringCertificate Authority
common_namestringCertificate CN field
name_valuestringAll names covered by the certificate
serialstringCertificate serial number
{
  "count": 2,
  "capped": false,
  "entries": [
    {
      "logged_at": "2024-01-15T00:00:00",
      "not_before": "2024-01-15T00:00:00",
      "not_after": "2025-04-15T23:59:59",
      "issuer": "Let's Encrypt",
      "common_name": "example.com",
      "serial": "abc123def456"
    }
  ]
}
Reveals infrastructure, related domains, and issuance patterns. Useful for detecting phishing campaigns and tracking certificate history.

bgp -- BGP / ASN Enrichment

FieldTypeDescription
recordsarrayASN records, deduplicated by ASN

ASN Record

FieldTypeDescription
ipstringResolved IP address
asnintAutonomous System Number
prefixstringIP prefix (CIDR notation)
countrystringCountry code
registrystringRegional Internet Registry (arin, ripe, apnic, etc.)
descriptionstringOrganization name
{
  "records": [
    {
      "ip": "93.184.216.34",
      "asn": 15133,
      "prefix": "93.184.216.0/24",
      "country": "US",
      "registry": "arin",
      "description": "EDGECAST, US"
    }
  ]
}
Identifies who owns the IP behind the domain. Useful for pivot analysis and detecting bulletproof hosting.

fingerprint -- Technology Fingerprinting

Detects web servers, frameworks, CDNs, CMS platforms, and programming languages from HTTP response headers. No extra HTTP requests are made -- detection uses the headers already fetched. Approximately 90 technologies are covered.

FieldTypeDescription
countintNumber of detected technologies
technologiesarrayDetected technologies

Technology Entry

FieldTypeDescription
namestringTechnology name (e.g., Nginx, PHP, Cloudflare)
categorystringCategory (see below)
versionstringVersion extracted from header value (empty if not detectable)
confidencestringWhich signal matched: header or cookie
{
  "count": 2,
  "technologies": [
    { "name": "Nginx", "category": "web-server", "version": "1.25.3", "confidence": "header" },
    { "name": "Cloudflare", "category": "cdn", "version": "", "confidence": "header" }
  ]
}

Categories

web-server, language, framework, cdn, cms, analytics, security, hosting, cache, javascript, other

threat_intel -- Threat Intelligence Pro

Queries external threat intelligence feeds concurrently and returns an aggregated risk assessment. Three providers are queried: VirusTotal (70+ antivirus engines), URLhaus (Abuse.ch malware URL database), and AlienVault OTX (community threat pulses).

FieldTypeDescription
risk_levelstringAggregate risk: none, low, medium, high, or critical
scoreintWeighted aggregate score (0--100)
categoriesstring[]Merged threat categories across all providers
providersarrayPer-provider results (see below)

Provider Result

FieldTypeDescription
providerstringProvider name: virustotal, urlhaus, or alienvault_otx
detectedboolWhether the provider flagged this domain
scoreintProvider-specific score (0--100). Omitted when not detected.
categoriesstring[]Threat categories from this provider. Omitted when not detected.
detailsstringHuman-readable summary (e.g., "3/70 engines detected this domain"). Omitted when not detected.
{
  "risk_level": "medium",
  "score": 45,
  "categories": ["malware"],
  "providers": [
    {
      "provider": "virustotal",
      "detected": true,
      "score": 3,
      "categories": ["malware"],
      "details": "3/70 engines detected this domain"
    },
    {
      "provider": "urlhaus",
      "detected": false
    },
    {
      "provider": "alienvault_otx",
      "detected": true,
      "score": 20,
      "categories": ["malware"],
      "details": "5 threat pulses reference this domain"
    }
  ]
}

Scoring

The aggregate score is a weighted average across providers: VirusTotal (50%), URLhaus (30%), AlienVault OTX (20%). Risk levels map from the aggregate score: 0 = none, 1--20 = low, 21--50 = medium, 51--80 = high, 81--100 = critical.

errors -- Partial Failures

Individual lookups can fail without blocking the rest of the response. Each error contains:

FieldTypeDescription
lookupstringWhich lookup failed (e.g., whois, dns, ssl)
messagestringHuman-readable error description

Full Response Example

A complete response with all optional features enabled (screenshot, reputation, email_security, subdomains, ct_logs, bgp, fingerprint, threat_intel):

[
  {
    "domain": "example.com",
    "cache_hit": false,
    "whois": {
      "domain_name": "example.com",
      "registrar": "RESERVED-Internet Assigned Numbers Authority",
      "created_date": "1995-08-14T04:00:00Z",
      "expiry_date": "2025-08-13T04:00:00Z",
      "name_servers": ["a.iana-servers.net", "b.iana-servers.net"]
    },
    "dns": {
      "a": ["93.184.216.34"],
      "aaaa": ["2606:2800:220:1:248:1893:25c8:1946"],
      "ns": ["a.iana-servers.net", "b.iana-servers.net"],
      "txt": ["v=spf1 -all"]
    },
    "ssl": {
      "subject": "www.example.org",
      "issuer": "DigiCert Global G2 TLS RSA SHA256 2020 CA1",
      "not_after": "2025-03-01T23:59:59Z",
      "expired": false,
      "days_until_expiry": 142,
      "sans": ["www.example.org", "example.net", "example.org"]
    },
    "headers": {
      "status_code": 200,
      "headers": { "Server": "ECAcc (dcd/7D5A)" },
      "security_headers": {
        "strict_transport_security": "max-age=31536000",
        "x_content_type_options": "nosniff"
      }
    },
    "screenshot": {
      "status_code": 200,
      "png": "iVBORw0KGgoAAAANSUhEUgAA..."
    },
    "reputation": {
      "score": 0,
      "risk": "clean",
      "providers": [
        { "listed": false, "provider": "spamhaus_dbl" },
        { "listed": false, "provider": "surbl" },
        { "listed": false, "provider": "uribl" },
        { "listed": false, "provider": "spamhaus_zen" }
      ]
    },
    "email_security": {
      "spf": { "raw": "v=spf1 -all", "version": "spf1", "all": "-all" },
      "dmarc": { "raw": "v=DMARC1; p=reject", "version": "DMARC1", "policy": "reject" },
      "dkim": [{ "selector": "default", "found": false }]
    },
    "subdomains": {
      "count": 2,
      "capped": false,
      "subdomains": [
        { "domain": "www.example.com", "source": "crt.sh" },
        { "domain": "mail.example.com", "source": "crt.sh" }
      ]
    },
    "ct_logs": {
      "count": 1,
      "capped": false,
      "entries": [
        { "logged_at": "2024-01-15T00:00:00", "issuer": "Let's Encrypt", "common_name": "example.com", "serial": "abc123" }
      ]
    },
    "bgp": {
      "records": [
        { "ip": "93.184.216.34", "asn": 15133, "prefix": "93.184.216.0/24", "country": "US", "description": "EDGECAST, US" }
      ]
    },
    "fingerprint": {
      "count": 1,
      "technologies": [
        { "name": "ECAcc", "category": "cdn", "version": "", "confidence": "header" }
      ]
    },
    "threat_intel": {
      "risk_level": "none",
      "score": 0,
      "providers": [
        { "provider": "virustotal", "detected": false },
        { "provider": "urlhaus", "detected": false },
        { "provider": "alienvault_otx", "detected": false }
      ]
    },
    "errors": []
  }
]

Caching

Results are cached for 60 minutes. The cache_hit field on each response indicates whether data was served from cache or fetched live.

Error Handling

StatusMeaning
400 Bad RequestInvalid request body, missing domains field, or invalid domain name
401 UnauthorizedMissing or invalid API key
403 ForbiddenYour plan does not include this endpoint or feature
413 Content Too LargeRequest body exceeds the 1 MB limit
429 Too Many RequestsRate limit exceeded -- check the Retry-After header
500 Internal Server ErrorServer error -- contact support@securityaccelerated.com

Error Response Format

All error responses use this format:

{
  "error": "description of the problem"
}
Partial failures within a domain lookup are different from HTTP error responses. When individual lookups fail (e.g., a WHOIS server is unreachable), the request still returns 200 OK with the successful lookups populated and failures listed in the errors array.

Request Correlation

You can pass an optional X-Client-Request-ID header with your own correlation ID for end-to-end tracing. The API echoes it back in the response headers and includes it in server-side logs.

HeaderDirectionDescription
X-Client-Request-IDRequestYour correlation ID (max 64 chars; alphanumeric, hyphens, underscores, dots, colons)
X-Request-IDResponseServer-generated UUID for every request. Reference this when contacting support.

What's New

v0.51.0

v0.50.1

v0.50.0

v0.44.0

v0.41.0

v0.40.0

v0.38.0

v0.36.0

v0.34.0

v0.33.0

v0.32.0

v0.31.0

v0.30.0

v0.19.0

v0.18.0

v0.16.0

v0.15.0

v0.13.0

v0.9.0

v0.6.0

v0.3.0

v0.1.0