API and curl reference.

Every server-side tool on this site is also a small API. Point curl at the same URL you would open in a browser and you get plain text; ask for JSON and you get JSON. No key, no sign-up, nothing stored. Last updated 2026-09-30.

The short version

curl kirkdiamond.com/tools/dns?name=example.com                 # plain text
curl "kirkdiamond.com/tools/tls?host=example.com&format=json"     # JSON
curl -H 'Accept: application/json' kirkdiamond.com/tools/ip       # JSON by header

That is the whole interface. The rest of this page lists the endpoints and their parameters, says which parts of the output you can build on, and has copy-and-paste checks for CI and cron.

How the output format is chosen

Each request is answered as HTML, plain text or JSON, decided in this order:

SignalExampleResult
?format= in the query&format=json, &format=text, &format=htmlAlways wins
The Accept headerAccept: application/json or text/plainJSON or text
The user agentcurl, wget, HTTPie, xhPlain text
Anything elseA browserThe HTML page

Plain text is laid out for a terminal and may change as the tools improve. If a script reads the output, ask for JSON.

Endpoints

One per server-side tool. This list is generated from the same catalogue as the tools index, so it cannot fall behind it. Browser-side tools (JSON, JWT, Base64, timestamps, diff, hashes) have no endpoint: they never send your input anywhere, which is the point of them.

Domain Health checker

GET /domain-health · open the domain health checker

ParameterRequiredMeaning
domainyesThe domain to check, e.g. example.com.
curl "kirkdiamond.com/domain-health?domain=example.com"

grade, pass, warn, fail, and pillars[] (dns, tls, http, mail), each with its own grade and checks[].

DNS lookup

GET /tools/dns · open the dns lookup

ParameterRequiredMeaning
nameyesThe name to look up.
typenoRecord type; repeat for several (type=A&type=MX). Defaults to A, AAAA, CNAME, MX, NS and TXT.
resolvernoIP address of a public resolver: 1.1.1.1 (default), 8.8.8.8, 9.9.9.9, 208.67.222.222 or any other public one.
curl "kirkdiamond.com/tools/dns?name=example.com&type=MX"

name, server, server_ip, and answers[]: one per type, with rcode, records[] (each with its TTL), rtt and transport.

DNS trace & propagation checker

GET /tools/dns-trace · open the dns trace & propagation checker

ParameterRequiredMeaning
nameyesThe name to trace from the root.
typenoRecord type to follow (A by default).
curl "kirkdiamond.com/tools/dns-trace?name=example.com"

hops[] (the delegation walk), rcode, answer, parent_ns, child_ns, authoritative_servers[], resolvers[] (each marked current or stale) and findings[].

SSL/TLS certificate checker

GET /tools/tls · open the ssl/tls certificate checker

ParameterRequiredMeaning
hostyesHostname or IP to connect to.
portnoPort, 443 by default.
sninoServer name to send, if different from host.
curl "kirkdiamond.com/tools/tls?host=example.com"

version, cipher, alpn, verified, hostname_match, versions (which TLS versions are accepted) and chain[], where chain[0] is the leaf with not_after and days_left.

SSL certificate chain checker

GET /tools/chain · open the ssl certificate chain checker

ParameterRequiredMeaning
hostyesHostname or IP to connect to.
portnoPort, 443 by default.
sninoServer name to send, if different from host.
curl "kirkdiamond.com/tools/chain?host=example.com"

complete, verified, ordered, root_sent, hostname_match, missing[], findings[], clients[] (one verdict per modelled client) and fullchain_pem.

Email deliverability checker

GET /tools/mail · open the email deliverability checker

ParameterRequiredMeaning
domainyesThe domain to check.
curl "kirkdiamond.com/tools/mail?domain=example.com"

grade, checks[], mx[], spf (record, terms tree, lookups, void_lookups), dmarc (policy, pct, tags) and dkim[] for the selectors found.

HTTP header & redirect checker

GET /tools/http · open the http header & redirect checker

ParameterRequiredMeaning
urlyesThe URL to fetch. A bare host gets https:// added.
methodnoGET (default) or HEAD.
curl "kirkdiamond.com/tools/http?url=https://example.com"

hops[] (status, location and timings per redirect), redirects, proto, http3_advertised, compression, grade, checks[] (security headers) and cookies[].

Webhook tester & request bin

POST /tools/bin · open the webhook tester & request bin

curl -si -X POST kirkdiamond.com/tools/bin | grep -i ^location

Creating a bin answers 303 with its viewer in Location. Send anything to /b/<id>; read the captures as JSON from /tools/bin/<id>?format=json.

HTTP request header checker

GET /tools/headers · open the http request header checker

curl kirkdiamond.com/tools/headers

The request headers exactly as the server received them.

HTTP status code tester

GET /tools/status/{code} · open the http status code tester

ParameterRequiredMeaning
delaynoMilliseconds to wait before answering, up to 10000.
curl -i "kirkdiamond.com/tools/status/503?delay=2000"

Plain text only. The status line is the point.

ASN & IP lookup

GET /tools/ipinfo · open the asn & ip lookup

ParameterRequiredMeaning
qyesAn IPv4 or IPv6 address, or a hostname.
curl "kirkdiamond.com/tools/ipinfo?q=1.1.1.1"

ip, version, ptr, asn, as_name, prefix, country, registry and rdap (the registry's own record).

What is my IP address

GET /tools/ip · open the what is my ip address

curl kirkdiamond.com/tools/ip

ip, version and proxied.

Findings, grades and guide links

The graders (Domain Health, the email, HTTP, chain and DNS trace tools) return their verdicts as a list, checks or findings, with the same shape everywhere:

{
  "name": "Strict-Transport-Security",
  "status": "fail",
  "value": "missing",
  "note": "Without HSTS a browser will follow a plain http:// link ...",
  "guide": "https://kirkdiamond.com/guides/hsts-preload-checklist"
}

status is always one of pass, warn, fail or info. guide, when present, is the guide that explains the finding; the plain-text output prints it as a see line under the finding. Grades are A to F.

What you can build on

Errors and rate limits

A query that cannot run (a malformed hostname, a private address, a host that does not answer) comes back as 400 with an error field in JSON, or an error: line in text. Lookups that make outbound connections share a limit per client address of 30 a minute with a burst of 10. Past that you get:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{"error": "Too many lookups in a short time. Give it a minute.", ...}

The bucket refills continuously, so waiting a few seconds between calls is enough for a loop over a handful of domains. Every tool refuses to connect to private, loopback and other non-public addresses; that is a guard, not an error on your side.

Checks for CI and cron

These use curl -f, so a 400 or 429 fails the step rather than passing it silently, and jq, which is on every GitHub Actions runner. Replace example.com with your own domain.

Fail the build if a certificate expires within 14 days

days=$(curl -sf "https://kirkdiamond.com/tools/tls?host=example.com&format=json" | jq '.chain[0].days_left')
echo "certificate: $days days left"
[ "$days" -ge 14 ]

Fail if SPF is over the ten-lookup limit

n=$(curl -sf "https://kirkdiamond.com/tools/mail?domain=example.com&format=json" | jq '.spf.lookups // 0')
echo "SPF: $n of 10 lookups"
[ "$n" -le 10 ]

Over ten, receivers treat the record as a PermError. The SPF lookup limit guide covers getting back under.

Fail if HSTS is missing or weak

curl -sf "https://kirkdiamond.com/tools/http?url=https://example.com&format=json" \
  | jq -e '.checks[] | select(.name == "Strict-Transport-Security") | .status == "pass"'

The same as a GitHub Actions step

- name: Certificate has at least 14 days left
  run: |
    days=$(curl -sf "https://kirkdiamond.com/tools/tls?host=example.com&format=json" | jq '.chain[0].days_left')
    echo "certificate: $days days left"
    test "$days" -ge 14

A weekly report by email

# crontab: every Monday at 08:00, the plain-text Domain Health report
0 8 * * 1  curl -s "https://kirkdiamond.com/domain-health?domain=example.com" | mail -s "domain health: example.com" [email protected]

Run checks like these on a schedule, not in a tight loop: once a day or once a deploy is plenty, and it keeps you well inside the limits.

Calling it from a web page

JSON responses carry no CORS headers, so a script on another site cannot call these endpoints from a visitor's browser. That is deliberate: they are for curl, servers and CI, where the request comes from you rather than from someone else's visitors.

Fair use

No key and no sign-up, and you do not need to ask. Automated use for ordinary diagnostic and development work is welcome within the rate limits, as set out in the terms of use. Targets you look up are not logged or stored; the privacy page has the detail. If you are building something that needs more than the limits allow, email [email protected].

All tools · Guides · Terms