Release Notes
Changelog
Every customer-facing change to the Intelligence API, newest first. Requests and responses are versionless — there is no version in the URL and no header to pin — so anything that would break an existing integration is called out explicitly rather than shipped quietly.
https://api.securityaccelerated.com v0.74.1
support@securityaccelerated.com
v0.74.0
- Release notes on the docs page now show field and parameter names as inline code instead of printing the backticks around them. 17 public entries were affected, including the BREAKING notes about
lookups,results, andcache_hit
v0.73.0
- Plans are now Free and Pro. The Basic tier is gone; its rate limit, batch size, Stripe price, and payment link have been removed, and the plan tables in the docs, OpenAPI spec, and sales material now show two columns
- The quickstart's example response described a shape the API does not return: the DNS fields are
aandmx, nota_recordsandmx_records, andmxis an array of {host, priority} objects rather than strings. The quickstart is the first thing a new customer copies, so it was the one example most likely to be pasted into a client errorsis omitted from a fully successful response — it is never[]. Six examples showed an empty array and two sentences promised the field was always present; the success examples drop it and the prose now says it appears only when a lookup failed. The OpenAPI spec already had this right- The overview no longer says each result contains exactly the lookups you requested. That reads as a guarantee that n requested lookups produce n fields, and a lookup that fails outright has its field omitted with the reason in
errors. Both documents said so correctly further down; the summary sentence a reader skims first was the one place contradicting them
v0.72.1
- One API machine now stays running at all times. Previously the service stopped after ten idle minutes and the next request paid a cold start; the first call after a quiet period is now as fast as any other
v0.70.0
- Every code block on the docs pages now has a copy button. The reference pages carry 40-plus line payloads, and dragging a selection through one on a phone means fighting the block's own sideways scroll
- The docs pages have a search: press / or Cmd-K (Ctrl-K on Windows) and type a field or section name, arrows to move, Enter to jump. Every result says which lookup it belongs to, which the browser's own find cannot — cache_hit appears on all fourteen lookups, so find walks fourteen identical hits with no way to tell them apart
v0.69.0
- The overview now opens with a working request. Authentication, plans, pricing, rate limiting and error handling all came before the first copy-pasteable call, so the page that should get you started explained the API before it showed it
- /v1/usage and /v1/keys/rotate have a reference page of their own at /docs/account, with parameters, response fields, four-language examples, and the sequence for rotating a key without downtime. They are two of the four public endpoints and were the only two documented by a single table row
- Documented that screenshot captures run under a small service-wide concurrency cap — typically one at a time — and that a capture which does not start before the request deadline reports 'screenshot queue timed out, please retry' in errors. Unlike most lookup errors that one is worth retrying — it means the service was busy, not that the answer is unavailable
- Both reference pages now show what a real upstream failure looks like: a valid target, a 200 response, and the failed lookup's field absent entirely rather than null. Requesting n lookups does not guarantee n fields, and code reaching straight for result.whois.registrar works in testing and throws the first time an upstream has a bad minute
- Documented that repeated key rotation never extends an expiry that is already set, so keys grace-expired by an earlier rotation keep their original deadline and rotation cannot be used to keep an exposed key alive
- The OpenAPI spec carries the same two contracts: the screenshot queue timeout on the screenshot property, and the absent-field behaviour on the errors array
- Documented what the lookup name in an errors entry actually tells you. A plain name (whois) means that lookup failed and its field is absent; a qualified name (threat_intel:virustotal) means one provider inside a fan-out lookup failed while the others answered, and that lookup's field is still present. Treating every errors entry as a missing field throws away good partial results from reputation and threat_intel
v0.68.0
- The documentation now fits a phone. Every page scrolled sideways and ran body text off the screen at any width below roughly 500px, which made the reference unreadable on the device people reach for first
- Reference tables that are too wide for a narrow screen now scroll on their own instead of taking the page with them, and long unbreakable tokens — header names, IPv6 addresses, config keys — wrap instead of painting past the edge
- The page navigation stays available on small screens. It was hidden below 860px, which left the overview — the one page with no sidebar — with no way to reach the rest of the documentation
- Unknown addresses now return a proper 404: a documented page with links to the reference in a browser, and the usual {"error": "not found"} envelope for paths under /v1 and /billing, so a mistyped endpoint is handled by a caller's existing error path
- Documented the tighter domain cap that applies when subdomains is requested — 1 / 3 / 5 rather than 1 / 5 / 20. It has been enforced since v0.44.0 but appeared in no documentation, so the 400 it returns was unpredictable from the docs
- Corrected the caching summary on the overview, which still described IP results as one cached document with a single top-level cache_hit. IP lookups have been cached individually, with per-lookup cache_hit, since v0.60.0
- Added request and response examples for /v1/usage and /v1/keys/rotate on the overview. Both were listed in a table with no example of either side
- Added cache_misses to the UsageSummary schema in the OpenAPI specification, where it was missing from a response the API has been returning
v0.66.0
- Domains with no certificates now return an empty subdomains and ct_logs result instead of an error. crt.sh answers 404 for a name it holds no certificates for, and that was being reported as a lookup failure. A freshly registered typosquat domain usually has no certificates yet, so the domains a customer is most likely to be triaging returned an error instead of the correct answer: none found
- Transient crt.sh failures are retried once before being reported, so a single 404 or 5xx from an unhealthy crt.sh no longer fails the lookup outright
v0.65.0
- Screenshots should start working again on small deployments. Captures were failing with a browser startup timeout, and because a failed lookup returns 200 with the reason in the errors array rather than an HTTP error, the failure was easy to miss entirely
- screenshot.timeout default raised from 15s to 45s. A cold Chromium on a small shared-CPU machine regularly needs longer than 15s just to announce its DevTools endpoint, so captures were failing before the browser had finished starting
v0.64.0
- Release notes have moved to their own page at /docs/changelog, linked from the top nav of every docs page. They previously ran down the bottom of both the overview and the domain reference, which put a list that only grows on two pages people open to look something up
- The full response example is now the last section on both reference pages, immediately before the end, rather than sitting between the field docs and Caching
v0.63.0
- The domain and IP docs pages now show the headers returned with a lookup, not just the JSON body. The full response example gained a Response Headers section covering X-Request-ID, the echoed X-Client-Request-ID, and the rate limit pair
- CORRECTION: the IP docs page said X-Client-Request-ID accepted "any string up to 128 chars". The real limit is 64 characters, restricted to letters, digits, hyphens, underscores, dots, and colons. An ID that fails validation is ignored rather than rejected, so anyone following the old text would have sent a longer ID, received 200, and silently lost their tracing with nothing to explain it. Both pages now state the enforced rule and call out the silent-drop behaviour
- The OpenAPI spec documented no response headers at all and never mentioned X-Client-Request-ID, so generated clients had no idea either existed. Added components.parameters.ClientRequestID and components.headers, wired into every 200 and the shared 429 response across all four documented endpoints
v0.62.0
- Screenshot lookups now honour their configured timeout when the browser is slow to start, instead of overrunning it. On a loaded host a capture could hold a browser slot well past its deadline, delaying other screenshot requests queued behind it
v0.61.0
- Lookups no longer report an upstream failure as an absent record. A threat intelligence provider that could not be reached, a BGP lookup whose queries all failed, an unreadable certificate transparency response, or email security records that could not be resolved are now reported as errors rather than as clean, empty results
- This matters most for threat intelligence: a rate-limited VirusTotal used to return "not detected", which scoring counted at its full 0.50 weight, so a domain nobody checked scored the same as a domain checked and found clean
v0.60.0
- SECURITY: fixed an SSRF weakness in the screenshot lookup. Headless Chrome could reach loopback and link-local addresses directly, so a page that passed the pre-flight safety check could redirect the browser to an internal service or cloud metadata endpoint and have it captured
v0.59.0
- Fixed a bug where the service could lose its database connection after a few minutes of uptime in deployments that address Postgres or Redis by an internal hostname
v0.58.0
- The OpenAPI spec at /docs/openapi.yaml was still describing the pre-v0.54.0 request contract — per-feature booleans instead of the
lookupsarray, a bare array response instead of theresultsenvelope, and a top-levelcache_hit. Anyone generating a client from it would have built requests that fail validation. It now matches the live API - The domain docs page listed
dns_securityas an optional boolean request field alongsidelookups. That row is gone; dns_security is a lookup name, as the Valid Lookups table already showed
v0.57.0
- GeoIP databases now load themselves at startup and persist across restarts.
geoandasnwere unavailable after most restarts because the databases had to be bootstrapped by hand; they are now stored on a volume and downloaded automatically on boot when missing or out of date
v0.56.0
- DNS lookups now fail over correctly. Failover never triggered over UDP, so a lookup could stall on an unresponsive resolver instead of moving to the next one; a resolver that cannot be reached at all is now skipped as well
- The Go code examples on the docs pages declared the same variable twice and did not compile. The JavaScript, Python and Go examples on the IP page were also still on the pre-v0.55.0 request contract
- A target that rejects the TLS handshake is reported as a finding about that target rather than as an internal error
v0.55.0
- BREAKING: IP lookups now take the same
lookupsarray as domain lookups. Thethreat_intelboolean is gone; valid names are geo, asn, reverse_dns, abuse_contact and threat_intel - BREAKING: IP responses are wrapped in a
resultsenvelope and the top-levelcache_hitis replaced by a per-lookupcache_hit, matching the domain endpoint - IP results now report the canonicalized
ipplus aninputsarray of the original entries that mapped to it. Addresses that canonicalize to the same value are deduplicated, so 2001:DB8::1 and 2001:db8:0:0:0:0:0:1 return one result - IP lookups are cached individually with their own TTLs — 24h for abuse_contact, 6h for reverse_dns, 30m for threat_intel — so a slow RDAP lookup no longer shortens everything else's cache lifetime
- geo and asn are no longer cached at all. They read a local database with no network call, so recomputing them is faster than a cache round trip; their cache_hit is always false
- Requesting a domain-only lookup name (such as whois) on the IP endpoint now returns 400 rather than being silently ignored
v0.54.0
- BREAKING: domain lookups now require a
lookupsarray naming exactly which lookups to run. The per-feature booleans (screenshot, reputation, email_security, subdomains, ct_logs, bgp, fingerprint, threat_intel) are gone, and whois/dns/ssl/headers are no longer implicit — nothing runs unless you ask for it - BREAKING: lookup responses are now wrapped in a
resultsenvelope instead of a bare JSON array, so every response is a JSON object - BREAKING: the top-level
cache_hitfield is gone. Each lookup object now carries its owncache_hit, since lookups are cached independently - Each result now reports the normalized
domainplus aninputsarray listing the original request entries that mapped to it. Match results bydomain— array position is not part of the contract - Domains that normalize to the same name are deduplicated into a single result. Plan domain limits still count the entries you submit
- Lookup names and domains are trimmed, lowercased, and deduplicated before validation, so
[" SSL ", "ssl"]andExample.COMbehave as expected - Results are now cached per lookup rather than per response, each with its own TTL — 30 minutes for dns/headers/reputation/threat_intel, 4 hours for ssl/email_security, 24 hours for whois/ct_logs/subdomains/bgp, 60 minutes for screenshot. A lookup you fetched yesterday is reusable today regardless of what else you request alongside it
- Requesting headers and fingerprint together now costs a single headers fetch. Fingerprint has no cache entry of its own, so fingerprint rule updates take effect immediately
- New 400 responses for a missing/empty
lookupsarray and for unrecognized lookup names; requesting a lookup outside your plan returns 403 naming that lookup dns_security(DNSSEC + CAA) is now selected like any other lookup rather than via its own flag- BREAKING: the aggregate
riskscore is now opt-in. Add "risk" tolookupsto get it — it still costs no extra network call and scores over whatever else you requested - Domain lookups no longer cache failures. Per-lookup TTLs mean one flaky provider can no longer shorten every other lookup's cache lifetime, and a failing lookup is retried rather than remembered. IP lookups still negative-cache, since they are cached as a single document
v0.53.0
- Improved reliability under load: heavy lookups are now bounded and isolated so one slow or failing lookup can't affect other requests
v0.52.0
- Every domain lookup now includes an aggregate risk score (0–100 with risk level and per-component breakdown) computed from all returned data
- New dns_security option — DNSSEC deployment (DS/DNSKEY, signing algorithms) and CAA records, available on all plans
- email_security now also checks MTA-STS (including the published policy), TLS-RPT, and BIMI
- New GET /v1/usage — view your own request counts, cache hit rate, and feature usage
- New POST /v1/keys/rotate — self-service API key rotation; old keys keep working for a 24h grace window
- Machine-readable OpenAPI 3.1 spec now served at /docs/openapi.yaml
- All responses now include Strict-Transport-Security, Referrer-Policy, and Content-Security-Policy headers
- Failed lookups are now retried sooner: error responses cache for a short negative TTL instead of the full cache window
v0.51.0
- Subdomain enumeration is now subject to a tighter per-plan domain cap (subdomain.max_domains.*). The config keys and defaults shipped earlier; this is the missing enforcement
v0.50.1
- Domain normalization now strips any URL scheme (ftp, ssh, etc.), not just http/https
v0.50.0
- Domain inputs with paths, ports, query strings, and fragments are now normalized instead of rejected
v0.44.0
- DNS lookups now use external resolvers (Google, Cloudflare, OpenDNS) with automatic fallback
v0.41.0
- New endpoint: POST /v1/ip/lookup — GeoIP, ASN, reverse DNS, abuse contact, and threat intelligence for IP addresses
- IP threat intelligence requires a pro plan (same as domain threat_intel)
- GeoIP and ASN data powered by MaxMind GeoLite2 databases (loaded from disk, refreshable via admin endpoint)
v0.40.0
- Domain input validation now rejects ports, paths, query strings, fragments, and userinfo
v0.38.0
- Partial lookup failures now include error_count in the response for better client-side observability
v0.36.0
- VirusTotal provider is now best-effort when rate-limited instead of failing the whole lookup
- Added threat intelligence section to API docs
v0.34.0
- Added Stripe billing integration with webhook handling and API key provisioning
- New /billing/success page for post-checkout key retrieval
- Customer Portal link for subscription management
v0.33.0
- Added threat intelligence lookups — VirusTotal, URLhaus, and AlienVault OTX with weighted scoring
- Threat intel available for pro and admin plans via threat_intel option
v0.32.0
- Added BGP/ASN lookups with origin AS, prefix, and RIR information
- BGP data available for all plans via bgp option
v0.31.0
- Added certificate transparency log lookups via crt.sh
- CT log data available for all plans via ct_logs option
v0.30.0
- Added technology fingerprinting — detects web servers, frameworks, CDNs, and more from HTTP headers
- ~90 built-in detection rules, hot-reloadable via admin endpoint
v0.19.0
- Added subdomain enumeration via certificate transparency data
- Subdomain results included in domain lookup response via subdomains option
v0.18.0
- Added X-Client-Request-ID header support for client-supplied request correlation
v0.16.0
- Added email security analysis — SPF, DKIM, and DMARC record validation
- Email security available for all plans via email_security option
v0.15.0
- Plan-based limits on domains per request — free: 1, basic: 5, pro: 20
v0.13.0
- Added per-plan rate limiting — free: 5/min, basic: 30/min, pro: 120/min
v0.9.0
- Added domain reputation lookups with multi-provider scoring (Spamhaus, Google Safe Browsing, PhishTank)
- Reputation available for pro and admin plans via reputation option
v0.6.0
- Added page screenshot capture via headless Chrome
- Screenshots available for pro and admin plans via screenshot option
v0.3.0
- Support for multiple domains per request via domains array
v0.1.0
- Initial release — WHOIS, DNS, SSL, and HTTP header lookups with Redis caching
- API key authentication with plan-based access control