{
  "components": {
    "schemas": {
      "Payload": {
        "properties": {
          "blocks": {
            "description": "The evidence. Each block names a display component and carries its props.",
            "items": {
              "properties": {
                "component": {
                  "type": "string"
                },
                "props": {
                  "type": "object"
                },
                "span": {
                  "type": "integer"
                }
              },
              "required": [
                "component",
                "props",
                "span"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "command": {
            "description": "The verb that ran.",
            "type": "string"
          },
          "degraded": {
            "description": "Upstreams that failed while the rest of the answer stood. Check before treating a result as complete.",
            "items": {
              "properties": {
                "reason": {
                  "type": "string"
                },
                "source": {
                  "type": "string"
                }
              },
              "required": [
                "source",
                "reason"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "elapsed_ms": {
            "type": "integer"
          },
          "notes": {
            "description": "Provenance and limits.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "target": {
            "description": "What it ran against, normalised.",
            "type": "string"
          },
          "ts": {
            "description": "When the answer was produced, unix milliseconds.",
            "type": "integer"
          },
          "ttl": {
            "description": "Seconds this answer stays valid.",
            "type": "integer"
          },
          "upstream_queries": {
            "description": "How many lookups it cost.",
            "type": "integer"
          },
          "verdict": {
            "description": "The answer in one sentence. Read this first.",
            "properties": {
              "detail": {
                "type": "string"
              },
              "headline": {
                "type": "string"
              },
              "state": {
                "enum": [
                  "ok",
                  "warn",
                  "none"
                ],
                "type": "string"
              }
            },
            "required": [
              "state",
              "headline",
              "detail"
            ],
            "type": "object"
          }
        },
        "required": [
          "command",
          "target",
          "verdict",
          "blocks",
          "notes",
          "degraded",
          "ts",
          "ttl",
          "elapsed_ms",
          "upstream_queries"
        ],
        "type": "object"
      }
    }
  },
  "info": {
    "description": "Every answer is a fresh lookup. Nothing is precomputed and nothing is stored between requests. Reads are open: no key, no signup. An upstream failure returns 200 with the failure named in `degraded` and the rest of the answer intact.",
    "summary": "Live domain and network diagnostics",
    "title": "dug",
    "version": "1"
  },
  "openapi": "3.1.0",
  "paths": {
    "/asn/{target}": {
      "get": {
        "description": "prefixes and address space. Example: ASN 13335",
        "operationId": "asn",
        "parameters": [
          {
            "description": "an as number, with or without the AS prefix",
            "example": "13335",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "prefixes and address space",
        "tags": [
          "addressing"
        ]
      }
    },
    "/dig/{target}": {
      "get": {
        "description": "every record type, or just one. Example: DIG example.com MX",
        "operationId": "dig",
        "parameters": [
          {
            "description": "a domain name",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "a single record type to ask for, such as MX",
            "example": "MX",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "every record type, or just one",
        "tags": [
          "resolution"
        ]
      }
    },
    "/dnssec/{target}": {
      "get": {
        "description": "chain of trust, ds and dnskey. Example: DNSSEC cloudflare.com",
        "operationId": "dnssec",
        "parameters": [
          {
            "description": "a domain name",
            "example": "cloudflare.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "chain of trust, ds and dnskey",
        "tags": [
          "delegation"
        ]
      }
    },
    "/http/{target}": {
      "get": {
        "description": "headers, redirect chain, security headers. Example: HTTP example.com",
        "operationId": "http",
        "parameters": [
          {
            "description": "a hostname",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "headers, redirect chain, security headers",
        "tags": [
          "transport"
        ]
      }
    },
    "/ip/{target}": {
      "get": {
        "description": "reverse dns, asn, prefix, neighbours. Example: IP 8.8.8.8",
        "operationId": "ip",
        "parameters": [
          {
            "description": "an ip address",
            "example": "8.8.8.8",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "reverse dns, asn, prefix, neighbours",
        "tags": [
          "addressing"
        ]
      }
    },
    "/mail/{target}": {
      "get": {
        "description": "mx, spf, dkim, dmarc and alignment policy. Example: MAIL example.com",
        "operationId": "mail",
        "parameters": [
          {
            "description": "a domain name",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "mx, spf, dkim, dmarc and alignment policy",
        "tags": [
          "mail"
        ]
      }
    },
    "/net/{target}/{bits}": {
      "get": {
        "description": "address space grid, a /24 or smaller. Example: NET 8.8.8.0/24",
        "operationId": "net",
        "parameters": [
          {
            "description": "a network in cidr form, a /24 or smaller",
            "example": "8.8.8.0/24",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "",
            "example": "",
            "in": "path",
            "name": "bits",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "address space grid, a /24 or smaller",
        "tags": [
          "addressing"
        ]
      }
    },
    "/ns/{target}": {
      "get": {
        "description": "root to tld to authoritative walk. Example: NS example.com",
        "operationId": "ns",
        "parameters": [
          {
            "description": "a domain name",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "root to tld to authoritative walk",
        "tags": [
          "delegation"
        ]
      }
    },
    "/ping/{target}": {
      "get": {
        "description": "icmp echo, round trip time and packet loss. Example: PING 1.1.1.1",
        "operationId": "ping",
        "parameters": [
          {
            "description": "a hostname or an ip address",
            "example": "1.1.1.1",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "how many echoes to send, 1 to 10",
            "example": "8",
            "in": "query",
            "name": "count",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "icmp echo, round trip time and packet loss",
        "tags": [
          "reachability"
        ]
      }
    },
    "/ports/{target}": {
      "get": {
        "description": "which tcp ports are open, closed or filtered. Example: PORTS scanme.nmap.org 22,80,443",
        "operationId": "ports",
        "parameters": [
          {
            "description": "a hostname or an ip address",
            "example": "scanme.nmap.org",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ports to try, comma separated, ranges allowed",
            "example": "22,80,443",
            "in": "query",
            "name": "ports",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "which tcp ports are open, closed or filtered",
        "tags": [
          "reachability"
        ]
      }
    },
    "/prop/{target}": {
      "get": {
        "description": "agreement across the fixed resolver list. Example: PROP example.com",
        "operationId": "prop",
        "parameters": [
          {
            "description": "a domain name",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "agreement across the fixed resolver list",
        "tags": [
          "resolution"
        ]
      }
    },
    "/rdap/{target}": {
      "get": {
        "description": "registration data with status codes decoded. Example: RDAP example.com",
        "operationId": "rdap",
        "parameters": [
          {
            "description": "a domain name",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "registration data with status codes decoded",
        "tags": [
          "registration"
        ]
      }
    },
    "/route/{target}": {
      "get": {
        "description": "the hops between here and there, with reverse dns. Example: ROUTE example.com",
        "operationId": "route",
        "parameters": [
          {
            "description": "a hostname or an ip address",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "the hops between here and there, with reverse dns",
        "tags": [
          "reachability"
        ]
      }
    },
    "/spf/{target}": {
      "get": {
        "description": "include tree, against the ten lookup limit. Example: SPF example.com",
        "operationId": "spf",
        "parameters": [
          {
            "description": "a domain name",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "include tree, against the ten lookup limit",
        "tags": [
          "mail"
        ]
      }
    },
    "/src": {
      "get": {
        "description": "resolver list, cache ceilings, upstream health. Example: SRC",
        "operationId": "src",
        "parameters": [
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "resolver list, cache ceilings, upstream health",
        "tags": [
          "meta"
        ]
      }
    },
    "/tls/{target}": {
      "get": {
        "description": "chain, validity spans, protocols. Example: TLS example.com",
        "operationId": "tls",
        "parameters": [
          {
            "description": "a hostname",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "chain, validity spans, protocols",
        "tags": [
          "transport"
        ]
      }
    },
    "/trace/{target}": {
      "get": {
        "description": "dns, tcp, tls and ttfb timing. Example: TRACE example.com",
        "operationId": "trace",
        "parameters": [
          {
            "description": "a hostname",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "dns, tcp, tls and ttfb timing",
        "tags": [
          "transport"
        ]
      }
    },
    "/ttl/{target}": {
      "get": {
        "description": "remaining lifetime per record. Example: TTL example.com",
        "operationId": "ttl",
        "parameters": [
          {
            "description": "a domain name",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "remaining lifetime per record",
        "tags": [
          "resolution"
        ]
      }
    },
    "/vs/{target}/{other}": {
      "get": {
        "description": "two domains side by side. Example: VS example.com github.com",
        "operationId": "vs",
        "parameters": [
          {
            "description": "a domain name, compared against `other`",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "the second domain name",
            "example": "github.com",
            "in": "path",
            "name": "other",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "two domains side by side",
        "tags": [
          "meta"
        ]
      }
    },
    "/watch/{target}": {
      "get": {
        "description": "domain and certificate expiry, computed now. Example: WATCH example.com",
        "operationId": "watch",
        "parameters": [
          {
            "description": "a domain name",
            "example": "example.com",
            "in": "path",
            "name": "target",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Force a representation. Without it, text for terminal clients and JSON for everything else.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "text",
                "json"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payload"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "The answer, and the evidence for it."
          }
        },
        "summary": "domain and certificate expiry, computed now",
        "tags": [
          "registration"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://dug.sh"
    }
  ]
}