{
  "request_status": "success",
  "message": "API documentation retrieved successfully",
  "data": {
    "api_info": {
      "name": "WHOIS Query API",
      "version": "v1",
      "description": "A comprehensive WHOIS and domain history API service that provides structured domain information, raw WHOIS data, historical tracking capabilities, and TLD metadata from IANA.",
      "base_url": "https://whois.datasourceapi.com",
      "documentation_url": "https://whois.datasourceapi.com/api/v1/docs",
      "features": [
        "Domain WHOIS lookups for 1500+ TLDs",
        "IP address WHOIS lookups (IPv4 and IPv6)",
        "ASN lookups via RDAP (format: AS followed by number, e.g., AS13335)",
        "TLD metadata from IANA registry (organization, contacts, DNSSEC, restrictions)",
        "Historical tracking and change detection for domains, TLDs, IPs, and ASNs",
        "RDAP support for modern TLDs",
        "Special handling for .us locality subdomains via DNS",
        "Raw WHOIS data access"
      ]
    },
    "endpoints": [
      {
        "path": "/api/v1/docs",
        "method": "GET",
        "description": "Get comprehensive API documentation (this endpoint)",
        "parameters": [],
        "response_format": "JSON",
        "example_request": "GET /api/v1/docs",
        "example_response": {
          "request_status": "success",
          "message": "API documentation retrieved",
          "data": {}
        }
      },
      {
        "path": "/api/v1/{ip}",
        "method": "GET",
        "description": "Get structured WHOIS information for an IP address (IPv4 or IPv6)",
        "parameters": [
          {
            "name": "ip",
            "type": "path",
            "required": true,
            "description": "The IP address to query (e.g., 1.1.1.1, 8.8.8.8, 2606:4700::)"
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/1.1.1.1",
        "example_response": {
          "request_status": "success",
          "message": "IP WHOIS data retrieved for 1.1.1.1",
          "data": {
            "query_type": "ip",
            "queried_ip": "1.1.1.1",
            "ip_version": 4,
            "network": {
              "handle": "NET-1-1-1-0-1",
              "name": "APNIC-LABS",
              "type": "ASSIGNED PORTABLE",
              "start_address": "1.1.1.0",
              "end_address": "1.1.1.255",
              "cidr": "1.1.1.0/24",
              "parent_handle": "NET-1-0-0-0-0"
            },
            "organization": {
              "handle": "AR302-AP",
              "name": "APNIC Research and Development",
              "email": null,
              "phone": null,
              "address": null
            },
            "country": "AU",
            "asn": null,
            "rir": "APNIC",
            "contacts": {
              "abuse": {
                "handle": "AR302-AP",
                "name": "APNIC Research and Development",
                "email": "helpdesk@apnic.net",
                "phone": "+61-7-3858-3100",
                "address": null
              },
              "technical": null,
              "administrative": null
            },
            "dates": {
              "registration": "2011-08-10T23:12:35Z",
              "last_changed": "2023-04-26T22:57:58Z"
            },
            "status": [
              "active"
            ],
            "remarks": null,
            "data_source": "rdap",
            "rdap_server": "https://rdap.apnic.net"
          }
        },
        "error_responses": [
          {
            "status": 500,
            "error_code": "ERROR_IP_LOOKUP",
            "description": "IP lookup failed (RIR server error or network issue)"
          }
        ],
        "notes": [
          "Automatically detects IPv4 vs IPv6 addresses",
          "Uses IANA RDAP bootstrap to route to correct Regional Internet Registry (RIR)",
          "Supported RIRs: ARIN (North America), RIPE NCC (Europe/Middle East), APNIC (Asia Pacific), LACNIC (Latin America), AFRINIC (Africa)",
          "Returns network allocation details, organization info, abuse contacts, and registration dates",
          "Results are cached for 1 hour"
        ]
      },
      {
        "path": "/api/v1/{asn}",
        "method": "GET",
        "description": "Get structured WHOIS information for an Autonomous System Number (ASN)",
        "parameters": [
          {
            "name": "asn",
            "type": "path",
            "required": true,
            "description": "The ASN to query. Must be in format AS followed by number (e.g., AS13335, AS15169). Case-insensitive. Must NOT contain dots (.), dashes (-), or colons (:)."
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/AS13335",
        "example_response": {
          "request_status": "success",
          "message": "ASN WHOIS data retrieved for AS13335",
          "data": {
            "query_type": "asn",
            "asn_info": {
              "asn": 13335,
              "handle": "AS13335",
              "name": "CLOUDFLARENET",
              "type": "DIRECT ALLOCATION",
              "start_asn": 13335,
              "end_asn": 13335
            },
            "organization": {
              "handle": "CLOUD14",
              "name": "Cloudflare, Inc.",
              "email": null,
              "phone": null,
              "address": "101 Townsend Street, San Francisco, CA, 94107, United States"
            },
            "country": "US",
            "rir": "ARIN",
            "contacts": {
              "abuse": {
                "handle": "ABUSE2916-ARIN",
                "name": "Abuse",
                "email": "abuse@cloudflare.com",
                "phone": "+1-650-319-8930",
                "address": null
              },
              "technical": {
                "handle": "ADMIN2521-ARIN",
                "name": "Admin",
                "email": "rir@cloudflare.com",
                "phone": "+1-650-319-8930",
                "address": null
              },
              "administrative": null
            },
            "dates": {
              "registration": "2010-07-14T22:35:57-04:00",
              "last_changed": "2017-02-17T15:21:49-05:00"
            },
            "status": [
              "active"
            ],
            "remarks": null,
            "data_source": "rdap",
            "rdap_server": "https://rdap.arin.net/registry"
          }
        },
        "error_responses": [
          {
            "status": 500,
            "error_code": "ERROR_ASN_LOOKUP",
            "description": "ASN lookup failed (RIR server error or network issue)"
          }
        ],
        "notes": [
          "ASN format must be AS followed by a number (e.g., AS13335, AS15169, as7922)",
          "Case-insensitive: AS13335, as13335, and As13335 are all valid",
          "Must NOT contain any dots (.), dashes (-), or colons (:)",
          "Uses IANA RDAP bootstrap to route to correct Regional Internet Registry (RIR)",
          "Supported RIRs: ARIN (North America), RIPE NCC (Europe/Middle East), APNIC (Asia Pacific), LACNIC (Latin America), AFRINIC (Africa)",
          "Returns ASN allocation details, organization info, abuse contacts, and registration dates",
          "Results are cached for 1 hour"
        ]
      },
      {
        "path": "/api/v1/{domain}",
        "method": "GET",
        "description": "Get structured WHOIS information for a domain",
        "parameters": [
          {
            "name": "domain",
            "type": "path",
            "required": true,
            "description": "The domain name to query (e.g., example.com, test.dev, site.gov)"
          },
          {
            "name": "fields",
            "type": "query",
            "required": false,
            "description": "Comma-separated list of specific fields to return (e.g., registrar,nameservers,registration_date)"
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/example.com?fields=registrar,nameservers",
        "example_response": {
          "request_status": "success",
          "message": "Parsed WHOIS data retrieved for example.com",
          "data": {
            "queried_domain": "example.com",
            "tld": "com",
            "data_source": "whois_direct",
            "registrar": "Example Registrar, Inc.",
            "registrar_iana_id": "1234",
            "registrar_url": "https://example-registrar.com",
            "registration_date": "2020-01-01T00:00:00Z",
            "expiration_date": "2025-01-01T00:00:00Z",
            "update_date": "2023-01-01T00:00:00Z",
            "domain_status": [
              {
                "status": "clientTransferProhibited",
                "url": "https://icann.org/epp#clientTransferProhibited"
              }
            ],
            "nameservers": [
              "ns1.example.com",
              "ns2.example.com"
            ],
            "dnssec": "signedDelegation",
            "registrant": {
              "name": "John Doe",
              "organization": "Example Corp",
              "email": "john@example.com",
              "phone": "+1.5551234567",
              "street": "123 Main St",
              "city": "Anytown",
              "state_province": "CA",
              "postal_code": "12345",
              "country": "US"
            },
            "admin": {},
            "tech": {},
            "billing": {}
          }
        },
        "error_responses": [
          {
            "status": 400,
            "error_code": "ERROR_INVALID_DOMAIN",
            "description": "Invalid domain format provided"
          },
          {
            "status": 400,
            "error_code": "ERROR_UNSUPPORTED_TLD",
            "description": "TLD not supported by the service"
          },
          {
            "status": 404,
            "error_code": "ERROR_UNREGISTERED",
            "description": "Domain is not registered"
          },
          {
            "status": 500,
            "error_code": "ERROR_SOCKET_OR_PARSE",
            "description": "WHOIS query or parsing failed"
          }
        ]
      },
      {
        "path": "/api/v1/{domain}/raw",
        "method": "GET",
        "description": "Get raw WHOIS data for a domain",
        "parameters": [
          {
            "name": "domain",
            "type": "path",
            "required": true,
            "description": "The domain name to query"
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/example.com/raw",
        "example_response": {
          "request_status": "success",
          "message": "Raw WHOIS data retrieved for example.com",
          "data": {
            "queried_domain": "example.com",
            "tld": "com",
            "data_source": "whois_direct",
            "rawWhois": "Domain Name: EXAMPLE.COM\nRegistrar: EXAMPLE REGISTRAR, INC.\nCreation Date: 2020-01-01T00:00:00Z\n..."
          }
        }
      },
      {
        "path": "/api/v1/{domain}/history",
        "method": "GET",
        "description": "Get historical WHOIS records for a domain (requires database)",
        "parameters": [
          {
            "name": "domain",
            "type": "path",
            "required": true,
            "description": "The domain name to get history for"
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/example.com/history",
        "example_response": {
          "request_status": "success",
          "message": "History retrieved for example.com",
          "data": {
            "domain": {
              "domain_name": "example.com",
              "tld": "com",
              "created_at": "2023-01-01T00:00:00Z",
              "updated_at": "2024-01-01T00:00:00Z"
            },
            "summary": {
              "total_records": 5,
              "first_seen": "2023-01-01T00:00:00Z",
              "last_seen": "2024-01-01T00:00:00Z",
              "successful_queries": 5,
              "failed_queries": 0
            },
            "records": [
              {
                "id": 123,
                "query_timestamp": "2024-01-01T00:00:00Z",
                "registration_status": "registered",
                "registrar": "Example Registrar, Inc.",
                "registration_date": "2020-01-01T00:00:00Z",
                "expiration_date": "2025-01-01T00:00:00Z",
                "nameservers": [
                  "ns1.example.com",
                  "ns2.example.com"
                ],
                "domain_status": [
                  {
                    "status": "clientTransferProhibited",
                    "status_url": "https://icann.org/epp#clientTransferProhibited"
                  }
                ]
              }
            ]
          }
        },
        "error_responses": [
          {
            "status": 404,
            "error_code": "ERROR_NO_HISTORY",
            "description": "No history found for the domain"
          }
        ]
      },
      {
        "path": "/api/v1/{domain}/changes",
        "method": "GET",
        "description": "Get changes tracked between WHOIS records for a domain (requires database)",
        "parameters": [
          {
            "name": "domain",
            "type": "path",
            "required": true,
            "description": "The domain name to get changes for"
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/example.com/changes",
        "example_response": {
          "request_status": "success",
          "message": "Changes retrieved for example.com",
          "data": {
            "domain": {
              "domain_name": "example.com",
              "tld": "com"
            },
            "total_changes": 3,
            "change_events": [
              {
                "timestamp": "2024-01-01T00:00:00Z",
                "from_timestamp": "2023-12-01T00:00:00Z",
                "record_id": 123,
                "from_record_id": 122,
                "changes": [
                  {
                    "field": "nameserver",
                    "old_value": "ns1.old.com",
                    "new_value": "ns1.new.com",
                    "change_type": "modified"
                  }
                ]
              }
            ]
          }
        }
      },
      {
        "path": "/api/v1/tld/{tld}",
        "method": "GET",
        "description": "Get metadata about a TLD (Top-Level Domain) from IANA registry",
        "parameters": [
          {
            "name": "tld",
            "type": "path",
            "required": true,
            "description": "The TLD to query (e.g., com, org, ninja, au). Supports with or without leading dot."
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/tld/com",
        "example_response": {
          "request_status": "success",
          "message": "TLD metadata retrieved for .com",
          "data": {
            "tld": "com",
            "tld_type": "gTLD",
            "query_timestamp": "2024-01-01T00:00:00Z",
            "registry": {
              "organization": "VeriSign Global Registry Services",
              "address": "12061 Bluemont Way\nReston Virginia 20190\nUnited States"
            },
            "contacts": {
              "administrative": {
                "name": "Registry Customer Service",
                "organization": "VeriSign Global Registry Services",
                "address": "12061 Bluemont Way\nReston Virginia 20190\nUnited States",
                "phone": "+1.7039256999",
                "fax": "+1.7039485833",
                "email": "info@verisign-grs.com"
              },
              "technical": {
                "name": "Registry Customer Service",
                "organization": "VeriSign Global Registry Services",
                "address": "12061 Bluemont Way\nReston Virginia 20190\nUnited States",
                "phone": "+1.7039256999",
                "fax": "+1.7039485833",
                "email": "info@verisign-grs.com"
              }
            },
            "nameservers": [
              "a.gtld-servers.net",
              "b.gtld-servers.net"
            ],
            "dnssec": {
              "signed": true,
              "ds_records": [
                {
                  "key_tag": 19718,
                  "algorithm": 8,
                  "digest_type": 2,
                  "digest": "8ACBB0CD28F41250A80A491389424D341522D946B0DA0C0291F2D3D771D7805A"
                }
              ]
            },
            "whois_server": "whois.verisign-grs.com",
            "status": "ACTIVE",
            "dates": {
              "created": "1985-01-01",
              "changed": "2024-01-01"
            },
            "restrictions": {
              "has_restrictions": false,
              "restriction_type": null,
              "eligibility_requirements": null
            },
            "remarks": "Registration information: http://www.verisigninc.com",
            "raw_iana_data": "domain:       COM\norganisation: VeriSign Global Registry Services\n..."
          }
        }
      },
      {
        "path": "/api/v1/tld/{tld}/history",
        "method": "GET",
        "description": "Get historical records for a TLD (requires database)",
        "parameters": [
          {
            "name": "tld",
            "type": "path",
            "required": true,
            "description": "The TLD to get history for"
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/tld/com/history",
        "example_response": {
          "request_status": "success",
          "message": "History retrieved for .com",
          "data": {
            "tld": {
              "tld": "com",
              "tld_type": "gTLD"
            },
            "total_records": 3,
            "records": [
              {
                "id": 1,
                "query_timestamp": "2024-01-01T00:00:00Z",
                "registry_organization": "VeriSign Global Registry Services",
                "admin_name": "Registry Customer Service",
                "tech_name": "Registry Customer Service",
                "whois_server": "whois.verisign-grs.com",
                "status": "ACTIVE",
                "dnssec_signed": true,
                "has_restrictions": false,
                "nameserver_count": 13,
                "dnssec_ds_count": 2
              }
            ]
          }
        }
      },
      {
        "path": "/api/v1/tld/{tld}/changes",
        "method": "GET",
        "description": "Get changes tracked between TLD metadata records (requires database)",
        "parameters": [
          {
            "name": "tld",
            "type": "path",
            "required": true,
            "description": "The TLD to get changes for"
          }
        ],
        "response_format": "JSON",
        "example_request": "GET /api/v1/tld/com/changes",
        "example_response": {
          "request_status": "success",
          "message": "Changes retrieved for .com",
          "data": {
            "tld": {
              "tld": "com",
              "tld_type": "gTLD"
            },
            "total_changes": 2,
            "change_events": [
              {
                "timestamp": "2024-01-01T00:00:00Z",
                "from_timestamp": "2023-12-01T00:00:00Z",
                "record_id": 2,
                "from_record_id": 1,
                "changes": [
                  {
                    "field": "changed_date",
                    "old_value": "2023-12-01",
                    "new_value": "2024-01-01",
                    "change_type": "modified"
                  },
                  {
                    "field": "nameserver",
                    "old_value": null,
                    "new_value": "m.gtld-servers.net",
                    "change_type": "added"
                  }
                ]
              }
            ]
          }
        }
      }
    ],
    "supported_tlds": {
      "total_count": "1500+",
      "description": "This API supports virtually all TLDs through a multi-tier lookup system",
      "lookup_tiers": [
        {
          "tier": 1,
          "name": "Hardcoded Map (200+ TLDs)",
          "description": "Instant lookup for popular TLDs with pre-configured WHOIS/RDAP servers",
          "response_time": "< 1ms",
          "examples": [
            ".com",
            ".net",
            ".org",
            ".io",
            ".xyz",
            ".ai",
            ".dev",
            ".app"
          ]
        },
        {
          "tier": 2,
          "name": "KV Cache (Optional)",
          "description": "Persistent cache for previously queried TLDs",
          "response_time": "< 5ms",
          "note": "Reduces repeated IANA lookups"
        },
        {
          "tier": 3,
          "name": "RDAP Bootstrap (1000+ TLDs)",
          "description": "Auto-discovery using IANA's RDAP DNS bootstrap registry",
          "response_time": "< 100ms",
          "examples": [
            ".cloud",
            ".tech",
            ".online",
            ".store"
          ]
        },
        {
          "tier": 4,
          "name": "IANA Fallback (Universal)",
          "description": "Direct query to whois.iana.org for any TLD",
          "response_time": "< 500ms",
          "coverage": "All IANA-registered TLDs"
        }
      ],
      "categories": [
        {
          "category": "Generic TLDs (gTLDs)",
          "count": "1200+",
          "examples": [
            ".com",
            ".net",
            ".org",
            ".info",
            ".biz",
            ".xyz",
            ".online",
            ".tech"
          ],
          "description": "Generic top-level domains available for general use"
        },
        {
          "category": "Country Code TLDs (ccTLDs)",
          "count": "250+",
          "examples": [
            ".us",
            ".uk",
            ".ca",
            ".au",
            ".de",
            ".jp",
            ".io",
            ".ai"
          ],
          "description": "Two-letter country and territory codes"
        },
        {
          "category": "Google Registry TLDs (RDAP)",
          "count": "16",
          "tlds": [
            ".dev",
            ".app",
            ".page",
            ".how",
            ".soy",
            ".meme",
            ".boo",
            ".dad",
            ".day",
            ".foo",
            ".zip",
            ".mov",
            ".nexus",
            ".phd",
            ".prof",
            ".esq"
          ],
          "data_source": "rdap",
          "note": "Uses RDAP instead of traditional WHOIS"
        },
        {
          "category": "Identity Digital TLDs (RDAP)",
          "count": "170+",
          "examples": [
            ".ninja",
            ".stream",
            ".email",
            ".photos",
            ".live",
            ".studio",
            ".cloud",
            ".world"
          ],
          "data_source": "rdap",
          "note": "Formerly Donuts Inc. registry, uses RDAP protocol"
        },
        {
          "category": "Restricted/Sponsored TLDs",
          "examples": [
            ".gov",
            ".mil",
            ".edu",
            ".museum",
            ".aero"
          ],
          "description": "TLDs with eligibility requirements or restrictions",
          "note": ".gov is served from the CISA dotgov-data CSV mirror (data_source: cisa_csv)"
        }
      ],
      "special_cases": [
        {
          "case": ".us Locality Subdomains (Domain Queries)",
          "pattern": "*.city.state.us",
          "examples": [
            "sergio.sf.ca.us",
            "example.nyc.ny.us"
          ],
          "behavior": "Automatically falls back to DNS queries when WHOIS returns 'No Data Found'",
          "endpoint": "/api/v1/{domain}",
          "data_returned": "Nameservers, SOA record, responsible entity from DNS",
          "note": "For domains UNDER locality zones (like example.seattle.wa.us), use the domain endpoint."
        },
        {
          "case": ".us Locality Delegations (TLD Queries)",
          "pattern": "city.state.us or state.us",
          "examples": [
            "sf.ca.us",
            "seattle.wa.us",
            "nyc.ny.us",
            "boulder.co.us"
          ],
          "behavior": "Queries DNS (SOA/NS) to identify the actual operator of the locality delegation",
          "endpoint": "/api/v1/tld/{locality}",
          "why_needed": ".us locality delegations are NOT in IANA registry. IANA only knows about 'us', not the individual city/state delegations.",
          "data_returned": "Operator name (extracted from nameservers), contact email (from SOA), nameservers, delegation status",
          "operator_examples": {
            "sf.ca.us": "Sonic.net",
            "seattle.wa.us": "Nuoz.net",
            "nyc.ny.us": "LocalityManagement.us",
            "boulder.co.us": "LocalityManagement.us"
          },
          "developer_tip": "For .us localities, query BOTH endpoints to get complete information",
          "example_use_case": {
            "description": "Get complete information about sf.ca.us and domains under it",
            "steps": [
              "1. Query /api/v1/tld/sf.ca.us to see who operates the zone (Sonic.net)",
              "2. Query /api/v1/example.sf.ca.us to lookup specific domains under that zone",
              "3. Both endpoints work together - TLD endpoint shows operator, domain endpoint shows registrant"
            ],
            "code_example": "// Get locality operator\nconst tld = await fetch('https://whois.datasourceapi.com/api/v1/tld/sf.ca.us');\nconsole.log(tld.data.locality_info.operator); // 'Sonic.net'\n\n// Get domain under locality\nconst domain = await fetch('https://whois.datasourceapi.com/api/v1/example.sf.ca.us');\nconsole.log(domain.data.registrar); // Shows registrar if domain exists"
          }
        },
        {
          "case": ".gov Domains (CISA Pseudo-WHOIS)",
          "status": "Supported",
          "data_source": "cisa_csv",
          "endpoint": "/api/v1/{domain}.gov",
          "why_pseudo": "The official .gov WHOIS server (whois.nic.gov) blocks Cloudflare Workers' egress IPs. To still serve .gov reliably, this API mirrors the CISA dotgov-data registry — the same authoritative dataset CISA itself publishes for the public.",
          "source": {
            "publisher": "Cybersecurity and Infrastructure Security Agency (CISA)",
            "repository": "https://github.com/cisagov/dotgov-data",
            "csv_url": "https://raw.githubusercontent.com/cisagov/dotgov-data/main/current-full.csv",
            "license": "CC0 / Public Domain",
            "current_size": "~15,800 domains (~3.4 MB JSON)"
          },
          "refresh_pipeline": {
            "storage": "Cloudflare KV namespace GOV_REGISTRY, key registry:current",
            "cadence": "Weekly, every Monday at 02:00 UTC via the existing scheduled() cron",
            "conditional_fetch": "Uses HTTP If-None-Match against the CISA CSV ETag — refresh is a no-op when the upstream has not changed",
            "manual_trigger": "POST /api/v1/refresh-gov?key=<CLEANUP_SECRET>[&force=1] (admin)",
            "change_tracking": "Every added / removed / modified domain emits a row to the Cosmos `changes` container via the same appendChange() helper used for real WHOIS changes. Visible at /api/v1/{domain}/changes with changeType in ('gov-added','gov-removed','gov-modified')."
          },
          "response_shape": {
            "note": "The response uses the same structured field layout as any other domain (registrar/registrant/nameservers/dates/etc.) so client code does not need a .gov-specific branch. data_source is set to 'cisa_csv'.",
            "always_populated": [
              "queried_domain",
              "tld ('gov')",
              "data_source ('cisa_csv')",
              "domain_registration_status ('registered' or 'unregistered')",
              "registrar ('Cybersecurity and Infrastructure Security Agency (CISA)')",
              "registrar_url ('https://get.gov/')",
              "registrar_abuse_email ('registrar@dotgov.gov')",
              "domain_status (['serverTransferProhibited …'])",
              "registrant.country ('US')",
              "update_date (the registry mirror's last refresh timestamp)",
              "cisa_metadata (see below)"
            ],
            "from_cisa_csv": {
              "description": "Sourced directly from the CISA dotgov-data CSV row for the domain.",
              "fields": [
                "registrant.organization     ← CSV: Organization name",
                "registrant.city             ← CSV: City",
                "registrant.state_province   ← CSV: State",
                "registrant.email            ← CSV: Security contact email (may be null when CISA records '(blank)')",
                "cisa_metadata.domain_type           ← CSV: Domain type (e.g. 'Federal - Executive', 'City', 'County', 'State')",
                "cisa_metadata.organization_name     ← CSV: Organization name",
                "cisa_metadata.suborganization_name  ← CSV: Suborganization name (e.g. 'Internal Revenue Service' under 'Department of the Treasury')",
                "cisa_metadata.security_contact_email ← CSV: Security contact email",
                "cisa_metadata.registry_updated_at   (timestamp of the last successful KV mirror refresh)",
                "cisa_metadata.source_url            (canonical CSV URL)",
                "cisa_metadata.stale_warning         (non-null if the mirror is >30 days old)"
              ]
            },
            "from_live_dns": {
              "description": "Enrichment performed at query time via Cloudflare DNS-over-HTTPS (NS record lookup). Best-effort — returns [] on DNS failure rather than blocking the response.",
              "fields": [
                "nameservers"
              ]
            },
            "always_null": {
              "description": "Not published by the .gov registry, therefore never present in the CSV.",
              "fields": [
                "registration_date",
                "expiration_date",
                "registrar_iana_id",
                "registrar_abuse_phone",
                "dnssec",
                "registrant.id",
                "registrant.name",
                "registrant.street",
                "registrant.postal_code",
                "registrant.phone",
                "registrant.fax",
                "admin / tech / billing contact blocks"
              ]
            }
          },
          "history_and_changes": {
            "history_endpoint": "/api/v1/{domain}.gov/history — every query writes a snapshot to the Cosmos whois-records container via saveWhoisRecord(), so .gov has full history parity with real WHOIS data.",
            "changes_endpoint": "/api/v1/{domain}.gov/changes — surfaces every CISA-CSV diff (gov-added / gov-removed / gov-modified) and any field-level deltas detected on subsequent re-checks.",
            "tracked_change_fields": [
              "domain_type",
              "organization_name",
              "suborganization_name",
              "city",
              "state",
              "security_contact_email"
            ]
          },
          "subdomain_handling": "Queries for sub.agency.gov roll up to the registered apex (agency.gov) via the Public Suffix List, since the CISA registry only publishes apex .gov names.",
          "unregistered_response": "Domains not present in the CISA CSV return HTTP 404 with error_code ERROR_UNREGISTERED and data_source 'cisa_csv'.",
          "example_request": "GET https://whois.datasourceapi.com/api/v1/irs.gov",
          "example_response_snippet": {
            "data_source": "cisa_csv",
            "registrar": "Cybersecurity and Infrastructure Security Agency (CISA)",
            "registrant": {
              "organization": "Department of the Treasury",
              "city": "Washington",
              "state_province": "DC",
              "country": "US",
              "email": "domainsecurity@treasury.gov"
            },
            "cisa_metadata": {
              "domain_type": "Federal - Executive",
              "suborganization_name": "Internal Revenue Service",
              "registry_updated_at": "2026-05-20T09:57:25.789Z"
            },
            "nameservers": [
              "ns0022.secondary.cloudflare.com",
              "ns0227.secondary.cloudflare.com"
            ]
          }
        }
      ],
      "us_delegation_structure": {
        "description": ".us has a unique hierarchical delegation structure not found in other TLDs",
        "hierarchy": [
          {
            "level": "Top Level",
            "example": "us",
            "handled_by": "Registry Services, LLC (Neustar)",
            "iana_registry": true,
            "endpoint": "/api/v1/tld/us"
          },
          {
            "level": "State Delegations",
            "examples": [
              "ca.us",
              "ny.us",
              "wa.us"
            ],
            "handled_by": "Varies by state - some have SOA, some are just delegation points",
            "iana_registry": false,
            "endpoint": "/api/v1/tld/ca.us (may fallback to parent 'us' if no SOA exists)",
            "note": "Not all state delegations have their own zone - many are just delegation points"
          },
          {
            "level": "Locality Delegations (City/County)",
            "examples": [
              "sf.ca.us",
              "seattle.wa.us",
              "nyc.ny.us"
            ],
            "handled_by": "Various operators (Sonic.net, Nuoz.net, LocalityManagement.us, etc.)",
            "iana_registry": false,
            "endpoint": "/api/v1/tld/sf.ca.us",
            "note": "These are actual DNS zones with SOA records. API queries DNS to find operator."
          },
          {
            "level": "Domains Under Localities",
            "examples": [
              "example.sf.ca.us",
              "test.seattle.wa.us"
            ],
            "handled_by": "Registered domains managed by locality operators",
            "iana_registry": false,
            "endpoint": "/api/v1/example.sf.ca.us",
            "note": "Use domain endpoint, not TLD endpoint. May fallback to DNS if no WHOIS data."
          }
        ],
        "best_practices": [
          "For locality zones (sf.ca.us): Use /api/v1/tld/{locality} to identify operator",
          "For domains (example.sf.ca.us): Use /api/v1/{domain} for registrant info",
          "Query both endpoints when you need complete context about .us localities",
          "Don't expect state-level delegations (ca.us) to have operator info - many lack SOA records"
        ]
      }
    },
    "data_sources": [
      {
        "name": "cisa_csv",
        "description": "CISA dotgov-data CSV mirror — pseudo-WHOIS for the .gov TLD",
        "protocol": "HTTPS (GitHub raw CSV) → Cloudflare KV",
        "format": "CSV upstream, JSON in KV, standard structured-WHOIS shape on the wire",
        "upstream": "https://raw.githubusercontent.com/cisagov/dotgov-data/main/current-full.csv",
        "license": "CC0 / Public Domain",
        "used_for": [
          ".gov domains (whois.nic.gov blocks Cloudflare Workers' egress IPs)"
        ],
        "refresh": "Weekly cron (Mondays 02:00 UTC) + manual POST /api/v1/refresh-gov",
        "change_tracking": "Per-row diffs emitted to Cosmos `changes` container as gov-added / gov-removed / gov-modified events",
        "limitations": [
          "No registration_date / expiration_date (the .gov registry does not publish these)",
          "Nameservers come from live DoH lookup, not from the CSV",
          "Contact details limited to security contact email; admin/tech/billing contacts are not published"
        ]
      },
      {
        "name": "whois_direct",
        "description": "Direct WHOIS queries over port 43 to registry WHOIS servers",
        "protocol": "TCP port 43",
        "format": "Plain text",
        "timeout": "30 seconds",
        "used_for": [
          "Traditional TLDs (.com, .net, .org, etc.)",
          "Most ccTLDs (.us, .uk, .au, etc.)",
          "Legacy gTLDs (.info, .biz, etc.)"
        ]
      },
      {
        "name": "rdap",
        "description": "RDAP (Registration Data Access Protocol) - Modern alternative to WHOIS",
        "protocol": "HTTPS/JSON",
        "format": "Structured JSON",
        "timeout": "30 seconds",
        "used_for": [
          "Google Registry TLDs (.dev, .app, .page, etc.)",
          "Identity Digital TLDs (.ninja, .stream, .email, etc.)",
          "Modern registries that don't support traditional WHOIS"
        ],
        "advantages": [
          "Structured data (no parsing needed)",
          "Standardized format across registries",
          "Better internationalization support",
          "More detailed contact information"
        ]
      },
      {
        "name": "dns_cloudflare",
        "description": "DNS queries using Cloudflare DNS-over-HTTPS API",
        "protocol": "HTTPS (DNS-JSON)",
        "format": "JSON",
        "used_for": [
          ".us locality subdomains without WHOIS data",
          "Domains that return 'No Data Found' from WHOIS"
        ],
        "data_returned": [
          "Authoritative nameservers (NS records)",
          "SOA record (zone authority and timing)",
          "Responsible entity (extracted from SOA email)"
        ]
      },
      {
        "name": "iana",
        "description": "TLD metadata from IANA registry",
        "endpoint": "whois.iana.org (port 43)",
        "format": "Structured text",
        "used_for": [
          "TLD metadata queries (/api/v1/tld/{tld})",
          "Registry organization information",
          "TLD administrative and technical contacts",
          "DNSSEC DS records",
          "TLD eligibility requirements"
        ],
        "data_included": [
          "Registry organization and address",
          "Administrative contact (name, email, phone, address)",
          "Technical contact (name, email, phone, address)",
          "Authoritative nameservers for the TLD",
          "DNSSEC status and DS records",
          "Creation and last change dates",
          "TLD status (ACTIVE, etc.)",
          "Remarks (including restrictions)"
        ]
      }
    ],
    "response_fields": {
      "domain_queries": {
        "description": "Fields returned for domain WHOIS queries (/api/v1/{domain})",
        "basic_info": [
          "queried_domain",
          "tld",
          "data_source",
          "domain_registration_status"
        ],
        "registrar_info": [
          "registrar",
          "registrar_iana_id",
          "registrar_url",
          "registrar_abuse_email",
          "registrar_abuse_phone"
        ],
        "dates": [
          "registration_date",
          "expiration_date",
          "update_date"
        ],
        "technical": [
          "domain_status",
          "nameservers",
          "dnssec"
        ],
        "contacts": [
          "registrant",
          "admin",
          "tech",
          "billing"
        ],
        "cisa_metadata": {
          "description": "Extra object present ONLY on .gov responses (data_source: 'cisa_csv'). Mirrors the row from the CISA dotgov-data registry CSV plus refresh-pipeline metadata. This is the canonical source of agency / domain-type information for .gov domains since the standard WHOIS fields (registration_date, expiration_date, etc.) are not published by the .gov registry.",
          "fields": [
            "cisa_metadata.domain_type           — The category of registrant. Examples: 'Federal - Executive', 'Federal - Legislative', 'Federal - Judicial', 'Interstate', 'State', 'Tribal', 'County', 'City'. Sourced from the CSV 'Domain type' column.",
            "cisa_metadata.organization_name     — Full registrant organization name (e.g. 'Department of the Treasury', 'Executive Office of the President'). Sourced from the CSV 'Organization name' column. Also mirrored to registrant.organization.",
            "cisa_metadata.suborganization_name  — Finer-grained subunit when present (e.g. 'Internal Revenue Service' under Treasury, 'White House Office' under EOP). Sourced from the CSV 'Suborganization name' column. May be null.",
            "cisa_metadata.security_contact_email — Published security contact for the domain (e.g. 'domainsecurity@treasury.gov'). Sourced from the CSV 'Security contact email' column. May be null when CISA records the literal '(blank)' value.",
            "cisa_metadata.registry_updated_at   — ISO-8601 timestamp of when this API last successfully refreshed its KV mirror from the upstream CSV. Useful for staleness checks.",
            "cisa_metadata.source_url            — Canonical upstream URL: https://raw.githubusercontent.com/cisagov/dotgov-data/main/current-full.csv",
            "cisa_metadata.stale_warning         — Human-readable warning string if registry_updated_at is more than 30 days old; null otherwise."
          ],
          "example": {
            "domain_type": "Federal - Executive",
            "organization_name": "Department of the Treasury",
            "suborganization_name": "Internal Revenue Service",
            "security_contact_email": "domainsecurity@treasury.gov",
            "registry_updated_at": "2026-05-20T09:57:25.789Z",
            "source_url": "https://raw.githubusercontent.com/cisagov/dotgov-data/main/current-full.csv",
            "stale_warning": null
          },
          "present_when": "data_source === 'cisa_csv' (every .gov response)",
          "absent_when": "data_source is anything else (whois_direct, rdap, dns_cloudflare, …)"
        },
        "gov_specific": {
          "description": "When data_source is 'cisa_csv' (i.e. .gov queries) the response carries the same field layout plus the cisa_metadata object documented above. Several standard fields are always null for .gov because the registry does not publish them — see special_cases['.gov Domains (CISA Pseudo-WHOIS)'] for the full breakdown.",
          "always_null_for_gov": [
            "registration_date",
            "expiration_date",
            "registrar_iana_id",
            "registrar_abuse_phone",
            "dnssec",
            "admin",
            "tech",
            "billing"
          ]
        }
      },
      "ip_queries": {
        "description": "Fields returned for IP WHOIS queries (/api/v1/{ip})",
        "basic_info": [
          "query_type ('ip')",
          "queried_ip",
          "ip_version (4 or 6)",
          "data_source ('rdap')",
          "rdap_server"
        ],
        "network": [
          "network.handle (registry identifier)",
          "network.name (network name, e.g., 'APNIC-LABS')",
          "network.type (e.g., 'ASSIGNED PORTABLE', 'ALLOCATED')",
          "network.start_address",
          "network.end_address",
          "network.cidr (CIDR notation)",
          "network.parent_handle"
        ],
        "organization": [
          "organization.handle",
          "organization.name",
          "organization.email",
          "organization.phone",
          "organization.address"
        ],
        "geo_and_routing": [
          "country (ISO country code)",
          "asn (array of ASN numbers if available)",
          "rir (Regional Internet Registry: ARIN, RIPE NCC, APNIC, LACNIC, AFRINIC)"
        ],
        "contacts": [
          "contacts.abuse (handle, name, email, phone, address)",
          "contacts.technical",
          "contacts.administrative"
        ],
        "dates": [
          "dates.registration",
          "dates.last_changed"
        ],
        "other": [
          "status (array of status flags)",
          "remarks"
        ],
        "note": "IP lookups use RDAP (Registration Data Access Protocol) to query the appropriate Regional Internet Registry. The API automatically determines the correct RIR using IANA's bootstrap protocol."
      },
      "tld_queries": {
        "description": "Fields returned for TLD metadata queries (/api/v1/tld/{tld})",
        "basic_info": [
          "tld",
          "tld_type",
          "query_timestamp",
          "status"
        ],
        "country_metadata": {
          "description": "Only present for ccTLDs (country code TLDs like .uk, .jp, .de). NOT present for gTLDs (.com, .org, .net)",
          "fields": [
            "country_code (ISO 3166-1 alpha-2, e.g., 'GB', 'JP', 'US')",
            "country_name (full name, e.g., 'United Kingdom')",
            "continent_code (e.g., 'EU', 'AS', 'NA')",
            "continent_name (e.g., 'Europe', 'Asia', 'North America')",
            "capital (capital city name, e.g., 'London')",
            "capital_coordinates.latitude (decimal degrees)",
            "capital_coordinates.longitude (decimal degrees)"
          ],
          "examples": {
            "uk": {
              "country_code": "GB",
              "country_name": "United Kingdom",
              "continent_code": "EU",
              "continent_name": "Europe",
              "capital": "London",
              "capital_coordinates": {
                "latitude": 51.5085,
                "longitude": -0.1257
              }
            },
            "jp": {
              "country_code": "JP",
              "country_name": "Japan",
              "continent_code": "AS",
              "continent_name": "Asia",
              "capital": "Tokyo",
              "capital_coordinates": {
                "latitude": 35.6895,
                "longitude": 139.6917
              }
            }
          },
          "note": "This field is automatically populated from a lookup table containing 278 ccTLDs with their associated country information. The data is sourced from ISO 3166-1 and maintained country databases. Users can query just the TLD field from domain queries, then optionally make a subrequest to /api/v1/tld/{tld} to get full country metadata."
        },
        "registry": [
          "registry.organization",
          "registry.address (full multi-line address)"
        ],
        "contacts": [
          "contacts.administrative (name, organization, address, phone, fax, email)",
          "contacts.technical (name, organization, address, phone, fax, email)"
        ],
        "technical": [
          "nameservers (array of {nameserver, ipv4, ipv6})",
          "dnssec.signed",
          "dnssec.ds_records (array of {key_tag, algorithm, algorithm_name, digest_type, digest_type_name, digest})"
        ],
        "dates": [
          "dates.created",
          "dates.changed"
        ],
        "restrictions": [
          "restrictions.has_restrictions",
          "restrictions.restriction_type",
          "restrictions.eligibility_requirements"
        ],
        "other": [
          "whois_server",
          "remarks",
          "raw_iana_data"
        ],
        "us_locality_specific": {
          "description": "Additional fields for .us locality delegations (sf.ca.us, nyc.ny.us, etc.)",
          "fields": [
            "locality_info.type ('us_delegation')",
            "locality_info.operator (extracted from nameservers, e.g., 'Sonic.net')",
            "locality_info.primary_nameserver",
            "locality_info.contact_email (from SOA record)"
          ],
          "note": ".us locality TLDs are NOT in IANA registry. We query DNS (SOA/NS records) to identify the operator and contact information."
        }
      },
      "us_subdomain_queries": {
        "description": "Fields returned for .us locality subdomain queries with DNS fallback",
        "fields": [
          "queried_domain",
          "tld",
          "domain_type",
          "data_source",
          "nameservers",
          "soa_record",
          "responsible_entity",
          "note"
        ]
      }
    },
    "contact_fields": [
      "id",
      "name",
      "organization",
      "street",
      "city",
      "state_province",
      "postal_code",
      "country",
      "phone",
      "phone_ext",
      "fax",
      "fax_ext",
      "email"
    ],
    "error_codes": {
      "ERROR_INVALID_PATH": {
        "description": "Invalid API path provided",
        "http_status": 404,
        "example": "Requesting /api/v2/example.com instead of /api/v1/example.com"
      },
      "ERROR_NO_DOMAIN": {
        "description": "No domain specified in the request",
        "http_status": 400,
        "example": "Requesting /api/v1/ without a domain"
      },
      "ERROR_INVALID_DOMAIN": {
        "description": "Invalid domain format",
        "http_status": 400,
        "example": "Requesting 'notadomain' or domain with less than 2 parts"
      },
      "ERROR_UNSUPPORTED_TLD": {
        "description": "TLD not supported by the service",
        "http_status": 400,
        "note": "This is rare - most TLDs fall back to IANA"
      },
      "ERROR_UNREGISTERED": {
        "description": "Domain is not registered or not found",
        "http_status": 404,
        "note": "WHOIS server returned 'No Data Found' or similar"
      },
      "ERROR_SOCKET_OR_PARSE": {
        "description": "WHOIS query or parsing failed",
        "http_status": 500,
        "causes": [
          "Network timeout",
          "WHOIS server connection failure",
          "Malformed WHOIS response"
        ]
      },
      "ERROR_NO_HISTORY": {
        "description": "No history found for the domain or TLD",
        "http_status": 404,
        "note": "The domain/TLD has not been queried before. Query it first to create history."
      },
      "ERROR_DATABASE": {
        "description": "Database operation failed",
        "http_status": 500,
        "note": "Applies to /history and /changes endpoints only"
      },
      "ERROR_NO_DATABASE": {
        "description": "Database not configured",
        "http_status": 500,
        "note": "Returned when database is required but not available"
      },
      "ERROR_TLD_QUERY": {
        "description": "Failed to query TLD metadata from IANA",
        "http_status": 500,
        "causes": [
          "IANA WHOIS server timeout",
          "TLD not found in IANA registry",
          "Parse error"
        ]
      },
      "ERROR_DNS_QUERY": {
        "description": "DNS query failed for .us subdomain",
        "http_status": 500,
        "causes": [
          "Cloudflare DNS API timeout",
          "Domain does not exist in DNS"
        ]
      },
      "ERROR_INVALID_ACTION": {
        "description": "Invalid action specified in TLD endpoint",
        "http_status": 400,
        "valid_actions": [
          "history",
          "changes"
        ]
      }
    },
    "rate_limiting": {
      "description": "No explicit rate limiting, but reasonable usage is expected",
      "recommendation": "Limit requests to 100 per minute per IP address"
    },
    "caching": {
      "description": "Responses include Cache-Control headers with 5-minute cache duration",
      "headers": {
        "Cache-Control": "max-age=300",
        "ETag": "SHA-1 hash of response content"
      }
    },
    "cors": {
      "description": "CORS is enabled for cross-origin requests",
      "headers": {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS"
      }
    },
    "use_cases": [
      {
        "title": "Domain Monitoring & Change Detection",
        "description": "Track domain ownership, contact, and DNS changes over time",
        "endpoints": [
          "/api/v1/{domain}",
          "/api/v1/{domain}/history",
          "/api/v1/{domain}/changes"
        ],
        "example_workflow": [
          "Query domain daily to store snapshots",
          "Use /history to view all historical records",
          "Use /changes to detect nameserver switches, registrar transfers, etc."
        ]
      },
      {
        "title": "TLD Research & Registry Information",
        "description": "Research TLD operators, DNSSEC deployment, and eligibility requirements",
        "endpoints": [
          "/api/v1/tld/{tld}",
          "/api/v1/tld/{tld}/history"
        ],
        "example_use_cases": [
          "Find who operates a TLD (e.g., VeriSign for .com)",
          "Check DNSSEC deployment status",
          "Identify TLD restrictions (e.g., .aero requires aviation nexus)",
          "Track registry contact changes over time"
        ]
      },
      {
        "title": "Domain Expiration Monitoring",
        "description": "Monitor domain expiration dates to prevent accidental losses",
        "endpoints": [
          "/api/v1/{domain}"
        ],
        "fields_to_track": [
          "expiration_date",
          "update_date",
          "domain_status"
        ]
      },
      {
        "title": "Registrar Analysis",
        "description": "Analyze registrar portfolios and identify domain migrations",
        "endpoints": [
          "/api/v1/{domain}",
          "/api/v1/{domain}/changes"
        ],
        "example_queries": [
          "Track which registrar hosts your domain portfolio",
          "Detect registrar transfers via change tracking",
          "Compare registrar abuse contact information"
        ]
      },
      {
        "title": "Security & Threat Intelligence",
        "description": "Identify domain ownership changes that may indicate compromise",
        "endpoints": [
          "/api/v1/{domain}/changes"
        ],
        "red_flags": [
          "Sudden nameserver changes",
          "Registrant email/organization changes",
          "Status code changes (e.g., lock removal)"
        ]
      },
      {
        "title": "Compliance & Legal",
        "description": "Verify domain ownership and contact information for legal/compliance purposes",
        "endpoints": [
          "/api/v1/{domain}",
          "/api/v1/{domain}/raw"
        ],
        "use_cases": [
          "Verify registrant organization for contracts",
          "Obtain admin contact for legal notices",
          "Document domain ownership with raw WHOIS data"
        ]
      }
    ],
    "integration_examples": {
      "javascript": "\n// Basic domain lookup\nconst response = await fetch('https://whois.datasourceapi.com/api/v1/example.com');\nconst data = await response.json();\n\n// Get specific fields only\nconst response = await fetch('https://whois.datasourceapi.com/api/v1/example.com?fields=registrar,nameservers,registration_date');\nconst data = await response.json();\n\n// Get TLD metadata\nconst response = await fetch('https://whois.datasourceapi.com/api/v1/tld/com');\nconst tldData = await response.json();\nconsole.log(tldData.data.registry.organization); // VeriSign Global Registry Services\n\n// Get raw WHOIS data\nconst response = await fetch('https://whois.datasourceapi.com/api/v1/example.com/raw');\nconst data = await response.json();\n\n// Get domain history\nconst response = await fetch('https://whois.datasourceapi.com/api/v1/example.com/history');\nconst data = await response.json();\n      ",
      "python": "\nimport requests\n\n# Basic domain lookup\nresponse = requests.get('https://whois.datasourceapi.com/api/v1/example.com')\ndata = response.json()\nprint(data['data']['registrar'])\n\n# Get specific fields only\nresponse = requests.get('https://whois.datasourceapi.com/api/v1/example.com?fields=registrar,nameservers,registration_date')\ndata = response.json()\n\n# Get TLD metadata\nresponse = requests.get('https://whois.datasourceapi.com/api/v1/tld/ninja')\ntld_data = response.json()\nprint(f\"Registry: {tld_data['data']['registry']['organization']}\")\nprint(f\"DNSSEC: {tld_data['data']['dnssec']['signed']}\")\n\n# Get TLD history\nresponse = requests.get('https://whois.datasourceapi.com/api/v1/tld/com/history')\nhistory = response.json()\nprint(f\"Total records: {history['data']['total_records']}\")\n\n# Get raw WHOIS data\nresponse = requests.get('https://whois.datasourceapi.com/api/v1/example.com/raw')\ndata = response.json()\n\n# Get domain history\nresponse = requests.get('https://whois.datasourceapi.com/api/v1/example.com/history')\ndata = response.json()\n\n# Track domain changes over time\nresponse = requests.get('https://whois.datasourceapi.com/api/v1/example.com/changes')\nchanges = response.json()\nfor event in changes['data']['change_events']:\n    print(f\"Changes at {event['timestamp']}:\")\n    for change in event['changes']:\n        print(f\"  {change['field']}: {change['old_value']} -> {change['new_value']}\")\n      ",
      "curl": "\n# Basic domain lookup\ncurl \"https://whois.datasourceapi.com/api/v1/example.com\"\n\n# Get specific fields only\ncurl \"https://whois.datasourceapi.com/api/v1/example.com?fields=registrar,nameservers,registration_date\"\n\n# Get TLD metadata\ncurl \"https://whois.datasourceapi.com/api/v1/tld/com\"\n\n# Get TLD metadata with trailing dot (both formats work)\ncurl \"https://whois.datasourceapi.com/api/v1/tld/org.\"\n\n# Get TLD history\ncurl \"https://whois.datasourceapi.com/api/v1/tld/ninja/history\"\n\n# Get TLD changes\ncurl \"https://whois.datasourceapi.com/api/v1/tld/io/changes\"\n\n# Get raw WHOIS data\ncurl \"https://whois.datasourceapi.com/api/v1/example.com/raw\"\n\n# Get domain history\ncurl \"https://whois.datasourceapi.com/api/v1/example.com/history\"\n\n# Get domain changes\ncurl \"https://whois.datasourceapi.com/api/v1/example.com/changes\"\n\n# Pretty print JSON with jq\ncurl -s \"https://whois.datasourceapi.com/api/v1/tld/com\" | jq '.data.registry'\n\n# Check if TLD has DNSSEC\ncurl -s \"https://whois.datasourceapi.com/api/v1/tld/ninja\" | jq '.data.dnssec.signed'\n\n# Get .us subdomain (automatically uses DNS fallback if needed)\ncurl \"https://whois.datasourceapi.com/api/v1/sergio.sf.ca.us\"\n\n# === .us Locality Examples (Query BOTH endpoints) ===\n\n# Get who operates sf.ca.us locality\ncurl \"https://whois.datasourceapi.com/api/v1/tld/sf.ca.us\" | jq '.data.locality_info.operator'\n# Returns: \"Sonic.net\"\n\n# Get domain under sf.ca.us\ncurl \"https://whois.datasourceapi.com/api/v1/example.sf.ca.us\"\n# Returns domain WHOIS or DNS data if domain exists\n\n# Compare: seattle.wa.us operator\ncurl \"https://whois.datasourceapi.com/api/v1/tld/seattle.wa.us\" | jq '{operator: .data.locality_info.operator, contact: .data.locality_info.contact_email}'\n# Returns: {\"operator\": \"Nuoz.net\", \"contact\": \"postmaster@nwnexus.com\"}\n\n# Full workflow - get complete context for a .us locality domain\ncurl -s \"https://whois.datasourceapi.com/api/v1/tld/sf.ca.us\" | jq '{zone_operator: .data.locality_info.operator}'\ncurl -s \"https://whois.datasourceapi.com/api/v1/example.sf.ca.us\" | jq '{domain_registrar: .data.registrar}'\n      "
    }
  }
}