API guide
Ask our checker from your own code.
An API is a way for programs to ask our checker directly, without opening the website. Your script sends a website name and gets back the same answer you see on this site, as data your code can read (JSON).
- Base address
https://checkwebsitenow.com- Key or account
- None needed
- Format
- JSON over HTTPS
- Price
- Free, with fair-use limits
Your first request: is a website responding?
Send one public domain, such as example.com. Paths, sign-in details, IP addresses and custom ports are refused. Pick your language; the choice applies to every example on this page.
/api/v1/checkBody: {"hostname":"example.com"}curl -s https://checkwebsitenow.com/api/v1/check \
-H "Content-Type: application/json" \
-d '{"hostname":"example.com"}'import json
import urllib.request
request = urllib.request.Request(
"https://checkwebsitenow.com/api/v1/check",
data=json.dumps({"hostname": "example.com"}).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
with urllib.request.urlopen(request, timeout=20) as response:
result = json.load(response)
print(result["status"], result["final_url"])
import requests
response = requests.post(
"https://checkwebsitenow.com/api/v1/check",
json={"hostname": "example.com"},
timeout=20,
)
response.raise_for_status()
result = response.json()
print(result["status"], result["final_url"])const response = await fetch("https://checkwebsitenow.com/api/v1/check", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ hostname: "example.com" }),
});
const result = await response.json();
if (!response.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
console.log(result.status, result.final_url);Call the API from a script or a server. A web page on another domain cannot call it from the visitor’s browser: those requests carry a foreign origin and are refused with 403 ORIGIN_NOT_ALLOWED.
Reading the answer
A real answer for example.com from a local test run on 6 October 2026, shortened where you see “…”:
{
"schema_version": "1.1",
"target": "example.com",
"status": "reachable",
"http_status": 200,
"checked_at": "2026-10-06T20:16:14.535382+00:00",
"duration_ms": 71,
"method": "HEAD",
"measurement_region": "…",
"cached": false,
"final_url": "https://example.com/",
"redirect_count": 0,
"redirect_chain": [],
"redirect_stop_reason": null,
"limitations": ["…"],
"evidence": {"dns_addresses": ["…"], "transport_reachable": true, "requests": ["…"], "get_fallback_used": false},
"diagnosis": {
"primary": {
"slug": "result-responding",
"title": "Result: The website is responding",
"display_title": "If it still fails for you",
"summary": "The website answered our check successfully.",
"visitor_steps": [{"title": "Try a private window", "detail": "…"}],
"owner_steps": [{"title": "Test the full user journey", "detail": "…"}],
"url": "/errors/result-responding"
},
"related": ["err-name-not-resolved", "err-connection-refused", "err-blocked-by-client"]
},
"diagnosis_schema": "1.1"
}The fields you will use most
| Field | What it tells you |
|---|---|
| status | The plain verdict. See the table below. |
| http_status | The server’s response code for the last tested address, for example 200. null when no response arrived. |
| final_url | The address we finally tested after following safe redirects. |
| redirect_count | How many redirects we followed (at most five). redirect_chain lists each step. |
| redirect_stop_reason | Why we stopped following redirects, for example redirect_loop or unsafe_address. null when nothing stopped us. |
| duration_ms | How long our check took, in milliseconds. This is not the page-load speed a visitor sees. |
| cached | true when a result from the last 60 seconds was reused instead of measuring again. |
| checked_at | When we measured, in UTC (ISO 8601). |
| limitations | What this result cannot prove. Show these to people who rely on the answer. |
| diagnosis.primary | The best matching fix guide: summary, steps for visitors (visitor_steps) and for site owners (owner_steps), and a link (url). Can be null. |
| diagnosis.related | Up to five related error guides, as short names (slugs) for /api/v1/errors/{slug}. |
Status values
| status | Meaning in plain words |
|---|---|
| reachable | Responding The tested homepage answered successfully from our measurement point. |
| redirected | Unclear A redirect could not be completed safely. Read redirect_stop_reason. |
| access_restricted | Restricted A login, protection rule or rate limit blocked our request. The site may still work for people. |
| http_error | Error The server answered with an error code, such as 404 or 503. |
| dns_error | Error We could not find the website’s network address. |
| tls_error | Error We could not build a verified secure connection (certificate or connection settings). |
| timeout | Unclear No answer within the time limit. Not proof of an outage. |
| probe_error | Unclear Our measurement could not finish. This says nothing about the website. |
New fields may be added over time. Ignore fields your code does not know. The complete contract is in the OpenAPI description (a machine-readable map of every endpoint).
Agent readability: can AI agents read a website?
This check reads a few public files of a website: its homepage, robots.txt (rules for bots), the optional llms.txt (a short guide for AI tools), the MCP and API discovery files, the sitemap and a Markdown version. It returns the CheckWebsiteNow Agent Readability Score from 0 to 100: our own transparent score, not an official standard, with a fix for every lost point. No scripts are run and no forms are sent. On our home page it runs with every Check Website and appears as a speedometer. How the score works.
/api/v1/agent-checkBody: {"hostname":"example.com"}curl -s https://checkwebsitenow.com/api/v1/agent-check \
-H "Content-Type: application/json" \
-d '{"hostname":"example.com"}'import requests
report = requests.post(
"https://checkwebsitenow.com/api/v1/agent-check",
json={"hostname": "example.com"},
timeout=30,
).json()
print(report["score"], report["band"]["label"])
for item in report["deductions"]:
print("+", item["lost_points"], item["fix_title"])const response = await fetch("https://checkwebsitenow.com/api/v1/agent-check", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ hostname: "example.com" }),
});
const report = await response.json();
console.log(report.score, report.band.label);
for (const item of report.deductions ?? []) {
console.log("+", item.lost_points, item.fix_title);
}| Field | What it tells you |
|---|---|
| score, band | 0 to 100 and its band (Low agent readiness, Partly agent-ready, Good, Excellent). headline answers separately whether agents can read the text and lists missing helpers. score is null with a score_unavailable_reason when too little could be measured; never a guess. |
| groups | Four groups: AI bot access, readable content, structure and metadata, agent help and actions (llms.txt, MCP, WebMCP). |
| checks, deductions | 14 checks with status, points, evidence and a fix (title, detail, copy-ready snippet). deductions lists every lost point. |
| mcp, webmcp | Explicit MCP discovery results (advertised, not tested) and WebMCP declarations (declared, not verified in a browser). |
| homepage_truncated | true when the homepage was larger than 1 MiB and we analysed its first 1 MiB; homepage_note explains it. |
| final_url, final_origin | The homepage we finally read, and the origin used for the other files. |
Published bot rules do not prove that a particular AI service can really connect, and a missing llms.txt does not make a readable page unreadable. Nothing here guarantees a place in search results or AI answers.
Website blocked in your country?
If a site may be blocked for some countries (geoblocking), ask for ordered solutions: free steps first, VPN providers only when a regional block is suspected, ordered by documented criteria without commission. Links with affiliate: true are ads; show their label “Ad” and the disclosure.
/api/v1/access-solutions?domain=example.comAdd &visitor_reported=1 when the site says it is not available in your countryError library: what does an error mean, and how do I fix it?
Every fix guide on this site is also available as data: meaning, likely causes, steps for visitors, steps for site owners, what to avoid and sources.
curl -s "https://checkwebsitenow.com/api/v1/errors/lookup?q=ERR_CONNECTION_REFUSED"import json
import urllib.parse
import urllib.request
query = urllib.parse.quote("ERR_CONNECTION_REFUSED")
url = f"https://checkwebsitenow.com/api/v1/errors/lookup?q={query}"
with urllib.request.urlopen(url, timeout=20) as response:
matches = json.load(response)["matches"]
if matches:
print(matches[0]["title"], "-", matches[0]["summary"])const query = encodeURIComponent("ERR_CONNECTION_REFUSED");
const response = await fetch(`https://checkwebsitenow.com/api/v1/errors/lookup?q=${query}`);
const { matches } = await response.json();
if (matches.length) console.log(matches[0].title, "-", matches[0].summary);All read-only endpoints
/api/v1/errors/lookup?q=Up to five ranked matches for a code or pasted message (1 to 300 characters)/api/v1/errorsThe whole library; optional filters ?category= and ?kind=/api/v1/errors/{slug}One complete guide, for example /api/v1/errors/http-503/api/v1/status-sitesPopular services with an “Is it down?” page; official status links only where verified/api/v1/statsPublic service facts: version, limits, library size. Never visitor analytics/api/v1/methodologyHow we measure, and what a check cannot provecurl -s "https://checkwebsitenow.com/api/v1/errors?kind=http_status"
curl -s https://checkwebsitenow.com/api/v1/errors/http-503
curl -s https://checkwebsitenow.com/api/v1/status-sites
curl -s https://checkwebsitenow.com/api/v1/stats
curl -s https://checkwebsitenow.com/api/v1/methodologyWhen a request is refused: error codes
Refusals always come back in one shape: {"error":{"code":"…","message":"…"}}. They describe our service or your request. They are never a verdict about the website you asked for.
| HTTP | error.code | What happened and what to do |
|---|---|---|
| 400 | INVALID_INPUT, INVALID_TARGET, INVALID_JSON, INVALID_QUERY, INVALID_FILTER | The request was not usable. Send exactly {"hostname":"example.com"} with a public domain, or fix the query parameter. |
| 403 | ORIGIN_NOT_ALLOWED | The request came from a web page on another domain. Call the API from your script or server instead. |
| 404 | NOT_FOUND | Unknown endpoint or unknown error slug. Use the lookup endpoint to search. |
| 408 | REQUEST_TIMEOUT | Your request body did not arrive in time. Send it again. |
| 413 | INVALID_SIZE | The JSON body is larger than 2048 bytes. |
| 415 | JSON_REQUIRED | Send the header Content-Type: application/json. |
| 429 | RATE_LIMITED | You reached a limit. Wait the number of seconds in the Retry-After header (currently 60), then try again. |
| 429 | PROBE_BUSY | All measurement slots are busy right now. Also sends Retry-After. Try again shortly. |
| 500 | PROBE_ERROR | Our measurement failed internally. This is not evidence that the website is down. |
import json
import time
import urllib.error
import urllib.request
def check(hostname):
request = urllib.request.Request(
"https://checkwebsitenow.com/api/v1/check",
data=json.dumps({"hostname": hostname}).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
for attempt in range(2):
try:
with urllib.request.urlopen(request, timeout=20) as response:
return json.load(response)
except urllib.error.HTTPError as error:
problem = json.load(error)["error"]
if error.code == 429 and attempt == 0:
time.sleep(int(error.headers.get("Retry-After", "60")))
continue
raise RuntimeError(f"{problem['code']}: {problem['message']}") from error
print(check("example.com")["status"])Limits and fair use
The limits keep the free service fast for everyone. They count per client (your internet address) and may change; always respect Retry-After.
- Website checks: 10 per minute. The same domain is answered from a 60-second cache.
- Agent-readability checks: 10 per minute, so one can run with every website check. Both check types share four measurement slots.
- Error library, status sites and stats: 120 requests per minute together.
- Remote MCP: 60 requests per minute, plus the same check limits as above.
- Request size: 2048 bytes of JSON for the HTTP API, 16 KiB for MCP.
Fair use means: check websites when you need an answer, not in bulk. Store results instead of asking again within a minute. Do not use the API to scan many domains or to put load on websites. Need more? Tell us what you are building.
What a check is: one look from one measurement point at the public HTTPS homepage, following at most five safe redirects within ten seconds. It is not a worldwide outage verdict and does not test sign-in, checkout or every page. How our checks work.
MCP: plug the checker into your AI assistant
MCP (Model Context Protocol) is a common standard that lets AI assistants use outside tools. Think of it as one plug that fits many assistants. Add our endpoint once, and you can ask your assistant “Is example.com up?” or “What does ERR_CONNECTION_REFUSED mean?”.
https://checkwebsitenow.com/mcpStreamable HTTP, stateless, JSON answers. No key, no session.Claude Code
claude mcp add --transport http checkwebsitenow https://checkwebsitenow.com/mcpClaude Desktop
If your Claude app offers custom connectors: open Settings → Connectors → Add custom connector, name it CheckWebsiteNow and paste https://checkwebsitenow.com/mcp. Otherwise, add this to claude_desktop_config.json. It uses the open-source mcp-remote bridge and needs Node.js:
{
"mcpServers": {
"checkwebsitenow": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://checkwebsitenow.com/mcp"]
}
}
}Cursor
{
"mcpServers": {
"checkwebsitenow": {
"url": "https://checkwebsitenow.com/mcp"
}
}
}VS Code
{
"servers": {
"checkwebsitenow": {
"type": "http",
"url": "https://checkwebsitenow.com/mcp"
}
}
}Raw protocol, for testing
MCP messages are JSON-RPC (a simple request-and-answer format). List the tools, then call one:
curl -s https://checkwebsitenow.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl -s https://checkwebsitenow.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"check_website","arguments":{"hostname":"example.com"}}}'Supported protocol versions: 2026-07-28, plus 2025-11-25, 2025-06-18 and 2025-03-26 through initialize. Details and the newer header rules are in the agents page.
The nine tools
check_website {hostname}Is the public homepage responding? Verdict, evidence, limits and a fix guide.check_agent_readability {hostname}The Agent Readability Score 0-100 with a fix for every lost point; MCP and WebMCP status named explicitly.get_agent_readability_method {}How the score works: checks, weights, caps and bands.get_access_solutions {domain, case?, visitor_reported?}Website blocked in a country? Free steps first; VPN providers only when a block is suspected; ads labelled.explain_error {query}Match a pasted browser, HTTP, DNS or certificate error and return the fixes.list_errors {category?, kind?}List the error library.get_error {slug}One complete fix guide.list_status_sites {}Popular services with verified official status links where available.get_service_info {}Method, limits, version and library size. No visitor analytics.
WebMCP: tools inside the browser
WebMCP is a new, experimental browser feature. It lets an AI assistant that runs in your browser use a web page’s functions as tools, instead of clicking around. Our home page check form is declared as the WebMCP tool check_website (with toolname, tooldescription and toolparamdescription). In a browser that supports WebMCP, every page also offers the same tools as our MCP server through document.modelContext.registerTool(), including check_agent_readability and get_access_solutions. On the home page the assistant’s check also appears on screen, so you see the same result.
Most browsers do not support WebMCP yet. The website, the HTTP API and MCP all work without it. Chrome’s WebMCP documentation
Privacy
We need the domain you send to run the check; only the domain name is accepted, never a full link with paths or queries. Answers are public observations about public websites. The API and MCP never return visitor analytics, session recordings, other people’s inputs or access data. Read the privacy details.