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

MethodEndpointPurposeWeb tool
GET/api/v1/healthMinimal API health—
POST/api/v1/http-checkHTTP status, response time and safe headersWebsite Status
POST/api/v1/dnsSelected public DNS recordsDNS Lookup
POST/api/v1/redirectsValidated redirect chainRedirect Checker
POST/api/v1/tlsHTTPS certificate validitySSL Checker
POST/api/v1/security-headersSupported response-header presenceSecurity Headers
POST/api/v1/ipLocal DB-IP City Lite lookupIP Lookup
POST/api/v1/subnetLocal CIDR calculationSubnet Calculator
POST/api/v1/punycodeLocal IDN conversionPunycode 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

CodeMeaning
invalid_json / invalid_json_objectThe body is malformed, not UTF-8 JSON or not an object.
missing_field / unknown_fieldThe object does not contain exactly the documented fields.
unsupported_media_type / request_too_largeThe request is not JSON or exceeds the 4 KiB body limit.
invalid_url / invalid_host / invalid_ipThe submitted target is syntactically invalid for that endpoint.
invalid_cidr / invalid_punycode / invalid_record_typeA local calculation or DNS type is invalid.
non_public_targetThe address or any resolved address is unsuitable for a public-Internet diagnostic.
nxdomain / no_answerDNS reports no domain or no matching record.
redirect_limitThe bounded HTTP redirect limit was exceeded.
timeout / connection_error / tls_validationThe bounded upstream operation did not complete successfully.
rate_limitedThe normalized client IP exceeded the applicable nginx limit.
internal_errorAn 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.