REST API reference
12 endpoints, one shape: JSON in, JSON out. Bearer-token auth. Rate-limited per API key. Every response typed via the OpenAPI 3.1 spec at /openapi.json.
Authentication
All authenticated requests carry a Bearer token:
Authorization: Bearer ws_...
Get a key at webscans.com/settings/keys. Public endpoints (search, domain, similar) work without a key at reduced rate limits.
Base URL
https://webscans.com
Errors & rate limits
| Status | Meaning | Response |
|---|---|---|
| 200 | OK | JSON payload |
| 401 / 403 | Invalid or missing key | {"detail": "..."} |
| 402 | Insufficient credits (paid tier) | Header: X-Credits-Needed |
| 404 | Domain not in index & couldn't fetch live | {"detail": "..."} |
| 429 | Rate limit exceeded | Header: Retry-After |
| 503 | Backend saturated — retry | Header: Retry-After: 3 |
| 5xx | Server error — safe to retry with backoff | — |
Rate limits: 30 req/min (free), 300 req/min (pro), 3,000 req/min (enterprise). Search-result row caps: 100 / 10,000 / 1,000,000 respectively.
OpenAPI spec
Full machine-readable spec: GET /openapi.json. Swagger UI: /docs. Import into Postman / Insomnia / your codegen tool of choice.
GET /search
| Param | Type | Notes |
|---|---|---|
q | string, required | Keyword or phrase |
mode | phrase|any|single | Default phrase |
tech | string | e.g. HubSpot, Shopify, React |
industry | string | e.g. Financial Services |
country | ISO-2 | US, GB, DE, ... |
tld | string | Without dot: com, io, ai |
has | email|phone|pricing|blog|ecommerce|contact | Feature filter |
limit | int | 1–500, default 100 |
offset | int | Pagination |
curl "https://webscans.com/search?q=solar%20panels&tech=HubSpot&country=US&limit=25" \
-H "Authorization: Bearer ws_..."from webscans import WebScans
ws = WebScans(api_key="ws_...")
r = ws.search("solar panels", tech="HubSpot", country="US", limit=25)
for hit in r.results:
print(hit.domain, hit.industry)const res = await fetch(
"https://webscans.com/search?q=solar+panels&tech=HubSpot&country=US&limit=25",
{ headers: { Authorization: "Bearer ws_..." }},
);
const { results } = await res.json();GET /search/count
curl "https://webscans.com/search/count?q=hubspot"
# → {"query":"hubspot","total_results":19433}
GET /autocomplete
?mode=domain returns only domain-name suggestions.GET /domain/{d}
/lookup or /enrich to fetch live.curl https://webscans.com/domain/stripe.com | jq '.industry, .tech_stack'
# "Finance & Banking"
# "Next.js, Schema.org, ContactPoint Schema, ..."
GET /domain/{d}/competitors
curl "https://webscans.com/domain/figma.com/competitors?limit=10"
# {
# "domain": "figma.com",
# "method": "faiss_embedding",
# "total_found": 10,
# "competitors": [
# {"domain": "linear.app", "score": 0.799, "match_type": "lookalike", ...},
# {"domain": "composio.dev", "score": 0.792, "match_type": "lookalike", ...},
# ...
# ]
# }
GET /lookup/{d}
curl_cffi → Playwright). Older two-stage cascade; use /enrich for the new race-based version with CC-WET.GET /enrich/{d}
curl_cffi + Common Crawl WARC (first byte wins) → Playwright browser → Bright Data residential proxy. Sub-1s p95 target.curl "https://webscans.com/enrich/anthropic.com?wait_ms=800"
# {
# "domain": "anthropic.com",
# "source": "cached", // cached | live_curl | cc_wet | playwright | brightdata | none
# "elapsed_ms": 8,
# "fetch_ms": 0,
# "cache_age_days": 42,
# "enriched_columns": 131,
# "profile": { ... 178 fields ... }
# }
Params: wait_ms (100–15000, default 800) caps the race budget. force=true bypasses cache. allow_playwright / allow_brightdata disable those tiers if you want budget-safe.
GET /search/download
Free tier: 100 rows. Pro: 10K. Enterprise: 1M.
GET /bulk-search/download
POST /bulk-lookup
curl -X POST https://webscans.com/bulk-lookup \
-H "Authorization: Bearer ws_..." \
-F "file=@my_domains.csv" \
-o enriched.csv
GET /my-companies/export
POST /copilot/query
curl -X POST https://webscans.com/copilot/query \
-H "Content-Type: application/json" \
-d '{"message":"find SaaS companies in California using HubSpot"}'
# {
# "answer": "Here are 8 SaaS companies ...",
# "tool_call": {"name":"search_companies","args":{...}},
# "results": {...},
# "elapsed_ms": 4520,
# "model": "claude-sonnet-4-6"
# }