PARTNER API v1 prototype
credits console site status

Checks any agent can buy — no account, per call, for tenths of a cent — or fund with a prepaid key. Every endpoint answers unpaid requests with HTTP 402 and machine-readable payment terms, so an agent can discover the price, pay, and retry without a human. Agents: start at /llms.txt (full reference /docs.md, OpenAPI, MCP server https://how.is/mcp).

Try it free, then pay

# every check has a free sample input — real data, no key (20/hour) curl "https://how.is/v1/domain/whois?domain=example.com" # any other input: the 402 lists every rail that works right now curl -X POST https://how.is/v1/domain/whois -d '{"domain":"github.com"}' # → 402 + terms # rail 1 — x402 (agents, no account): sign the PAYMENT-REQUIRED terms, retry with # PAYMENT-SIGNATURE: <base64 payload> (Base Sepolia testnet for now) # rail 2 — prepaid key: buy by card on how.is, then curl -X POST https://how.is/v1/domain/whois -H "Authorization: Bearer sk_…" -d '{"domain":"github.com"}'

Endpoints — POST a JSON body, or GET with the same field as a query parameter

endpointpricewhat you get
/v1/domain/profile$0.025 All of the domain checks below plus IP intelligence for the A record, in one call. Body: {"domain": "..."}.
/v1/domain/dns$0.005DNS records by type, with resolve timing. {"domain"}
/v1/domain/whois$0.005Parsed WHOIS/RDAP: registrar, dates, nameservers, status. {"domain"}
/v1/domain/tls$0.005Certificate validity, issuer, SANs, days until expiry, protocol. {"domain"}
/v1/domain/dnssec$0.005Signed / valid, chain of trust, DS and DNSKEY records. {"domain"}
/v1/domain/email-auth$0.005SPF, DKIM, DMARC, MX and an overall score. {"domain"}
/v1/domain/security-score$0.005Letter grade and point score with the scored items. {"domain"}
/v1/domain/blacklist$0.005Whether the domain's addresses are on spam/abuse blocklists. {"domain"}
/v1/ip$0.005ASN, company, location, privacy flags, abuse contact. {"ip"}
/v1/check/site$0.005 Per site: HTTP status + latency, DNS resolve time, resolved IP, A-record TTL, nameservers, TLS days-remaining, server header. Body: {"sites": [...]} (up to 10).
/v1/watch/page$0.005 Content-change detection vs last snapshot: text-similarity %, changed flag (≥2% threshold), added/removed snippets, last-change time. Body: {"url": "..."}. First call stores the baseline.
/v1/bots$0.050 The bot observatory's partner tier, one document regenerated hourly: networks (ASN), named crawlers and TLS (JA4) fingerprints seen across the constellation in the last 7 days. Body: {}. The public tier is free at dns.pizza/bots.
POST /v1/monitorsruns billed Scheduled checks. Body: {"type": "site"|"page", "target": url, "interval_min": 5} + Bearer key. Each run charges the key. Cap/balance failure pauses the monitor.
GET /v1/monitorsfreeList your monitors with state, last run, last summary. Requires your Bearer key — it only ever returns monitors funded by that key.
PATCH / DELETE /v1/monitors/<id>freePause, change interval, or delete. Funding key required (Bearer).
GET /v1freeMachine-readable index of all of the above.

Spend safety (prepaid keys)

daily capper key, default $0.10; the operator can raise it
100% of caphard stop — 402 daily spend cap reached until 00:00 UTC (x402 rail unaffected)

Monitors: the subscription that is just credits + a schedule

# check a site every 5 min ($1.44/day) curl -X POST https://how.is/v1/monitors -H "Authorization: Bearer sk_…" \ -d '{"type":"site","target":"https://example.com","interval_min":5}' # watch a page for material changes every 30 min curl -X POST https://how.is/v1/monitors -H "Authorization: Bearer sk_…" \ -d '{"type":"page","target":"https://example.com/pricing","interval_min":30}'

Billing rules

casewhat you are charged
Check succeedsthe listed price, once.
Single check failsnothing — a failed individual check is refunded.
Profile, some parts failthe full bundle price. The response names the missing parts in errors and restates this in billing. A profile is refunded only if every part fails.
Profile side effecteach profile also stores a free page snapshot of https://<domain> so your first page_watch on it returns a real diff. An existing baseline is never overwritten. No charge, and it never fails the call.