---
title: "Ask a public resolver, or any public address, for a record"
method: GET
path: "/api/query"
---

# Ask a public resolver, or any public address, for a record

`GET /api/query`

## Request

- Base URL: `https://isitdns.net`
- URL: `https://isitdns.net/api/query`
- Auth: none declared

The dig tool. JSON by default; with a curl user agent or Accept: text/plain the answer comes back in the shape dig prints.

## Query parameters

- `name` string, required
- `type` string
- `resolver` string
- `ip` string
- `transport` 'doh' | 'dot' | 'tcp53' | 'udp53'
- `dnssec` boolean
- `cd` boolean
- `ecs` string
- `norec` boolean
- `nsid` boolean
- `family` 'v4' | 'v6' | 'both'
- `from` 'north-america' | 'europe'
- `follow` boolean

## Response `200`

The answer from each resolver asked

- QueryResult
  - `askedAt` string, date-time: When the question was asked, taken before the first dial (UTC, milliseconds).
  - `query` object: The question as asked, after validation
  - `results` RunResult[]
    - `resolver` object
      - `id` string
      - `name` string
      - `ips` string[]
    - `latencyMs` number: Round trip in milliseconds, measured where vantage says. A row from one of our probes carries that probe's own round trip to the resolver, not comparable with the edge rows beside it. Zero is not a measurement: it means nothing reached a resolver, which is every row carrying requestError and every row whose probe failed.
    - `vantage` object: Where this row was measured. Present on every result that was dialled, and absent only where nothing was: a skipped row and a request that could not be built carry none.
      - `seat` string: `edge` for the Cloudflare edge, or the name of the probe that asked (theoracle, thewizard).
      - `label` string: Human name of the vantage, e.g. theoracle or "the isitdns edge".
      - `place` string: Where the row was asked from: the Cloudflare location code for an edge row (e.g. DFW), else the probe's place (e.g. Phoenix); `unavailable from this vantage` or `not measured` when there is none.
    - `ipUsed` string
    - `response` DnsResponse
      - `rcode` integer
      - `rcodeName` string
      - `qr` boolean
      - `aa` boolean
      - `tc` boolean
      - `rd` boolean
      - `ra` boolean
      - `ad` boolean
      - `cd` boolean
      - `question` object
      - `answer` RR[]
        - `name` string
        - `type` integer
        - `typeName` string
        - `class` integer
        - `ttl` integer
        - `data` string: dig-style rendering of the record data
      - `authority` RR[]
        - `name` string
        - `type` integer
        - `typeName` string
        - `class` integer
        - `ttl` integer
        - `data` string: dig-style rendering of the record data
      - `additional` RR[]
        - `name` string
        - `type` integer
        - `typeName` string
        - `class` integer
        - `ttl` integer
        - `data` string: dig-style rendering of the record data
      - `ede` unknown[]: Extended DNS Errors (RFC 8914), present only when the server sent them
        - unknown
      - `nsid` string
    - `error` string
    - `skipped` boolean
    - `skippedReason` string
    - `transportUsed` 'doh' | 'dot' | 'tcp53' | 'udp53': The transport of the last attempt: the one that answered when error is absent, else the last that failed. Equal to the requested transport except with resolver=all, where a row the requested transport cannot reach is asked over one it can. Absent when nothing was dialled (see requestError).
    - `attempts` object[]: Transports tried before this answer, oldest first, each with its error; present only when one failed. With no error, the row answered on a later transport. With an error and two or more attempts, no transport tried reached the resolver from the isitdns edge; with one, only that transport was tried.
      - `transport` 'doh' | 'dot' | 'tcp53' | 'udp53'
      - `error` string
    - `requestError` boolean: The query could not be built, so no socket was opened and no transport was used. Never set alongside transportUsed or attempts: those describe dials, and there was none. A malformed ECS string is a 400, never a requestError.
    - `at` string, date-time: When this row's dial began (UTC, milliseconds); for a row nothing was dialled for, when it was refused.
  - `omitted` object[]: Board rows no transport can reach, each with why.
    - `id` string
    - `name` string
    - `reason` string
  - `agreement` object: resolver=all only: the rows that answered, grouped by rcode, answer data (RRSIG and TTL aside) and AD (groups); rows asked with no reply (noAnswer); rows not asked (notMeasured); rows that answered on another transport than the one asked (rungs, and in their id).
    - `groups` object[]
      - `ids` string[]
      - `rcode` string
      - `answer` string[]
      - `ad` boolean
    - `noAnswer` object[]: Rows asked with no reply, each with its error.
      - `id` string
      - `why` string
    - `notMeasured` object[]: Rows not asked, each with why.
      - `id` string
      - `why` string
    - `rungs` object[]: Rows that answered on another transport than the one asked: the id it carries in groups, the transport it answered on, and each transport that failed first, with its error.
      - `id` string
      - `answeredOver` string
      - `failed` object[]
        - `transport` string
        - `error` string
  - `follow` AliasChain: The CNAME chain from the asked name (follow=true only), or { error } when the walk failed.
    - `asked` string
    - `hops` object[]
      - `owner` string
      - `target` string
      - `ttl` integer
    - `end` object: How the chain ends: kind address (a, aaaa, failed, inside), no-address, failed (rcode), nxdomain, loop, too-long, inside or not-read (why), with the name it ended at
      - `kind` 'address' | 'no-address' | 'failed' | 'nxdomain' | 'loop' | 'too-long' | 'inside' | 'not-read'
      - `name` string
    - `trailingDot` string[]: Targets that read like a name written without its trailing dot
    - `server` string
    - `readAt` string, date-time
    - `reads` object[]: Every question the walk asked, in order, each with its time, rcode, answer and latency, or its error
    - `error` string

## Other responses

- `400`: The name, type, transport or an address did not validate
- `429`: Rate limited

---

[API](https://skmtc.dev/isitdns/apis/is-it-dns-api.md) · [All operations](https://skmtc.dev/isitdns/apis/is-it-dns-api/llms.txt) · [OpenAPI document](https://skmtc.dev/isitdns/apis/is-it-dns-api/revisions/d5257837c67b?raw)
