DNS Lookup API

DNS records for a domain (A, AAAA, MX, TXT, NS, CNAME, SOA, CAA) with their TTLs.

Endpoint
POST /v1/dns-lookup
Price
free
Family
Domain, DNS & network

01When to use it

  • A DNS query needs the network, so an agent cannot answer it on its own. It is what you run in a loop over a list of domains.

When not to use it

  • The destination needs more than 5 s to answer: the call ends with upstream_timeout (424).

02Parameters

FieldTypeRequiredDescription
domainstringyesFully qualified domain name to resolve, up to 253 characters; it is trimmed, lowercased and stripped of trailing dots, and IP literals, single-label names and private suffixes such as .local or .internal are refused.
typesarraynoRecord types to query, from a, aaaa, mx, txt, ns, cname, soa and caa in either case; duplicates collapse to one query per type, answers come back in that fixed order, and the default is all eight.

03Limits

LimitValue
Size cap2 MB (2,097,152 bytes)
Timeout5 s

04Example

The published example of dns-lookup, verbatim: the request body and the response it returns.

Request
POST /v1/dns-lookup
content-type: application/json

{
  "domain": "example.com",
  "types": [
    "a",
    "mx"
  ]
}
Response
200 OK

{
  "domain": "example.com",
  "types_requested": [
    "a",
    "mx"
  ],
  "records": [
    {
      "type": "a",
      "values": [
        {
          "address": "93.184.215.14",
          "ttl": 3600
        }
      ],
      "truncated": false,
      "resolution_error": null
    },
    {
      "type": "mx",
      "values": [
        {
          "exchange": "mail.example.com",
          "priority": 10
        }
      ],
      "truncated": false,
      "resolution_error": null
    }
  ],
  "queried_at": "2026-08-26T18:00:00.000Z"
}

This example is illustrative: it shows the exact shape the handler returns, but it was not produced by a reproducible call, because the real answer depends on live network data that changes over time.

Response fieldTypeIn the example
domainstring"example.com"
types_requestedarray2 items
recordsarray2 items, each with type, values, truncated and resolution_error
queried_atstring"2026-08-26T18:00:00.000Z"

05Call it from code

JavaScript
// dns-lookup: free, no payment needed
// Save as client.mjs (ES module, Node 18+) and run: node client.mjs

const body = {
  "domain": "example.com",
  "types": [
    "a",
    "mx"
  ]
}

const res = await fetch('https://grist.tools/v1/dns-lookup', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify(body),
})
console.log(res.status, await res.json())
Python
# dns-lookup: free, no payment needed
# Install: pip install requests
import requests

payload = {
    "domain": "example.com",
    "types": [
        "a",
        "mx"
    ]
}

res = requests.post("https://grist.tools/v1/dns-lookup", json=payload)
print(res.status_code, res.json())
curl
# dns-lookup: free, no payment needed
curl -X POST 'https://grist.tools/v1/dns-lookup' -H 'content-type: application/json' -d '{"domain":"example.com","types":["a","mx"]}'

06Errors

CodeHTTPFor this service
invalid_input400The body does not match the schema; its fields are domain and types.
unreachable_target424
upstream_timeout424

When each code is raised, and what it means for payment: /docs/dns-lookup.

07Questions

How much does a dns-lookup call cost?
Nothing: dns-lookup is free to call, without a payment header, an account or an API key.
What does dns-lookup return?
A JSON object with 4 top-level fields: domain, types_requested, records and queried_at. The example on this page is illustrative, not a recorded call.
What happens when a dns-lookup call fails?
The tool answers with a typed JSON error from the errors table. Busy answers (429, 503) carry a retry-after header.