Skip to content

A DNS zone is a short list of records, and each type answers a different question. Where's the website? Who takes the mail? Who's allowed to issue a certificate? This page goes through the ten types the DNS Lookup API can query, with a real answer for each, so you know what you're looking at when one shows up.

Every call on this page has the same shape:

curl -G "https://apixies.io/api/v1/dns-lookup" \
     -H "X-API-Key: YOUR_API_KEY" \
     --data-urlencode "domain=github.com" \
     --data-urlencode "type=A"

Only domain and type change, so from here on I'll show the two values and the records that came back. Each record also has a ttl, the seconds left on it in the resolver's cache. I've left it out of most examples.

A: where the site lives

An A record maps a name to an IPv4 address. It's what a browser asks for first.

github.com, A:

{ "type": "A", "host": "github.com", "ip": "140.82.121.3" }

Big sites return several. google.com gave me six addresses, and clients pick one. Look at A records when you want to know if a domain points at your server yet, or where it pointed before a migration.

AAAA: the same, for IPv6

cloudflare.com, AAAA:

{ "type": "AAAA", "host": "cloudflare.com", "ipv6": "2606:4700::6810:84e5" },
{ "type": "AAAA", "host": "cloudflare.com", "ipv6": "2606:4700::6810:85e5" }

Note the field is ipv6, not ip. No AAAA records just means the site is IPv4 only. github.com still is.

CNAME: this name is really that name

A CNAME says "don't look here, look over there". It's how a subdomain gets pointed at a CDN or a hosted service.

www.githubstatus.com, CNAME:

{ "type": "CNAME", "host": "www.githubstatus.com", "target": "kctbh9vrtdwd.stspg-customer.com" }

GitHub's status page is hosted by Statuspage, and that's the record that says so.

Two things worth knowing. A CNAME can't sit on the bare domain (github.com has none), only on subdomains. And when you ask for the A record of an alias, you get the CNAME and the address it leads to in the same answer:

{ "type": "CNAME", "host": "www.github.com", "target": "github.com" },
{ "type": "A", "host": "github.com", "ip": "140.82.121.4" }

MX: who takes the mail

gmail.com, MX:

{ "type": "MX", "host": "gmail.com", "priority": 5, "target": "gmail-smtp-in.l.google.com" },
{ "type": "MX", "host": "gmail.com", "priority": 10, "target": "alt1.gmail-smtp-in.l.google.com" },
{ "type": "MX", "host": "gmail.com", "priority": 20, "target": "alt2.gmail-smtp-in.l.google.com" }

(There are five. I've cut two.) Senders try the lowest priority first, and that's the order they come back in.

No MX records means the domain can't get mail. One MX with an empty target, like example.com has, means the owner is saying so on purpose. The MX records guide turns that into a signup check.

TXT: notes for machines

TXT records hold free text. Nobody reads them by hand. Other services look for a line they recognise.

gmail.com, TXT:

{ "type": "TXT", "host": "gmail.com", "txt": "v=spf1 redirect=_spf.google.com" },
{ "type": "TXT", "host": "gmail.com", "txt": "globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8=" },
{ "type": "TXT", "host": "gmail.com", "txt": "yahoo-verification-key=dKYwfVbaxatmcXiXy6LDAxMRirqpOq5tj98iJv9qWVk=" }

What you'll usually find:

  • v=spf1 ... is SPF, the list of servers allowed to send mail for the domain
  • something-verification=... is proof of ownership for some service. google.com has 17 TXT records, and most of them are these: Docusign, Facebook, Apple, Cisco, Microsoft. You can read a company's vendor list off its DNS.
  • DKIM keys and DMARC policies are TXT too, but they live on names like _dmarc.gmail.com

Look that name up with type=TXT and you get the policy: v=DMARC1; p=none; sp=quarantine; rua=mailto:mailauth-reports@google.com. If you want SPF, DKIM and DMARC checked and explained, the email authentication endpoint does all three in one call.

NS: who answers for this domain

cloudflare.com, NS:

{ "type": "NS", "host": "cloudflare.com", "target": "ns3.cloudflare.com" },
{ "type": "NS", "host": "cloudflare.com", "target": "ns4.cloudflare.com" },
{ "type": "NS", "host": "cloudflare.com", "target": "ns5.cloudflare.com" }

(Five in total.) NS records name the servers that hold the real zone. They tell you which DNS provider a domain uses, and after moving providers they're the first thing to check. github.com lists eight, four at NS1 and four at AWS, so one provider going down doesn't take them offline.

SOA: the zone's own header

There's one SOA record per zone. It's bookkeeping.

google.com, SOA:

{
  "type": "SOA", "host": "google.com",
  "mname": "ns1.google.com", "rname": "dns-admin.google.com",
  "serial": 983759398, "refresh": 900, "retry": 900, "expire": 1800, "minimum_ttl": 60
}

mname is the primary nameserver. rname is the admin's email address with the @ written as a dot, so that one is dns-admin@google.com. serial goes up whenever the zone changes. If you're wondering whether your DNS edit was published, look it up before and after and compare. minimum_ttl is how long resolvers remember that a name doesn't exist, which is why a record you've just created can stay invisible for a while.

CAA: who may issue certificates

google.com, CAA:

{ "type": "CAA", "host": "google.com", "flags": 0, "tag": "issue", "value": "pki.goog" }

Only Google's own certificate authority may issue certificates for google.com. Every other CA has to refuse. Most domains have no CAA record, which means any CA may issue. Check it when a certificate order fails for no clear reason: a leftover CAA record naming your old CA is a common cause.

PTR: from address back to name

PTR is the reverse of an A record. The name you look up is the IP address backwards with .in-addr.arpa on the end, so 8.8.8.8 (easy one) becomes:

8.8.8.8.in-addr.arpa, PTR:

{ "type": "PTR", "host": "8.8.8.8.in-addr.arpa", "target": "dns.google" }

For GitHub's 140.82.121.3 you look up 3.121.82.140.in-addr.arpa, and get lb-140-82-121-3-fra.github.com. A load balancer in Frankfurt, going by the name.

Mail servers care about PTR records. Many refuse mail from an address with no PTR record, or one that doesn't match the name the server gives. It's also how you find out who a strange address in your logs belongs to.

SRV: where a service listens

SRV records say "this service runs on that host and port". They're used by SIP, XMPP, LDAP and Minecraft, among others, and they carry priority, weight, port and target.

The name is built from the service and the protocol, both with an underscore in front. Gmail publishes where its IMAP server is under _imaps._tcp.gmail.com:

{ "type": "SRV", "host": "_imaps._tcp.gmail.com", "priority": 5, "weight": 0, "port": 993, "target": "imap.gmail.com" }

Mail clients read that to set themselves up.

All at once

Leave type out and you get A, AAAA, MX, TXT, NS and CNAME in one request. For google.com that was 32 records: 6 A, 4 AAAA, 1 MX, 17 TXT, 4 NS. SOA, CAA, SRV and PTR are only returned when you ask for them by name.

So a full picture of a domain is three requests, not ten:

import os
import requests
from collections import Counter

def records(domain, record_type=None):
    params = {"domain": domain}
    if record_type:
        params["type"] = record_type

    res = requests.get(
        "https://apixies.io/api/v1/dns-lookup",
        params=params,
        headers={"X-API-Key": os.environ["APIXIES_API_KEY"]},
        timeout=15,
    )
    body = res.json()
    if body["status"] != "success":
        raise RuntimeError(f"{body['code']}: {body['message']}")
    if body["data"]["partial"]:
        print("timed out:", [t for t, late in body["data"]["timed_out"].items() if late])
    return body["data"]["records"]

domain = "google.com"
found = records(domain) + records(domain, "SOA") + records(domain, "CAA")

for record_type, count in Counter(r["type"] for r in found).items():
    print(f"{record_type:5} {count}")
A     6
AAAA  4
MX    1
TXT   17
NS    4
SOA   1
CAA   1

That matters with 75 requests a day on the free tier. Three per domain lets you audit 25 domains. Ten per domain gets you seven.

Next steps

Try the DNS Lookup API

Free tier is for development & small projects. 75 requests/day with a registered account.

cookies

We use analytics cookies to see how the site gets used. Nothing loads until you accept. Privacy policy