Public beta
Developer API
WhatWebSees provides lightweight HTTP APIs for website, DNS, TLS and network diagnostics. Use them from curl, shell scripts, CI, automation tools and server-side applications.
Quick start
No authentication is required during the public beta. Send JSON to a versioned endpoint and inspect the stable ok/data envelope:
curl -sS https://whatwebsees.com/api/v1/http-check \
-H 'Content-Type: application/json' \
--data '{"url":"https://example.com"}'
{
"ok": true,
"data": {
"url": "https://example.com/",
"status_code": 200,
"http_response_time_ms": 123,
"final_url": "https://example.com/",
"redirect_count": 0,
"headers": {"Content-Type": "text/html"}
}
}
Python
import json
from urllib.request import Request, urlopen
body = json.dumps({"domain": "example.com", "type": "A"}).encode()
request = Request("https://whatwebsees.com/api/v1/dns", body,
{"Content-Type": "application/json"}, method="POST")
with urlopen(request, timeout=15) as response:
print(json.load(response))
Node.js server runtime
const response = await fetch("https://whatwebsees.com/api/v1/tls", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({hostname: "example.com"}),
});
console.log(await response.json());
The API does not enable cross-origin browser access. These examples target command-line and server runtimes, not JavaScript running on unrelated websites.
Available endpoints
| Method | Endpoint | Purpose | Web tool |
|---|---|---|---|
| GET | /api/v1/health | Minimal API health | — |
| POST | /api/v1/http-check | HTTP status, response time and safe headers | Website Status |
| POST | /api/v1/dns | Selected public DNS records | DNS Lookup |
| POST | /api/v1/redirects | Validated redirect chain | Redirect Checker |
| POST | /api/v1/tls | HTTPS certificate validity | SSL Checker |
| POST | /api/v1/security-headers | Supported response-header presence | Security Headers |
| POST | /api/v1/ip | Local DB-IP City Lite lookup | IP Lookup |
| POST | /api/v1/subnet | Local CIDR calculation | Subnet Calculator |
| POST | /api/v1/punycode | Local IDN conversion | Punycode Converter |
API reference
The responses below illustrate the documented shape. Live DNS answers, timing, headers, certificate dates and location fields vary by target and time.
GET /api/v1/health — Health
Returns only public API availability and version. It does not reveal process, database, server or container details.
Request: no body.
curl -sS https://whatwebsees.com/api/v1/health
{"ok":true,"data":{"status":"ok","api_version":"v1"}}
POST /api/v1/http-check — HTTP Check
Checks a public HTTP or HTTPS URL through the same SSRF-safe connection layer as Website Status. Timing is server-side HTTP response time, not ICMP ping or full page-load time. Only an explicit safe response-header allowlist is returned.
{"url":"https://example.com"}
curl -sS https://whatwebsees.com/api/v1/http-check -H 'Content-Type: application/json' --data '{"url":"https://example.com"}'
{"ok":true,"data":{"url":"https://example.com/","status_code":200,"http_response_time_ms":123,"final_url":"https://example.com/","redirect_count":0,"headers":{"Content-Type":"text/html"}}}
POST /api/v1/dns — DNS Lookup
Queries one of A, AAAA, CNAME, MX, TXT or NS. Results are typed objects rather than presentation HTML.
{"domain":"example.com","type":"A"}
curl -sS https://whatwebsees.com/api/v1/dns -H 'Content-Type: application/json' --data '{"domain":"example.com","type":"A"}'
{"ok":true,"data":{"domain":"example.com","type":"A","ttl":300,"records":[{"address":"93.184.216.34"}]}}
POST /api/v1/redirects — Redirect Checker
Returns the bounded redirect path. Every destination is resolved and validated again before a connection is made.
{"url":"http://example.com"}
curl -sS https://whatwebsees.com/api/v1/redirects -H 'Content-Type: application/json' --data '{"url":"http://example.com"}'
{"ok":true,"data":{"initial_url":"http://example.com/","final_url":"https://example.com/","redirect_count":1,"hops":[{"url":"http://example.com/","status_code":301,"location":"https://example.com/","http_response_time_ms":42},{"url":"https://example.com/","status_code":200,"location":null,"http_response_time_ms":65}]}}
POST /api/v1/tls — TLS Certificate
Validates a public hostname over HTTPS on port 443. Arbitrary ports are not accepted in v1.
{"hostname":"example.com"}
curl -sS https://whatwebsees.com/api/v1/tls -H 'Content-Type: application/json' --data '{"hostname":"example.com"}'
{"ok":true,"data":{"hostname":"example.com","certificate_valid":true,"hostname_match":true,"valid_from":"2026-01-01T00:00:00+00:00","valid_until":"2026-04-01T23:59:59+00:00","days_remaining":30,"issuer":"Example CA"}}
POST /api/v1/security-headers — Security Headers
Reports whether supported browser security headers were observed. A missing header is not, by itself, confirmation of a vulnerability. Cookies are never returned.
{"url":"https://example.com"}
curl -sS https://whatwebsees.com/api/v1/security-headers -H 'Content-Type: application/json' --data '{"url":"https://example.com"}'
{"ok":true,"data":{"url":"https://example.com/","final_url":"https://example.com/","status_code":200,"headers":{"Strict-Transport-Security":{"present":true,"value":"max-age=31536000"},"Content-Security-Policy":{"present":false,"value":null},"X-Content-Type-Options":{"present":true,"value":"nosniff"},"Referrer-Policy":{"present":false,"value":null},"Permissions-Policy":{"present":false,"value":null},"Cross-Origin-Opener-Policy":{"present":false,"value":null},"Cross-Origin-Embedder-Policy":{"present":false,"value":null},"Cross-Origin-Resource-Policy":{"present":false,"value":null}},"note":"A missing header is an observation, not confirmation of a vulnerability."}}
POST /api/v1/ip — IP Lookup
Accepts only globally routable addresses and reads WhatWebSees’ local DB-IP City Lite database. Geographic fields are approximate and returned only when present; the dataset does not supply this API with ISP, ASN, organization, postal-code or time-zone fields.
{"ip":"8.8.8.8"}
curl -sS https://whatwebsees.com/api/v1/ip -H 'Content-Type: application/json' --data '{"ip":"8.8.8.8"}'
{"ok":true,"data":{"ip":"8.8.8.8","ip_version":4,"country_code":"US","country":"United States","data_source":"DB-IP City Lite"}}
IP geolocation by DB-IP. Location is a database estimate, not a street address, person or GPS position.
POST /api/v1/subnet — Subnet Calculator
Calculates boundaries locally. Even very large IPv6 networks are represented by their bounds and address count; hosts are never enumerated.
{"cidr":"192.0.2.0/24"}
curl -sS https://whatwebsees.com/api/v1/subnet -H 'Content-Type: application/json' --data '{"cidr":"192.0.2.0/24"}'
{"ok":true,"data":{"input_address":"192.0.2.0","network":"192.0.2.0","prefix":24,"netmask":"255.255.255.0","total":256,"first":"192.0.2.0","last":"192.0.2.255","version":4,"broadcast":"192.0.2.255","usable":254,"first_usable":"192.0.2.1","last_usable":"192.0.2.254","host_note":"Traditional IPv4 host count excludes the network and broadcast addresses."}}
POST /api/v1/punycode — Punycode
Converts a domain locally between Unicode and ASCII IDNA forms. It does not query DNS or confirm registration.
{"value":"münchen.example"}
curl -sS https://whatwebsees.com/api/v1/punycode -H 'Content-Type: application/json' --data '{"value":"münchen.example"}'
{"ok":true,"data":{"unicode":"münchen.example","ascii":"xn--mnchen-3ya.example"}}
HTTP latency and speed measurement
Internet speed must be measured by the client that transfers the bytes. The JSON API does not pretend to determine a remote caller’s connection speed.
HTTP latency to the WhatWebSees Cloudflare edge
curl -o /dev/null -sS \
-w 'HTTP latency: %{time_total}s\n' \
https://whatwebsees.com/speed-test/ping/
This is HTTP request latency measured by curl, including the relevant connection work. It is not ICMP ping.
Download throughput
Choose a bounded payload that is large enough for the connection:
curl -o /dev/null -sS \
-w 'bytes=%{size_download} seconds=%{time_total} bytes_per_second=%{speed_download}\n' \
https://whatwebsees.com/speed-test/download/payload-16m.bin
This measures throughput between the machine executing the request and the WhatWebSees Cloudflare edge. It does not measure a third-party server and is not an ISP-certified line-speed result.
Upload throughput
head -c 1048576 /dev/urandom | curl -o /dev/null -sS \
-H 'Content-Type: application/octet-stream' --data-binary @- \
-w 'bytes=%{size_upload} seconds=%{time_total} bytes_per_second=%{speed_upload}\n' \
https://whatwebsees.com/speed-test/upload/
The Worker counts and discards the request body. Its existing 16 MiB maximum remains in force. The endpoint is not made cross-origin embeddable, and callers should repeat measurements rather than treating one short transfer as definitive.
Common responses and errors
Successful calls return {"ok":true,"data":{...}}. Failures return a stable error object:
{
"ok": false,
"error": {
"code": "invalid_url",
"message": "Human-readable explanation."
}
}
Clients should branch on the machine-readable code, while treating the message as explanatory text. Common categories include malformed or non-object JSON, unknown or missing fields, invalid targets, non-public targets, unsupported record types, timeouts and upstream connection failures. Wrong methods return HTTP 405 with an Allow header.
Error codes
| Code | Meaning |
|---|---|
invalid_json / invalid_json_object | The body is malformed, not UTF-8 JSON or not an object. |
missing_field / unknown_field | The object does not contain exactly the documented fields. |
unsupported_media_type / request_too_large | The request is not JSON or exceeds the 4 KiB body limit. |
invalid_url / invalid_host / invalid_ip | The submitted target is syntactically invalid for that endpoint. |
invalid_cidr / invalid_punycode / invalid_record_type | A local calculation or DNS type is invalid. |
non_public_target | The address or any resolved address is unsuitable for a public-Internet diagnostic. |
nxdomain / no_answer | DNS reports no domain or no matching record. |
redirect_limit | The bounded HTTP redirect limit was exceeded. |
timeout / connection_error / tls_validation | The bounded upstream operation did not complete successfully. |
rate_limited | The normalized client IP exceeded the applicable nginx limit. |
internal_error | An unexpected failure was hidden behind a generic safe message. |
Rate limits
Network and outbound endpoints are limited to 30 requests per minute per normalized client IP with a small burst. Local subnet and Punycode calculations allow 120 requests per minute with a bounded burst. Health has a separate modest limit. A limit response uses HTTP 429. Public-beta limits can change as operating data becomes available; the service is not unlimited and does not publish guessed “remaining” values.
Authentication
No authentication is required during the public beta. There are no accounts or API keys in v1, and no service-level agreement. The API is intended for light diagnostic use.
Security model
Outbound URL checks accept public HTTP or HTTPS targets on standard ports only. Credentials are rejected. Each hostname is resolved once, all returned addresses must be globally routable, the connection is pinned to a validated numeric address while retaining the original Host and TLS identity, and every redirect repeats the complete validation. Redirects, bodies and network time are bounded.
Requests must be small JSON objects with exactly the documented fields. Responses expose an explicit header allowlist and never return Set-Cookie, authorization values, internal proxy headers, stack traces, filesystem paths or infrastructure details.
Privacy
Subnet and Punycode calls are local computations. IP lookup uses a local DB-IP dataset rather than sending the address to a third-party geolocation service. Network diagnostics necessarily send the requested target to WhatWebSees and contact that public target from the service. API responses are non-cacheable and carry X-Robots-Tag: noindex, nofollow. Normal delivery and security infrastructure can still process request metadata.
Source code
Review the implementation or report an issue in the WhatWebSees source code on GitHub.