Every live tool is a JSON endpoint under https://api.ferrlens.com. Send a POST with a JSON body, get JSON back. No authentication: anonymous requests share a per-IP budget, see Rate limits.

curl -X POST https://api.ferrlens.com/v1/dns/lookup \
  -H 'content-type: application/json' \
  -d '{"domain":"example.com"}'

Errors

A failed request returns a non-2xx status and a body with a stable code:

{ "code": "INVALID_STRATEGY", "message": "strategy must be 'mobile' or 'desktop'" }

Branch on code, not on message. A 429 carries RATE_LIMITED and a Retry-After header.

URLs you submit must be public. Addresses that resolve to private or internal ranges are rejected.

DNS

Endpoint Request Response
POST /v1/dns/lookup domain domain, records (kind, records[]), total
POST /v1/dns/propagation domain, kind (default A) domain, kind, distinct_answers, hits[]
POST /v1/dns/reverse ip ip, hostnames[]

kind for propagation is one of A, AAAA, MX, TXT, NS, CNAME, SOA. Each entry of hits is one public resolver: resolver, resolver_label, resolver_ip, timings_ms, records, error. When distinct_answers has a single entry, every resolver agrees.

Email

Endpoint Request Response
POST /v1/email/spf-dmarc domain spf, dmarc, dkim_selectors[], score, notes[]
POST /v1/email/blacklist target (domain or IP) target, resolved_ip, checked, listed, errored, entries[]
POST /v1/email/verify email syntax_valid, local_part, domain, disposable, role_based, mx[], has_mx

SEO and web

Endpoint Request Response
POST /v1/seo/check url, strategy (mobile default, or desktop) url, fetched_at, scores, core_web_vitals, notes[], findings[]
POST /v1/seo/check/stream same as above server-sent events
POST /v1/seo/robots domain, user_agent, test_path url, status, raw, groups[], sitemaps[], matched_agent, test_result
POST /v1/seo/sitemap url url, status, is_index, url_count, sample[], children[], warnings[]
POST /v1/web/meta url url, final_url, title, entries[], counts
POST /v1/web/og-preview url url, final_url, card, warnings[]
POST /v1/web/mixed-content url url, final_url, is_https, mixed[], total
POST /v1/web/cors url, origin, method (default GET) preflight, actual, checks[]
POST /v1/web/ct-search domain domain, total, unique_sans, certificates[]
POST /v1/http/headers url url, final_url, status, headers, timings_ms, redirects[]
POST /v1/http/sec-headers url url, final_url, status, total_score, grade, checks[]

scores holds performance, seo, accessibility and best_practices, each a number or null. SEO results are cached for 24 hours per URL and strategy.

The stream variant sends accepted first, then vitals, scores and notes as they become available, and ends with done or error. A cached result arrives as one cached event followed by done.

POST /v1/link-check crawls a site from url and reports the status of every link it finds.

Field Default Limits
url required
max_depth 2 clamped to 1 to 3
max_pages 200 clamped to 10 to 500

The crawl respects robots.txt, waits between requests, and stops after 60 seconds. The response lists the crawled pages and a summary with total, broken, redirects, ok, external, blocked_by_robots, blocked and unreachable.

Shares

POST /v1/shares, GET /v1/shares/{id} and DELETE /v1/shares/{id} are covered in Share links.