DNS Inspector API

Base URL: https://dns.netray.info

Multi-resolver DNS debugger with six modes: query, check, trace, compare, auth compare, and DNSSEC validation. Results stream via Server-Sent Events or can be returned as a single JSON response.

See also: interactive API reference (auto-generated OpenAPI)

Query Language

All endpoints accept a query field using a dig-inspired syntax:

domain [TYPE...] [@server...] [+flag...]
ComponentDescriptionExamples
Domain Target domain (required) example.com
Types Record types to query (default: A) A AAAA MX NS TXT CNAME SOA SRV CAA TLSA HTTPS
Servers DNS servers to use @1.1.1.1, @cloudflare, @google, @quad9, @public, @all
Flags Mode and behavior flags +check, +trace, +compare, +auth, +dnssec, +norecurse, +short
# Query A and MX records via Cloudflare and Google
example.com A MX @cloudflare @google

# Run a health check
example.com +check

# Trace delegation chain for AAAA
example.com AAAA +trace

Streaming vs JSON

By default, all query endpoints return Server-Sent Events (SSE). Add ?stream=false to get a single JSON response instead.

SSE mode (default)

Events stream as they arrive. Use --no-buffer with curl:

curl -s -N -X POST https://dns.netray.info/api/query \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com A @cloudflare"}' \
  --no-buffer

SSE event types:

EventDescription
batchA batch of results (one or more records)
doneStream complete
errorAn error occurred

Raw SSE output looks like:

event: batch
data: {"records": [{"name": "example.com", "type": "A", "ttl": 300, "data": "93.184.215.14", ...}]}

event: done
data: {"key": "abc123"}

JSON mode (?stream=false)

Waits for all results and returns a single JSON object:

curl -s -X POST 'https://dns.netray.info/api/query?stream=false' \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com A MX"}' | jq .
{
  "events": [
    {"type": "batch", "data": {"records": [...]}},
    ...
  ],
  "truncated": false
}

Endpoints

POST /api/query -- DNS Query

Standard DNS lookup. Fan-out across record types and servers.

# A records from default resolver
curl -s -X POST 'https://dns.netray.info/api/query?stream=false' \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com A"}' | jq .
# MX and TXT from all public resolvers
curl -s -X POST 'https://dns.netray.info/api/query?stream=false' \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com MX TXT @public"}' | jq .

POST /api/check -- Domain Health Check

Comprehensive domain health analysis: SPF, DKIM, DMARC, MTA-STS, TLSRPT, BIMI, DANE, nameserver consistency, and more.

curl -s -X POST 'https://dns.netray.info/api/check?stream=false' \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com"}' | jq .

POST /api/trace -- Delegation Trace

Walk the delegation chain from root to authoritative nameservers.

curl -s -X POST 'https://dns.netray.info/api/trace?stream=false' \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com"}' | jq .

POST /api/dnssec -- DNSSEC Validation

Validate the full DNSSEC chain of trust from root to domain.

curl -s -X POST 'https://dns.netray.info/api/dnssec?stream=false' \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com"}' | jq .

POST /api/compare -- Transport Comparison

Compare results across different DNS transports (UDP, TCP, DoT, DoH).

curl -s -X POST 'https://dns.netray.info/api/compare?stream=false' \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com A"}' | jq .

POST /api/authcompare -- Authoritative vs Recursive

Compare authoritative nameserver responses against recursive resolver responses.

curl -s -X POST 'https://dns.netray.info/api/authcompare?stream=false' \
  -H 'Content-Type: application/json' \
  -d '{"query": "example.com A"}' | jq .

Utility Endpoints

POST /api/parse -- Query Parser

Parse a query string and get completions. Useful for building UIs.

curl -s -X POST https://dns.netray.info/api/parse \
  -H 'Content-Type: application/json' \
  -d '{"query": "example"}' | jq .

GET /api/results/{key} -- Cached Results

Retrieve a cached result by its permalink key (returned in the done SSE event).

curl -s https://dns.netray.info/api/results/abc123 | jq .

GET /api/servers -- Available DNS Servers

List all available DNS servers and their aliases.

curl -s https://dns.netray.info/api/servers | jq .

GET /api/record-types -- Supported Record Types

List all supported DNS record types.

curl -s https://dns.netray.info/api/record-types | jq .

GET /api/config -- Client Configuration

Server-side configuration relevant to API clients.

curl -s https://dns.netray.info/api/config | jq .

Rate Limits

Three-tier GCRA rate limiting: per-IP, per-target domain, and global. The cost of a request is calculated as:

cost = number_of_record_types * number_of_servers

For example, querying example.com A MX @cloudflare @google costs 4 (2 types x 2 servers).

When rate-limited, you receive a 429 with a Retry-After header.

Errors

Standard error envelope:

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Retry after 5 seconds."
  }
}

In SSE mode, errors arrive as an error event:

event: error
data: {"error": {"code": "bad_request", "message": "Invalid query syntax"}}