{
  "openapi": "3.1.0",
  "info": {
    "title": "is it DNS? API",
    "version": "2026-09-10",
    "summary": "Live DNS from isitdns.net: a dig tool over the public resolvers, a domain audit, a delegation walk, and the resolver board with its history.",
    "description": "Free, no key, no account. Every reading carries the time it was read and is taken from the isitdns seat, never from your network. Rate limit: 100 a minute per address, on every route that asks a real server and on every MCP tool call. The same tools, plus the top-100 domain board and the outage feed, are served over the Model Context Protocol at https://isitdns.net/mcp (Streamable HTTP, stateless). Text form for terminals: GET / , /dig/<name>[/<type>][/<resolver>], /check/<domain>, /<domain>, /<resolver>, /top100 with a curl user agent or Accept: text/plain.",
    "contact": {
      "url": "https://isitdns.net/agents"
    }
  },
  "servers": [
    {
      "url": "https://isitdns.net"
    }
  ],
  "x-mcp": {
    "endpoint": "https://isitdns.net/mcp",
    "transport": "streamable-http",
    "tools": [
      "dig",
      "check_domain",
      "trace",
      "resolver_status",
      "resolver_history",
      "top_domains",
      "dns_events",
      "ksk_board"
    ]
  },
  "paths": {
    "/api/query": {
      "get": {
        "operationId": "dig",
        "summary": "Ask a public resolver, or any public address, for a record",
        "description": "The dig tool. JSON by default; with a curl user agent or Accept: text/plain the answer comes back in the shape dig prints.",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "example.com"
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "A"
            },
            "description": "A, AAAA, MX, TXT, NS, SOA, CNAME, DS, DNSKEY, CAA, SRV, HTTPS, SVCB, PTR, or TYPE<n>"
          },
          {
            "name": "resolver",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "cloudflare"
            },
            "description": "A board resolver id (cloudflare, google, quad9, opendns, adguard, ...), a registry alias (8.8.8.8, dns.google), \"all\" for every public resolver side by side, or any public IP address"
          },
          {
            "name": "ip",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Explicit custom targets, comma separated, up to 6 public addresses. Wins over resolver."
          },
          {
            "name": "transport",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "doh",
                "dot",
                "tcp53"
              ],
              "default": "doh"
            }
          },
          {
            "name": "dnssec",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "Set DO and read AD; dnssec=0 turns it off"
          },
          {
            "name": "cd",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Checking disabled"
          },
          {
            "name": "ecs",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "EDNS Client Subnet, CIDR, e.g. 192.0.2.0/24"
          },
          {
            "name": "norec",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Clear RD, like dig +norec"
          },
          {
            "name": "nsid",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "family",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "v4",
                "v6",
                "both"
              ],
              "default": "v4"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The answer from each resolver asked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryResult"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The name, type, transport or an address did not validate",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited"
          }
        }
      },
      "post": {
        "operationId": "digPost",
        "summary": "The same query as a JSON body",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "See GET",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryResult"
                }
              }
            }
          }
        }
      }
    },
    "/api/check": {
      "post": {
        "operationId": "checkDomain",
        "summary": "The five-check DNS audit for a domain",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Score, grade and each check explained",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckResult"
                }
              }
            }
          }
        }
      }
    },
    "/api/trace": {
      "post": {
        "operationId": "trace",
        "summary": "Walk the delegation from the root, like dig +trace",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "default": "A"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Every hop, root to authority, with the final answer",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/status": {
      "get": {
        "operationId": "resolverStatus",
        "summary": "The live board: every public resolver's latest reading",
        "description": "Read every 3 minutes over DoT from the isitdns seat. updatedAt is when the newest reading was taken; a reading older than five minutes is a record, not a reading.",
        "responses": {
          "200": {
            "description": "The board",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusPayload"
                }
              }
            }
          }
        }
      }
    },
    "/api/endpoint": {
      "get": {
        "operationId": "resolverCard",
        "summary": "One resolver's card: its addresses, uptime, latency percentiles and incident record",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "cloudflare"
          }
        ],
        "responses": {
          "200": {
            "description": "The card",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/history": {
      "get": {
        "operationId": "resolverHistory",
        "summary": "Incidents logged against the public resolvers",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Limit to one resolver id"
          },
          {
            "name": "all",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Include short degraded runs"
          }
        ],
        "responses": {
          "200": {
            "description": "The incidents",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "generatedAt": {
                      "type": "string"
                    },
                    "incidents": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Incident"
                      }
                    },
                    "probingLive": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/ksk": {
      "get": {
        "operationId": "kskBoard",
        "summary": "The RFC 8509 root KSK sentinel across the public resolvers",
        "responses": {
          "200": {
            "description": "The board",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "operationId": "mcp",
        "summary": "The Model Context Protocol endpoint (JSON-RPC 2.0 over Streamable HTTP, stateless)",
        "description": "Tools: dig, check_domain, trace, resolver_status, resolver_history, top_domains, dns_events, ksk_board. Add https://isitdns.net/mcp to an MCP client; no key.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One JSON-RPC response"
          },
          "202": {
            "description": "A notification or response was accepted"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "QueryBody": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "default": "A"
          },
          "resolver": {
            "type": "string",
            "default": "cloudflare",
            "description": "A board id, \"all\", or \"custom\" with customIps"
          },
          "customIps": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 6
          },
          "transport": {
            "type": "string",
            "enum": [
              "doh",
              "dot",
              "tcp53"
            ],
            "default": "doh"
          },
          "dnssec": {
            "type": "boolean",
            "default": true
          },
          "cd": {
            "type": "boolean",
            "default": false
          },
          "ecs": {
            "type": "string"
          },
          "noRecurse": {
            "type": "boolean",
            "default": false
          },
          "nsid": {
            "type": "boolean",
            "default": false
          },
          "ipFamily": {
            "type": "string",
            "enum": [
              "v4",
              "v6",
              "both"
            ],
            "default": "v4"
          }
        }
      },
      "RR": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "integer"
          },
          "typeName": {
            "type": "string"
          },
          "class": {
            "type": "integer"
          },
          "ttl": {
            "type": "integer"
          },
          "data": {
            "type": "string",
            "description": "dig-style rendering of the record data"
          }
        }
      },
      "DnsResponse": {
        "type": "object",
        "properties": {
          "rcode": {
            "type": "integer"
          },
          "rcodeName": {
            "type": "string"
          },
          "qr": {
            "type": "boolean"
          },
          "aa": {
            "type": "boolean"
          },
          "tc": {
            "type": "boolean"
          },
          "rd": {
            "type": "boolean"
          },
          "ra": {
            "type": "boolean"
          },
          "ad": {
            "type": "boolean"
          },
          "cd": {
            "type": "boolean"
          },
          "question": {
            "type": "object"
          },
          "answer": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RR"
            }
          },
          "authority": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RR"
            }
          },
          "additional": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RR"
            }
          },
          "ede": {
            "type": "array",
            "description": "Extended DNS Errors (RFC 8914), present only when the server sent them"
          },
          "nsid": {
            "type": "string"
          }
        }
      },
      "RunResult": {
        "type": "object",
        "properties": {
          "resolver": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "ips": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "latencyMs": {
            "type": "number"
          },
          "ipUsed": {
            "type": "string"
          },
          "response": {
            "$ref": "#/components/schemas/DnsResponse"
          },
          "error": {
            "type": "string"
          },
          "skipped": {
            "type": "boolean"
          },
          "skippedReason": {
            "type": "string"
          }
        }
      },
      "QueryResult": {
        "type": "object",
        "properties": {
          "query": {
            "type": "object",
            "description": "The question as asked, after validation"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RunResult"
            }
          },
          "omitted": {
            "type": "array",
            "description": "Board rows this transport could not reach, named rather than dropped",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "reason": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "CheckResult": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string"
          },
          "generatedAt": {
            "type": "string"
          },
          "grade": {
            "type": "string"
          },
          "score": {
            "type": "integer"
          },
          "summary": {
            "type": "object"
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "cappedBy": {
            "type": "string"
          }
        }
      },
      "Incident": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "resolverId": {
            "type": "string"
          },
          "resolverName": {
            "type": "string"
          },
          "startedAt": {
            "type": "string"
          },
          "endedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "severity": {
            "type": "string",
            "enum": [
              "warn",
              "bad"
            ]
          },
          "durationMs": {
            "type": "integer"
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "StatusPayload": {
        "type": "object",
        "properties": {
          "updatedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "vantage": {
            "type": "object"
          },
          "resolvers": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      }
    }
  }
}
