Protocols

DNS over HTTPS

Ask DNS questions over HTTPS instead of plain UDP. Private, and it works anywhere HTTPS works.

Yatta answers DNS questions on /dns-query. Only A and AAAA records are answered — the normal “what IP is this name?” question. Answers come from the machine’s own resolver.

Ask with JSON

The easy shape is a GET with a name and a type. Nothing else is needed.

Ask for an addressts
curl "http://localhost:4000/dns-query?name=example.com&type=A" # Answer{  "Status": 0,  "TC": false, "RD": true, "RA": true,  "Question": [{ "name": "example.com.", "type": 1 }],  "Answer": [{ "name": "example.com.", "type": 1, "TTL": 300, "data": "93.184.215.14" }]} # IPv6 instead — type AAAA, code 28curl "http://localhost:4000/dns-query?name=example.com&type=AAAA"

Ask from code

Ask for the JSON shape with an Accept header, then read the data field of the first answer.

Fetch the JSON shapets
const res = await fetch(  "http://localhost:4000/dns-query?name=example.com&type=A",  { headers: { Accept: "application/dns-json" } },);const body = await res.json();console.log(body.Answer[0].data); // "93.184.215.14"

Wire format

The strict RFC shape also works. POST a DNS wire message with Content-Type: application/dns-message, or GET with a base64url wire message in ?dns=.... The answer comes back as application/dns-message.

Wire message by POSTts
# query.bin holds one DNS wire message, one questioncurl -X POST --data-binary @query.bin \  -H "Content-Type: application/dns-message" \  http://localhost:4000/dns-query -o answer.bin # Or the same message, base64url, in a GETcurl "http://localhost:4000/dns-query?dns=AAABAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE"

Answer codes

Status 0
Answered. Check the Answer list.
Status 3
The name does not exist (NXDOMAIN).
Status 2
Server failure. Includes a type the server does not support, and a broken address from the resolver.
Wire rcode 4
NOTIMP on the wire shape, for a type other than A or AAAA. The JSON shape reports the same case as Status 2.

Only A and AAAA are ever answered. A type name the server does not know is answered “not supported”, never silently as A. And if the resolver hands back a broken address, the reply is a clean server failure, not a crash.

Bad questions

These answer 400, before any lookup happens: a wire message with more than one question, a compression pointer, a truncated message, or bad base64 in ?dns=. A GET with neither ?name= nor ?dns= also answers 400.

Warning
A public DoH endpoint can be used to map your network. Only expose /dns-query publicly if you mean to run a public resolver.