{
  "openapi": "3.0.3",
  "info": {
    "title": "tttx.net Network Census API",
    "version": "1.0.0",
    "description": "Free IPv4 network-census API. Look up any host, or search the corpus with the same query language the site uses. Get a key at https://tttx.net/signup.php (1,000 requests/day). Human docs: https://tttx.net/docs.php",
    "contact": { "name": "tttx abuse/support", "email": "abuse@tttx.net" }
  },
  "servers": [ { "url": "https://tttx.net", "description": "Production" } ],
  "tags": [
    { "name": "lookup", "description": "Single-host lookup" },
    { "name": "search", "description": "Corpus search" },
    { "name": "public", "description": "Keyless endpoints" }
  ],
  "security": [ { "ApiKeyHeader": [] }, { "ApiKeyQuery": [] } ],
  "paths": {
    "/api/v1/host": {
      "get": {
        "tags": [ "lookup" ],
        "summary": "All services on one IPv4 host",
        "operationId": "getHost",
        "parameters": [
          { "name": "ip", "in": "query", "required": true, "schema": { "type": "string", "format": "ipv4" },
            "example": "154.59.103.7", "description": "IPv4 address to look up." }
        ],
        "responses": {
          "200": { "description": "Host record (found may be false).",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HostResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/QuotaExceeded" }
        }
      }
    },
    "/api/v1/search": {
      "get": {
        "tags": [ "search" ],
        "summary": "Search hosts by query",
        "operationId": "searchHosts",
        "parameters": [
          { "$ref": "#/components/parameters/Query" },
          { "name": "page", "in": "query", "required": false,
            "schema": { "type": "integer", "minimum": 0, "maximum": 100, "default": 0 },
            "description": "Zero-based page; 20 hosts per page." }
        ],
        "responses": {
          "200": { "description": "Matching hosts (collapsed by IP).",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchResponse" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/QuotaExceeded" }
        }
      }
    },
    "/api/stats": {
      "get": {
        "tags": [ "public" ],
        "summary": "Corpus totals and top ports/products",
        "operationId": "getStats",
        "security": [],
        "responses": {
          "200": { "description": "Aggregate stats.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StatsResponse" } } } }
        }
      }
    },
    "/api/ownership": {
      "get": {
        "tags": [ "public" ],
        "summary": "IPv4 ownership by ASN (owners), or subnets for one ASN",
        "operationId": "getOwnership",
        "security": [],
        "parameters": [
          { "name": "q", "in": "query", "required": false, "schema": { "type": "string" },
            "description": "Optional filter (same query language; e.g. country:US, org:Comcast)." },
          { "name": "asn", "in": "query", "required": false, "schema": { "type": "integer" },
            "description": "If set, return the subnets announced by this ASN instead of the owner list." },
          { "name": "limit", "in": "query", "required": false,
            "schema": { "type": "integer", "minimum": 10, "maximum": 500, "default": 200 },
            "description": "Max owners returned (owner-list mode)." }
        ],
        "responses": {
          "200": { "description": "Owner list or subnet breakdown (see mode).",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OwnershipResponse" } } } }
        }
      }
    },
    "/api/openapi.json": {
      "get": {
        "tags": [ "public" ],
        "summary": "This OpenAPI document",
        "operationId": "getOpenapi",
        "security": [],
        "responses": { "200": { "description": "OpenAPI 3.0 spec (JSON).",
          "content": { "application/json": {} } } }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": { "type": "apiKey", "in": "header", "name": "X-API-Key",
        "description": "Preferred. Your key from /signup.php." },
      "ApiKeyQuery": { "type": "apiKey", "in": "query", "name": "key",
        "description": "Alternative to the header: ?key=YOUR_KEY." }
    },
    "parameters": {
      "Query": {
        "name": "q", "in": "query", "required": false,
        "schema": { "type": "string" },
        "example": "product:nginx port:443 country:US",
        "description": "Space-separated tokens (AND at the service level). `key:value` tokens filter; bare words are full-text; a bare IP/CIDR filters by address. See x-tttx-filters for the full filter list.",
        "x-tttx-filters": [
          { "name": "ip", "type": "ip|cidr|prefix", "example": "ip:1.0.0.0/24", "description": "Exact IP, CIDR, or dotted prefix." },
          { "name": "port", "type": "port|list|range", "example": "port:80,443,8000-8100", "description": "Host has the port open. Comma = any (OR); a-b = range." },
          { "name": "ports_all", "type": "list", "example": "ports_all:22,443", "description": "Host has ALL listed ports open (AND). Capped at 10,000 hosts." },
          { "name": "product", "type": "keyword", "example": "product:nginx", "description": "Identified service product (exact)." },
          { "name": "country", "type": "iso2", "example": "country:US", "description": "RIR-authoritative country code." },
          { "name": "asn", "type": "int", "example": "asn:7018", "description": "Autonomous system number (AS prefix optional)." },
          { "name": "org", "type": "text", "example": "org:Comcast", "description": "AS organization name (text match)." },
          { "name": "owner", "type": "text", "example": "owner:Cogent", "description": "RIR registrant (substring, case-insensitive)." },
          { "name": "hostname", "type": "text", "example": "hostname:example.com", "description": "TLS cert CN/SAN and text." },
          { "name": "status", "type": "int", "example": "status:200", "description": "HTTP response status code." },
          { "name": "has_ssl", "type": "bool", "example": "has_ssl:true", "description": "TLS enabled." },
          { "name": "expired", "type": "bool", "example": "expired:true", "description": "Expired TLS certificate." },
          { "name": "self_signed", "type": "bool", "example": "self_signed:true", "description": "Self-signed certificate." },
          { "name": "cve", "type": "cve-id", "example": "cve:CVE-2021-41773", "description": "A specific CVE is present." },
          { "name": "has_vuln", "type": "bool", "example": "has_vuln:true", "description": "Any known CVE present." },
          { "name": "cvss", "type": "compare", "example": "cvss:>=9", "description": "Max CVSS of any CVE. Operators > >= < <= (none = >=)." },
          { "name": "latency", "type": "compare", "example": "latency:<20", "description": "TCP-handshake RTT in ms. Operators > >= < <= (bare number = at most)." },
          { "name": "tag", "type": "keyword", "example": "tag:wordpress", "description": "Derived tag (web, tls, vuln, no-auth, tarpit, wordpress, wordpress-plugin...)." },
          { "name": "app", "type": "keyword", "example": "app:WordPress", "description": "Stacked app / CMS product, e.g. app:WordPress or app:wp-plugin:woocommerce." },
          { "name": "plugin", "type": "keyword", "example": "plugin:elementor", "description": "WordPress plugin by slug (shorthand for app:wp-plugin:<slug>)." },
          { "name": "exposure", "type": "keyword", "example": "exposure:open-redis", "description": "A specific no-auth exposure." },
          { "name": "no_auth", "type": "bool", "example": "no_auth:true", "description": "Any no-auth / anonymous exposure." }
        ]
      }
    },
    "responses": {
      "BadRequest": { "description": "Invalid parameter.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Missing, malformed, or revoked API key.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "QuotaExceeded": { "description": "Daily quota exceeded (1,000/day).",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    },
    "schemas": {
      "Error": { "type": "object", "properties": {
        "error": { "type": "string" }, "daily_quota": { "type": "integer" } }, "required": [ "error" ] },
      "Vuln": { "type": "object", "properties": {
        "cve": { "type": "string", "example": "CVE-2021-41773" },
        "cvss": { "type": "number", "format": "float", "example": 7.5 } } },
      "Location": { "type": "object", "properties": {
        "country": { "type": "string" }, "country_code": { "type": "string" },
        "city": { "type": "string" }, "continent": { "type": "string" },
        "rir": { "type": "string" },
        "coordinates": { "type": "object", "properties": {
          "lat": { "type": "number" }, "lon": { "type": "number" } } } } },
      "AutonomousSystem": { "type": "object", "properties": {
        "asn": { "type": "integer" }, "name": { "type": "string" },
        "bgp_prefix": { "type": "string" }, "description": { "type": "string" } } },
      "Service": { "type": "object", "properties": {
        "port": { "type": "integer" }, "transport": { "type": "string", "example": "tcp" },
        "service": { "type": "object", "properties": {
          "name": { "type": "string" }, "product": { "type": "string" }, "version": { "type": "string" } } },
        "http": { "type": "object", "nullable": true },
        "tls": { "type": "object", "nullable": true },
        "ssh": { "type": "object", "nullable": true },
        "vulns": { "type": "array", "items": { "$ref": "#/components/schemas/Vuln" } },
        "exposures": { "type": "array", "items": { "type": "string" } },
        "last_seen": { "type": "string", "format": "date-time" } } },
      "HostResponse": { "type": "object", "properties": {
        "ip": { "type": "string" }, "found": { "type": "boolean" }, "count": { "type": "integer" },
        "services": { "type": "array", "items": { "$ref": "#/components/schemas/Service" } } } },
      "SearchRow": { "type": "object", "properties": {
        "ip": { "type": "string" },
        "ports": { "type": "array", "items": { "type": "object", "properties": {
          "port": { "type": "integer" }, "product": { "type": "string" }, "version": { "type": "string" } } } },
        "last_seen": { "type": "string", "format": "date-time" },
        "location": { "$ref": "#/components/schemas/Location" },
        "autonomous_system": { "$ref": "#/components/schemas/AutonomousSystem" } } },
      "SearchResponse": { "type": "object", "properties": {
        "query": { "type": "string" }, "page": { "type": "integer" },
        "services_matched": { "type": "integer" },
        "results": { "type": "array", "items": { "$ref": "#/components/schemas/SearchRow" } } } },
      "Facet": { "type": "object", "properties": {
        "key": {}, "count": { "type": "integer" } } },
      "StatsResponse": { "type": "object", "properties": {
        "services": { "type": "integer" }, "hosts": { "type": "integer" },
        "top_ports": { "type": "array", "items": { "$ref": "#/components/schemas/Facet" } },
        "top_products": { "type": "array", "items": { "$ref": "#/components/schemas/Facet" } } } },
      "OwnershipResponse": { "type": "object", "description": "owners mode (default) or subnets mode (asn set).",
        "properties": {
          "mode": { "type": "string", "enum": [ "owners", "subnets" ] },
          "total_asns": { "type": "integer" }, "total_hosts": { "type": "integer" },
          "total_subnets": { "type": "integer" }, "shown": { "type": "integer" },
          "owners": { "type": "array", "items": { "type": "object", "properties": {
            "asn": { "type": "integer" }, "name": { "type": "string" }, "owner": { "type": "string" },
            "country": { "type": "string" }, "cc": { "type": "string" },
            "hosts": { "type": "integer" }, "subnets": { "type": "integer" } } } },
          "asn": { "type": "integer" }, "name": { "type": "string" }, "owner": { "type": "string" },
          "subnets": { "type": "array", "items": { "type": "object", "properties": {
            "cidr": { "type": "string" }, "hosts": { "type": "integer" } } } },
          "bgp_prefixes": { "type": "array", "items": { "type": "object", "properties": {
            "cidr": { "type": "string" }, "services": { "type": "integer" } } } } } }
    }
  }
}
