q.cf.rt.ht and qi.rt.ht

q.cf.rt.ht answers questions about domains, IP addresses and networks in one HTTP call: DNS records, IP and ASN data, RDAP and WHOIS records, whether a TLD exists, and whether a host supports post-quantum TLS. qi.rt.ht is its console, and whois.rt.ht is a WHOIS front end.

Syntax

plain
https://q.cf.rt.ht/?TYPE=VALUE[&TYPE=VALUE…]
https://qi.rt.ht/?TYPE=VALUE[&TYPE=VALUE…]
https://whois.rt.ht/<domain>

Every query parameter of q.cf.rt.ht is TYPE=VALUE. The host answers GET requests and ignores the path. Types are not case-sensitive. A type and a value can each be a comma list. Braces expand first, and they can nest. Each result then splits on commas, and every pair of a type and a value runs, as a cartesian product. Text outside the braces is copied into every alternative, and duplicates collapse in the result. Send i to see what a query would run, without running it:

plain
https://q.cf.rt.ht/?i&A={rtcode,rtedge}.io,elefunc.com

The plan is A rtcode.io, A elefunc.com, A rtedge.io and A elefunc.com. A request with no TYPE=VALUE pair, or with only control parameters such as ?s, gets a 308 redirect to https://apple.com/.

Parameters

Control parameters

Control parameters are removed before the query is planned.

_=<JSON>

Options, for example _={"max":0} or the TLD filters below.

s

With any value: short, raw results. A and AAAA stay plain arrays, and IP only echoes its value.

i

With an empty value only: returns the expanded plan, [[TYPE, value], …], without running it.

0

With an empty value only: no retries.

An empty value, and the values i and I, mean your own IP address, so ?ip looks up your IP. TLD is the exception: an empty value lists every TLD.

Types

TypeValueResult
A, AAAA, CNAME, PTR, NSA nameAn array of strings.
TXTA nameAn array of strings, with the outer quotes removed.
MXA name{ preference, exchange }
SOAA name{ mname, rname, serial, refresh, retry, expire, minimum }
SRVA name{ priority, weight, port, target }
CAAA name{ flags, tag, value }
HTTPSA nameThe decoded SvcParams, plus content.
XAn IP addressA reverse lookup: a PTR query on d.c.b.a.in-addr.arpa for IPv4, or on the nibble-reversed ip6.arpa name for IPv6.
IPAn IP addressThe IPinfo record of the address.
ASA number, AS13335 or ASN13335The IPinfo ASN record: asn, allocated, country, domain, downstreams and more.
RDAPA domain, an IP address or an ASNThe RDAP record, as JSON.
RDAXA domain, an IP address or an ASNThe RDAP record, as indented text.
WHOISA domain, an IP address or an ASNThe WHOIS text.
TLDEmpty, or a labelThe list of TLDs, or true or false for one label.
PQA hostThe post-quantum TLS check.

The DNS types ask Cloudflare DNS over HTTPS, with a timeout of 4 seconds, and a DNS status other than zero becomes an error.

A, AAAA and IP enrichment

Unless you send s, an A or AAAA answer is enriched with IPinfo data: each address becomes a record with fields such as city, region, country, loc, postal, timezone, anycast, asn, company, privacy, abuse and domains. The fields come from IPinfo and can vary. With s the answers stay plain arrays, and ?s&ip answers {"IP":{"<your IP>":"<your IP>"}} without an external lookup.

RDAP

The host picks the RDAP server from IANA's bootstrap files, and returns the first answer that is not 404. If every server answers 404, the result is { error: "No records for <type>: <value>", status: 404, … }. A TLD that is missing from the bootstrap fails with "RDAP servers not found for TLD: <tld>". That was true for .io on 2026-10-04, so use WHOIS for such names.

WHOIS

The host queries port 43 over a TCP socket. The IANA referral picks the server and is remembered for each TLD. Connecting and reading each time out after 4 seconds, and reading stops after 1,000,000 bytes. For some TLDs, and when a lookup fails, the answer falls back to RDAX text.

RDAX

The RDAP record as - key: value text, indented by 4 spaces for each level. It starts with "NOTICE: This is synthesized from RDAP data." When it stands in for a WHOIS lookup that failed, the first line reads "NOTICE: WHOIS service failed! This is synthesized from RDAP data."

TLD

An empty value returns IANA's list of TLDs as a lower-case array, in IANA's order. A label returns true or false. Options in _ filter by label length with min and max, and join with any non-null value returns one comma-separated string, as in tld=&_={"min":3,"max":4,"join":true}.

Tip: Add 0 to a TLD query, as in ?TLD=com&0. In _, max is also the retry count, and TLD reads it as the longest label, so the default can cut the answer short unless you send 0 or set max yourself.

PQ

The host asks Cloudflare Radar whether a host supports post-quantum TLS, and answers { secure, host: "<host>:443", kex: { name, id } }. A fallback path adds "_": -2 or -1, and a total failure answers { "error": "PQ test failed for <host>" }. On 2026-10-04, rtedge.net, rtcode.io and elefunc.com answered X25519MLKEM768, id 4588, with secure: true. See Post-quantum cryptography.

Retries

RDAP, RDAX, WHOIS and the domain-availability types retry up to max times after the first attempt: twice by default, with a linear back-off of 200 ms for each attempt. Send 0, or _={"max":N}, to change that.

CDN and domain-availability types Experimental

FASTLY=<host>

Requests https://<host>/ with the header fastly-debug: 1, and answers { debug } with the fastly-debug-* values, without their prefix.

AKAMAI=<host>

Sends Akamai's Pragma debug directives, and answers with all response headers.

CF=<host>

Listed in the QI help. It is meant to read /cdn-cgi/trace, but it currently answers {} for every host.

DNSP, CFRP and IDS

Each takes a domain and checks whether a domain registrar offers it. The answers contain data from third-party registrars, so this page shows no sample output. IDS checks a value without a dot under .com.

The types answer { error } when a probe fails.

Response

The answer is 200 JSON of the form { "<TYPE>": { "<value>": <result> } }, pretty-printed with two spaces, with the types in the order of the query. Each result is sorted: object keys, and string arrays such as NS and TXT records, alphabetically. PQ and TLD with an empty value are not sorted.

js
{ "PQ": { "rtcode.io": { "secure": true, "host": "rtcode.io:443", "kex": { "name": "X25519MLKEM768", "id": 4588 } } } }

A failure that is not tied to one query answers 200 with text/plain and the error text. A failing query shows as { "error": "<text>" } inside the JSON.

Response headers

HeaderValue
Access-Control-Allow-Origin*
Cache-Controlno-store
_The options as JSON, with the defaults, for example {"max":2}.
ip{"i":"<your IP>"}
ip-xhttps://ipinfo.io, the source of the IP data.
durThe time taken, in milliseconds.
server-timingtotal;dur=<ms>
Access-Control-Expose-Headers_, ip, ip-x, dur, server, server-timing

The QI console

qi.rt.ht is an RTCode deployment that sends what you type to q.cf.rt.ht and shows the result as foldable JSON.

For the raw JSON, open https://q.cf.rt.ht/?<query> directly. The built-in help lists the flags, the types and these examples:

QueryWhat it asks
a,aaaa=example.comThe addresses of a name.
mx,txt=example.comThe mail exchangers and the TXT records.
x=1.1.1.1The reverse name of an address.
ip=1.1.1.1&as=13335An address and an ASN.
rdap=openai.com&whois=openai.comThe RDAP and the WHOIS record of a domain.
tld=&_={"min":3,"max":4,"join":true}The TLDs of three or four letters, as one string.
i&a,aaaa=example.comThe plan of a query, without running it.
s&ip=1.1.1.1A short answer, without enrichment.
pq=cloudflare.comA post-quantum TLS check.

whois.rt.ht

Experimental whois.rt.ht is a small worker that calls q.cf.rt.ht and unwraps the answer. The same worker also answers on who.rt.ht and wi.rt.ht.

https://whois.rt.ht/<domain>

The domain is the path, or the q parameter. It is lower-cased and trimmed, and another spelling gets a 308 to the canonical path, so /RTCode.io goes to /rtcode.io. An empty domain looks up your own IP address.

Default

Plain-text WHOIS.

?s

With an empty value: drops the % and # comment lines and collapses blank lines.

?rdap

RDAP JSON. ?rdap&text, or &x, returns RDAX text instead, and so does ?rdax in lower case.

The answer copies the headers of q.cf.rt.ht, with Access-Control-Allow-Origin: *, and adds url: //q.cf.rt.ht/?… and q-d: <domain>. The content type is text/plain;charset=utf-8 or application/json;charset=utf-8.

Examples

Check post-quantum TLS and DNS in one call

One request asks for the pq and a types, with s for short answers:

html
<ul id=pq></ul>
<script type=module>
  const q = new URLSearchParams({ pq: 'rtcode.io,rtedge.net', a: 'rtcode.io', s: '' });
  const { PQ, A } = await fetch(`//q.cf.rt.ht/?${q}`).then(r => r.json());
  pq.innerHTML = Object.entries(PQ).map(([host, { secure, kex }]) => `<li>${host}: ${secure ? '🔐' : '⚠️'} ${kex?.name}</li>`).join('') + `<li>rtcode.io A: ${A['rtcode.io'].join(', ')}</li>`;
</script>

This is the pattern behind the Verify button on elefunc.com.

html
<a href=//qi.rt.ht/?pq=elefunc.com,rtedge.net,rtcode.io target=_pq>Verify post-quantum TLS</a>
<a href=//qi.rt.ht/?mx,txt=example.com target=_qi>MX and TXT for example.com</a>

CORS and limits

Status

q.cf.rt.ht and qi.rt.ht are available, with the DNS, IP, AS, RDAP, RDAX, WHOIS, TLD and PQ types and the control parameters. These parts are Experimental and may change: the CDN and domain-availability types, and whois.rt.ht. Behavior was checked on 2026-10-04.

See also