GET/api/v2/dns
DNS lookup API
Ask one resolver one question: any record type of a name, or the PTR of an IP address.
- 60 calls a minute per IP
- Same engine as the DNS Lookup tool
{
"query": {
"name": "github.com",
"type": "A",
"resolver": "google"
},
"resolver": {
"id": "google",
"name": "Google Public DNS",
"ip": "8.8.8.8",
"transport": "tcp"
},
"rcode": "NOERROR",
"authoritative": false,
"dnssecValidated": false,
"records": [
{
"name": "github.com",
"type": "A",
"ttl": 60,
"value": "140.82.114.4"
}
],
"authority": [],
"tookMs": 48
}How it works
Sends one query to one recursive resolver and returns its whole answer: the response code, the AA and AD flags, the answer section (CNAMEs it followed, then the records) and the authority section, which holds the SOA of a negative answer. Values come in presentation format, and MX, SRV, SOA and CAA also come parsed in data.
Resolvers are asked over TCP on port 53 (RFC 7766); Cloudflare's own addresses (1.1.1.1, 1.0.0.1 and their family filters) over DNS-over-HTTPS. The AD bit is set in the query (RFC 6840 §5.7), so a validating resolver reports whether DNSSEC checked out.
A resolver that doesn't answer is a result, not an error: rcode is null, and incomplete with warnings says whether it timed out (5 seconds), refused the connection or sent something unreadable. For the authoritative answers, the path from the root and every record type at once, use the DNS Lookup page.
Query parameters
namestringrequiredA domain or host name (a URL or an e-mail address works too; IDNs in Unicode are sent as Punycode), or an IPv4 or IPv6 address, which is asked as its in-addr.arpa or ip6.arpa name.typestringoptionaldefaultAThe record type. DefaultAfor a name,PTRfor an IP address (an address has no other type).one of
A,AAAA,CNAME,MX,NS,PTR,SRV,SOA,TXT,CAA,DS,DNSKEY,HTTPS,SVCBresolverstringoptionaldefaultgoogleA named resolver (google,cloudflare,quad9,opendns,adguard) or any public IPv4 address of a resolver. Defaultgoogle.
Response fields
200 with this JSON object, plus tookMs, and incomplete with warnings when a source failed. Fields marked optional appear only when they apply.
queryobjectalwaysWhat was looked up, normalised (lower case, no trailing dot, IDNs as Punycode).namestringalwaysThe name asked: lower case, IDNs as Punycode, an IP address as its in-addr.arpa or ip6.arpa name.typestringalwaysThe record type asked.one of
"A","AAAA","CNAME","MX","NS","PTR","SRV","SOA","TXT","CAA","DS","DNSKEY","HTTPS","SVCB"resolverstringalwaysThe resolver as given: a name from the list or an IPv4 address.
resolverobjectalwaysThe resolver asked.Show 4 fields
idstring or nullalwaysThe named resolver; null for another address.one of
"google","cloudflare","quad9","opendns","adguard",nullnamestring or nullalwaysIts name, e.g. "Google Public DNS"; null for another address.ipstringalwaysThe address asked.transportstringalwaystcp(port 53) ordoh(DNS over HTTPS, for Cloudflare's addresses).one of
"tcp","doh"
rcodestring or nullalwaysThe response code:NOERROR(with or without records),NXDOMAIN,SERVFAIL,REFUSED,FORMERR,NOTIMP…; null when no answer came (seewarnings).authoritativeboolean or nullalwaysThe AA flag: the answer came from a server authoritative for the name (resolvers say false). Null without an answer.dnssecValidatedboolean or nullalwaysThe AD flag: the resolver validated the answer with DNSSEC. Null without an answer.recordsarray of objectsalwaysThe answer section: the CNAMEs followed, then the records of the asked type. Empty for NXDOMAIN and for a name without that type (NOERROR, no records).Show 5 fields
namestringalwaysThe owner name, lower case, without the trailing dot.typestringalwaysThe record type (A, CNAME, MX…).ttlintegeralwaysThe TTL the resolver handed out (the time left in its cache), in seconds.valuestringalwaysThe record's data in presentation format, as dig prints it. TXT strings are joined, without quotes; names have no trailing dot.dataobjectoptionalParsed fields, for MX, SRV, SOA and CAA records only (absent for other types).Show 15 fields
priorityintegeroptionalMX, SRV: lower is tried first.exchangestringoptionalMX: the mail server's host name;.for a null MX (RFC 7505).weightintegeroptionalSRV: the share among equal priorities.portintegeroptionalSRV: the service's port.targetstringoptionalSRV: the host offering the service;.for none.mnamestringoptionalSOA: the primary nameserver.rnamestringoptionalSOA: the zone's contact mailbox, the first dot standing for @.serialintegeroptionalSOA: the zone's version number.refreshintegeroptionalSOA: seconds between secondaries' checks.retryintegeroptionalSOA: seconds before a failed check is retried.expireintegeroptionalSOA: seconds a secondary keeps serving without reaching the primary.minimumintegeroptionalSOA: the negative-caching TTL (RFC 2308), in seconds.flagsintegeroptionalCAA: 128 = critical.tagstringoptionalCAA:issue,issuewild,iodef…valuestringoptionalCAA: the tag's value, unquoted.
authorityarray of objectsalwaysThe authority section: the zone's SOA with a negative answer (its TTL is how long the miss is cached, RFC 2308).Show 5 fields
namestringalwaysThe owner name, lower case, without the trailing dot.typestringalwaysThe record type (A, CNAME, MX…).ttlintegeralwaysThe TTL the resolver handed out (the time left in its cache), in seconds.valuestringalwaysThe record's data in presentation format, as dig prints it. TXT strings are joined, without quotes; names have no trailing dot.dataobjectoptionalParsed fields, for MX, SRV, SOA and CAA records only (absent for other types).Show 15 fields
priorityintegeroptionalMX, SRV: lower is tried first.exchangestringoptionalMX: the mail server's host name;.for a null MX (RFC 7505).weightintegeroptionalSRV: the share among equal priorities.portintegeroptionalSRV: the service's port.targetstringoptionalSRV: the host offering the service;.for none.mnamestringoptionalSOA: the primary nameserver.rnamestringoptionalSOA: the zone's contact mailbox, the first dot standing for @.serialintegeroptionalSOA: the zone's version number.refreshintegeroptionalSOA: seconds between secondaries' checks.retryintegeroptionalSOA: seconds before a failed check is retried.expireintegeroptionalSOA: seconds a secondary keeps serving without reaching the primary.minimumintegeroptionalSOA: the negative-caching TTL (RFC 2308), in seconds.flagsintegeroptionalCAA: 128 = critical.tagstringoptionalCAA:issue,issuewild,iodef…valuestringoptionalCAA: the tag's value, unquoted.
Errors
422target_not_allowedresolveris a private, reserved, documentation or IPv6 address (our servers reach resolvers over IPv4 only).
Plus the errors every endpoint can return: 400 for a missing or unreadable parameter, 429 past the limit, 503 when every source failed.
Code samples
curl "https://dnsrobot.net/api/v2/dns?name=github.com"const params = new URLSearchParams({ name: "github.com" });
const res = await fetch(`https://dnsrobot.net/api/v2/dns?${params}`);
const data = await res.json();
if (!res.ok) throw new Error(data.error.message);
console.log(data.records);import requests
r = requests.get(
"https://dnsrobot.net/api/v2/dns",
params={"name": "github.com"},
timeout=30,
)
data = r.json()
if not r.ok:
raise RuntimeError(data["error"]["message"])
print(data["records"])package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
func main() {
q := url.Values{"name": {"github.com"}}
res, err := http.Get("https://dnsrobot.net/api/v2/dns?" + q.Encode())
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode != http.StatusOK {
panic(data["error"])
}
fmt.Println(data["records"])
}<?php
$query = http_build_query(["name" => "github.com"]);
$context = stream_context_create(["http" => ["ignore_errors" => true, "timeout" => 30]]);
$data = json_decode(file_get_contents("https://dnsrobot.net/api/v2/dns?" . $query, false, $context), true);
if (isset($data["error"])) {
throw new RuntimeException($data["error"]["message"]);
}
print_r($data["records"]);require "net/http"
require "json"
uri = URI("https://dnsrobot.net/api/v2/dns")
uri.query = URI.encode_www_form(name: "github.com")
data = JSON.parse(Net::HTTP.get(uri))
raise data["error"]["message"] if data["error"]
puts data["records"]// Cargo.toml: reqwest = { version = "0.13", features = ["blocking", "json"] }, serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
let res = reqwest::blocking::get("https://dnsrobot.net/api/v2/dns?name=github.com")?;
let ok = res.status().is_success();
let data: serde_json::Value = res.json()?;
if !ok {
return Err(data["error"]["message"].to_string().into());
}
println!("{}", data["records"]);
Ok(())
}using System.Text.Json;
using var http = new HttpClient();
var res = await http.GetAsync("https://dnsrobot.net/api/v2/dns?name=github.com");
var data = JsonDocument.Parse(await res.Content.ReadAsStringAsync()).RootElement;
if (!res.IsSuccessStatusCode)
throw new Exception(data.GetProperty("error").GetProperty("message").GetString());
Console.WriteLine(data.GetProperty("records"));A records of github.com from Google
GET /api/v2/dns?name=github.com{
"query": {
"name": "github.com",
"type": "A",
"resolver": "google"
},
"resolver": {
"id": "google",
"name": "Google Public DNS",
"ip": "8.8.8.8",
"transport": "tcp"
},
"rcode": "NOERROR",
"authoritative": false,
"dnssecValidated": false,
"records": [
{
"name": "github.com",
"type": "A",
"ttl": 60,
"value": "140.82.114.4"
}
],
"authority": [],
"tookMs": 48
}cloudflare.com's SOA from Cloudflare (parsed fields)
GET /api/v2/dns?name=cloudflare.com&type=SOA&resolver=cloudflare{
"query": {
"name": "cloudflare.com",
"type": "SOA",
"resolver": "cloudflare"
},
"resolver": {
"id": "cloudflare",
"name": "Cloudflare DNS",
"ip": "1.1.1.1",
"transport": "doh"
},
"rcode": "NOERROR",
"authoritative": false,
"dnssecValidated": true,
"records": [
{
"name": "cloudflare.com",
"type": "SOA",
"ttl": 300,
"value": "ns3.cloudflare.com dns.cloudflare.com 2417999975 10000 2400 604800 300",
"data": {
"mname": "ns3.cloudflare.com",
"rname": "dns.cloudflare.com",
"serial": 2417999975,
"refresh": 10000,
"retry": 2400,
"expire": 604800,
"minimum": 300
}
}
],
"authority": [],
"tookMs": 2
}The PTR of 8.8.8.8
GET /api/v2/dns?name=8.8.8.8{
"query": {
"name": "8.8.8.8.in-addr.arpa",
"type": "PTR",
"resolver": "google"
},
"resolver": {
"id": "google",
"name": "Google Public DNS",
"ip": "8.8.8.8",
"transport": "tcp"
},
"rcode": "NOERROR",
"authoritative": false,
"dnssecValidated": false,
"records": [
{
"name": "8.8.8.8.in-addr.arpa",
"type": "PTR",
"ttl": 1053,
"value": "dns.google"
}
],
"authority": [],
"tookMs": 42
}