Documentation▾
Free Public API
Merlonix exposes a set of unauthenticated JSON endpoints under https://api.merlonix.com/v1/public/. They need no API key, no signup, and no Authorization header — they are the same endpoints that power the free tools, called directly.
They exist because the checks behind them are useful outside a browser: in CI, in a provisioning script, in an agent, or on a dashboard. Everything documented on this page is live and callable right now.
curl "https://api.merlonix.com/v1/public/mcp-health?url=https://mcp.deepwiki.com/mcp"
If you want to read or manage your own monitored assets, alerts, clients, and status pages, that is a different, key-authenticated surface — see the API reference and the MCP server.
Conventions
Base URL — https://api.merlonix.com/v1/public
Authentication — none. Do not send a key; these routes ignore one.
CORS — every JSON endpoint on this page responds with Access-Control-Allow-Origin: *, so you can call them from browser JavaScript on any origin.
Caching — responses carry a real Cache-Control (300–600s depending on the endpoint) and are served from Cloudflare's edge cache. A repeat request for the same target inside the TTL is answered from cache: it is fast, and it does not consume your rate budget, because no work is performed.
Rate limits — per client IP, per minute, on the cache-miss path only:
| Endpoint | Limit (req/min/IP) |
|---|---|
/mcp-health | 15 |
/domain-health | 20 |
/agent-readiness | 20 |
/blacklist | 10 |
/broken-links | 3 |
Exceeding a limit returns HTTP 429. The tighter limits are on the endpoints that fan out to many outbound probes per call — a broken-link scan is up to 25 link checks, and a blacklist check queries several DNSBL zones for every resolved IP.
Targets must be public. Every endpoint validates the target hostname and rejects private, reserved, and non-resolving hosts. localhost, 127.0.0.1, and RFC 1918 addresses return 400. These are outside-in checks; they cannot see inside your network.
Errors are a consistent envelope with a trace id you can quote in a support request:
{
"error": {
"code": "validation_failed",
"message": "Provide a valid public hostname, e.g. example.com",
"trace_id": "02bd0e8e-96ce-4994-8e78-7b192960ef29"
}
}
Codes you will see: validation_failed (400), not_found (404), rate_limited (429).
GET /v1/public/mcp-health
Probes a remote Model Context Protocol endpoint the way a client would: a JSON-RPC initialize POST, then tools/list, then resources/list and prompts/list where the server advertises them.
Parameters — url (required; aliases endpoint, domain). The full endpoint URL including its path, since an MCP endpoint is rarely at the origin root. A bare hostname is upgraded to https://. URLs carrying inline credentials are rejected.
curl "https://api.merlonix.com/v1/public/mcp-health?url=https://mcp.deepwiki.com/mcp"
{
"endpoint": "https://mcp.deepwiki.com/mcp",
"checked_at": "2026-08-03T23:56:17.111Z",
"status": "up",
"reachable": true,
"transport": "streamable_http",
"spec_generation": "stateful_2025",
"handshake_ok": true,
"tools_ok": true,
"auth_required": false,
"latency_ms": 216,
"http_status": 200,
"snapshot": {
"protocol_version": "2025-06-18",
"server_name": "DeepWiki",
"server_version": "2.14.3",
"capabilities": ["experimental", "prompts", "resources", "tools"],
"tools": ["ask_question", "read_wiki_contents", "read_wiki_structure"],
"tool_count": 3,
"resource_count": 0,
"prompt_count": 0,
"tool_digests": { "ask_question": "…" }
},
"findings": [],
"security_posture": {
"score": 70,
"grade": "C",
"summary": "…",
"dimensions": [],
"auth_required": false,
"secure_transport": true,
"tools_scanned": true
}
}
Fields worth knowing:
status—up,degraded, ordown.degradedis a server that answers but slowly, or answers incompletely.transport—streamable_httporsse. SSE framing on the response to aninitializePOST is permitted by Streamable HTTP and is not the legacy transport;ssehere means the server steered you to legacy HTTP+SSE. See Streamable HTTP vs SSE.spec_generation— which revision the server behaves like, including the stateless 2026 revision that has no handshake at all. A refusedinitializeis not automatically an outage; see why MCP initialize fails.auth_required—truewhen the endpoint answered401/403. That is a reachable, correctly gated server, not a down one.snapshot.tool_digests— a per-tool hash over name, description, and input schema. Store it and compare across runs to detect tool and schema drift.security_posture— an externally-observable grade only. It cannot audit your server's internals; see the MCP server security checklist.
The browser version of this is the MCP health checker, and the MCP directory is this endpoint run continuously across public servers.
GET /v1/public/domain-health
SSL certificate, domain registration, DNS, DNSSEC, security headers, CAA, security.txt, DMARC, SPF, and mail-transport posture for one hostname, plus a rolled-up score.
Parameters — hostname (required; alias domain).
curl "https://api.merlonix.com/v1/public/domain-health?hostname=example.com"
Top-level keys: hostname, checked_at, ssl, registration, dns, dns_security, security_headers, caa, security_txt, dmarc, spf, email_transport, health.
ssl.days_until_expiry and registration.days_until_expiry are the two fields most people wire into CI. health.score and health.band are the roll-up.
GET /v1/public/agent-readiness
How a site presents itself to AI agents and answer engines: llms.txt, robots rules for named AI crawlers, structured data, whether content survives without JavaScript, AI content-licensing signals, live reachability probes as several bots, /.well-known/mcp.json, page-level AI directives, and sitemap declarations.
Parameters — hostname (required; aliases domain, url).
curl "https://api.merlonix.com/v1/public/agent-readiness?hostname=example.com"
Top-level keys: hostname, checked_at, llms_txt, robots, structured_data, render_gate, ai_licensing, ai_reachability, mcp, ai_page_directives, sitemap, score, grade, findings.
render_gate is the one to read first if the score surprises you: it reports how much text is visible without executing JavaScript.
GET /v1/public/blacklist
Checks every IP a hostname resolves to against a set of DNSBL zones.
Parameters — domain (required; aliases host, hostname).
curl "https://api.merlonix.com/v1/public/blacklist?domain=example.com"
{
"hostname": "example.com",
"checked_at": "2026-08-03T23:56:20.669Z",
"status": "clean",
"checked_ips": ["104.20.23.154", "172.66.147.243"],
"listed_count": 0,
"zones_queried": 20,
"zones_total": 8,
"listings": []
}
zones_total is the number of zones consulted; zones_queried is the total lookups performed (zones × resolved IPs). Each entry in listings names the zone and the listed IP.
GET /v1/public/broken-links
Fetches one page, extracts its links, and checks them. Also reports mixed content — HTTP subresources on an HTTPS page.
Parameters — url (required; aliases page, domain). This one is per page, not per host, so the path matters.
curl "https://api.merlonix.com/v1/public/broken-links?url=https://example.com/"
{
"url": "https://example.com/",
"hostname": "example.com",
"checked_at": "2026-08-03T23:57:23.311Z",
"broken_count": 0,
"mixed_content_count": 0,
"broken": [],
"mixed_content": [],
"truncated": false,
"max_link_checks": 25
}
truncated: true means the page had more links than max_link_checks and only the first batch was checked. This is the most expensive endpoint per call, hence the 3/min limit.
GET /v1/public/vendors and /v1/public/vendors/{slug}
The status of the upstream providers Merlonix tracks — cloud platforms, CDNs, AI providers, payment processors — polled from their own status feeds.
curl "https://api.merlonix.com/v1/public/vendors"
curl "https://api.merlonix.com/v1/public/vendors/anthropic"
The collection returns { data: [...], checked_at }, each row carrying slug, name, current_status, last_updated, incident_count_24h, and incidents. The single-vendor route adds history — roughly 30 days of status events. An unknown slug returns 404.
Note that last_updated is the last status change, while checked_at is when the feed was last polled. An unknown slug returns 404, so treat the collection as the authoritative slug list.
Status badges
Each of these returns image/svg+xml and is safe to hotlink in a README or a status page. They are cached for 600s.




Every badge carries an aria-label describing its state in words, so it degrades sensibly for screen readers and for anyone who blocks images. There are also larger card.svg variants of the domain-health and agent-readiness badges for social embeds.
Fair use
There is no key, so there is no quota to buy and nothing to cancel. The rate limits above are the whole policy. Two requests:
- Cache on your side too. These checks probe third parties. If you are polling the same target on a schedule, respect the
Cache-Controlyou get back rather than hammering past it — the answer will not have changed. - Do not point the scanning endpoints at hosts you have no relationship with, at volume. Each call generates real outbound traffic to the target. One check is ordinary internet behavior; a loop over someone else's infrastructure is not, and it is your IP in their logs.
If you need higher volume, scheduled checks, history, alerting, or checks against private endpoints, that is what an account is for. If you are building something on these endpoints and the limits are in your way, get in touch — we would rather know.