In short: plain HTTPS GET requests, JSON responses, no account needed for light use. The same checks power the website, so results match what you see here.
What it does
Each endpoint takes a hostname in the path and returns the same result as the matching tool page. If you pass a full URL instead, encode it. Paths and query strings are stripped before the check, exactly as on the site. {type} is one of A, AAAA, CNAME, MX, NS or TXT.
| Endpoint | Returns |
|---|---|
GET /v1/report/{host} | All five report checks below in one response |
GET /v1/reachability/{host} | Status code and response time per region, plus the verdict |
GET /v1/redirects/{host} | Every hop, with loop and mixed-protocol flags |
GET /v1/ssl/{host} | Issuer, validity dates, days left, hostnames, chain |
GET /v1/dns/{host} | A, AAAA, CNAME, MX, NS and TXT records |
GET /v1/dns-propagation/{host}/{type} | One record type across public resolvers |
GET /v1/domain-expiry/{host} | Registrar, expiry date and days left |
GET /v1/availability/{host} | Whether the domain has a registration record |
Example: SSL check
Requestcurl "https://api.sitecheckerlab.com/v1/ssl/example.com"Response · 200 OK
{
"check": "ssl",
"host": "example.com",
"checked_at": "2026-11-11T14:32:05Z",
"status": "ok",
"reason": "Valid for 74 more days and covers example.com.",
"data": {
"issuer": "Example Trust CA R1",
"valid_from": "2026-10-26T09:14:00Z",
"valid_to": "2027-01-24T09:14:00Z",
"days_left": 74,
"hostnames": [
"example.com",
"www.example.com"
],
"covers_host": true,
"chain_complete": true,
"chain_length": 3,
"trusted": true,
"error": null
}
}status is always one of ok, warn, error or unknown. Use unknown the way the site uses “Couldn't check”: the check didn't get a clear answer, which is not the same as a failure. reason is the one line the site shows under each result. data is null when nothing usable came back.
Reachability outcomes
Each entry in data.regions of a reachability result has an outcome. Only server_error, refused, tls_failed and no_address count as a clear failure. Timeouts, resets and blocks could be a firewall, so they never count as Down. On their own they lead to “Couldn't check”, and next to a region that answered they lead to a partial result. New values may be added, so treat one you don't know as no clear answer.
| Outcome | Meaning |
|---|---|
up | Answered with a 2xx or 3xx status |
client_error | Answered with a 4xx status. The site is there but may block automated checks |
server_error | Answered with a 5xx status, or the redirects loop, run past 10 or are malformed |
refused | The connection was refused |
tls_failed | The secure connection failed |
no_address | The name doesn't exist or has no address records |
dns_timeout | DNS didn't answer in time for the last hop, so we never reached it |
timeout | No response within 10 seconds |
reset | The connection was reset before any response |
blocked | We stopped ourselves, for example at a redirect to a private address |
Errors
A check that runs and finds a problem with the site is still a 200, with status set to error. HTTP errors are only for the request itself, and they all use the same JSON shape:
{
"error": {
"code": "private_address",
"message": "We only check public websites."
}
}| Code | HTTP | When |
|---|---|---|
invalid_input | 400 | Not a valid hostname or URL, or an unknown record type |
private_address | 422 | Private, internal or reserved address |
port_not_allowed | 422 | A port other than 80 or 443 |
rate_limited | 429 | Too many requests. See the Retry-After header |
busy | 503 | Too many checks running at once. Retry after a few seconds |
upstream_timeout | 504 | A registry or resolver didn't answer in time |
Rate limits
- 60 requests per hour per IP address, no key needed.
- A full report counts as 5 requests.
- At most 20 requests in any one minute.
- Every response includes
RateLimit-RemainingandRateLimit-Resetheaders. A 429 also carriesRetry-After. - Need more? Email hello@sitecheckerlab.com with what you're building.
AI assistants (coming later)
Coming later. This is not available yet, and there is no server to connect to.
We plan to offer the same checks as tools over the Model Context Protocol (MCP), so an AI assistant can run them while it helps you, for example “check whether example.com's certificate expires this month”. They will have the same rate limits and the same refusal of private addresses as the HTTP API. Setup instructions will appear here once it is live.
Privacy and fair use
Hostnames are held in memory for about a minute, for caching and rate limiting, and are never written to disk. Paths and query strings are never stored. Don't use the API to scan networks you don't run or to probe for weaknesses. Addresses that do will be blocked.