{"openapi":"3.1.0","info":{"title":"who.is API","version":"1.0.0","description":"The who.is public API — parsed WHOIS, normalized RDAP, and DNS/certificate\nhistory for any domain. Authenticate with a Bearer API key; every response\ncarries `X-RateLimit-Limit` and `X-RateLimit-Remaining`, and `Retry-After`\naccompanies a 429.\n\n## Plans\n\n- **Free** — 500 requests/month (100/day), 1 req/s, 0 full-history queries/month, 0 live refreshes/day, no DNS/cert change timelines.\n- **Pro API Access** — 15,000 requests/month (no daily sub-cap), 5 req/s, 5 full-history queries/month, 250 live refreshes/day, DNS/cert change timelines included.\n\nErrors use RFC-7807 `application/problem+json` with a machine-readable `type`.","contact":{"name":"who.is API docs","url":"https://who.is/docs/api"}},"servers":[{"url":"https://api.who.is","description":"Production"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Lookups","description":"Parsed WHOIS and normalized RDAP."},{"name":"History","description":"Domain history summary from the archive."},{"name":"DNS","description":"Current DNS records and change timeline."},{"name":"Certificates","description":"Current TLS certificate and change timeline."}],"paths":{"/v1/whois/{domain}":{"get":{"operationId":"getWhois","summary":"Parsed WHOIS record","description":"Snapshot-first parsed WHOIS: registrar, statuses, events, nameservers, and redacted-as-received contacts. Serves a stored snapshot (≤30 days) unless `?live=true` forces an upstream refresh. Raw upstream text is never returned.","tags":["Lookups"],"parameters":[{"name":"domain","in":"path","required":true,"description":"The domain to look up, e.g. `example.com`. A subdomain is resolved to its registrable domain (`www.example.com` → `example.com`).","schema":{"type":"string"},"example":"example.com"},{"name":"live","in":"query","required":false,"description":"Set to `true` to force a fresh upstream lookup (bounded by a 1-hour floor). Starter-only — a free key is denied with `plan_required`. Any other value is a normal snapshot lookup.","schema":{"type":"string","enum":["true"]},"example":"true"}],"responses":{"200":{"description":"Success.","headers":{"X-RateLimit-Limit":{"description":"Your plan's monthly request quota.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current month.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhoisResponse"},"example":{"domain":"example.com","registrar":"Example Registrar, Inc.","whois_server":"whois.example-registrar.com","referral_url":"https://example-registrar.com","statuses":["clientTransferProhibited"],"snapshot_time":"2026-07-30T12:00:00.000Z","events":[{"event_action":"registration","event_date":"2003-01-01T00:00:00.000Z"},{"event_action":"expiration","event_date":"2027-01-01T00:00:00.000Z"}],"nameservers":[{"ldh_name":"ns1.example.com"},{"ldh_name":"ns2.example.com"}],"contacts":{"registrant":{"organization":"Acme","state_province":"CA","country":"US","email":"jane@acme.test"}}}}}},"400":{"description":"Invalid domain. `type` is one of: invalid_domain.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"invalid_domain","title":"Invalid domain","status":400,"detail":"A human-readable explanation of what went wrong."}}}},"401":{"description":"Unauthorized. `type` is one of: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"unauthorized","title":"Unauthorized","status":401,"detail":"A human-readable explanation of what went wrong."}}}},"403":{"description":"Plan required. `type` is one of: plan_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"plan_required","title":"Plan required","status":403,"detail":"A human-readable explanation of what went wrong."}}}},"404":{"description":"Not found. `type` is one of: domain_not_available, not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"domain_not_available","title":"Not found","status":404,"detail":"A human-readable explanation of what went wrong."}}}},"429":{"description":"Rate limited. `type` is one of: rate_limited, quota_exceeded.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"rate_limited","title":"Rate limited","status":429,"detail":"A human-readable explanation of what went wrong."}}}},"502":{"description":"Upstream unavailable. `type` is one of: upstream_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"upstream_unavailable","title":"Upstream unavailable","status":502,"detail":"A human-readable explanation of what went wrong."}}}},"503":{"description":"Service unavailable. `type` is one of: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"service_unavailable","title":"Service unavailable","status":503,"detail":"A human-readable explanation of what went wrong."}}}}}}},"/v1/rdap/{domain}":{"get":{"operationId":"getRdap","summary":"Normalized RDAP record","description":"Snapshot-first normalized RDAP: entities (recursing through sub-entities), events, and nameservers. Serves a stored snapshot unless `?live=true` forces an upstream refresh. Never an upstream passthrough.","tags":["Lookups"],"parameters":[{"name":"domain","in":"path","required":true,"description":"The domain to look up, e.g. `example.com`. A subdomain is resolved to its registrable domain (`www.example.com` → `example.com`).","schema":{"type":"string"},"example":"example.com"},{"name":"live","in":"query","required":false,"description":"Set to `true` to force a fresh upstream lookup (bounded by a 1-hour floor). Starter-only — a free key is denied with `plan_required`. Any other value is a normal snapshot lookup.","schema":{"type":"string","enum":["true"]},"example":"true"}],"responses":{"200":{"description":"Success.","headers":{"X-RateLimit-Limit":{"description":"Your plan's monthly request quota.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current month.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RdapResponse"},"example":{"domain":"example.com","handle":"DOM-123","object_class_name":"domain","statuses":["active"],"rdap_conformance":["rdap_level_0"],"resource_url":"https://rdap.example/domain/example.com","snapshot_time":"2026-07-30T12:00:00.000Z","entities":[{"handle":"REG-1","roles":["registrar"],"fn":"Example Registrar","org":"Example Registrar, Inc.","country_code":"US","public_id_type":"IANA Registrar ID","public_id":"9999","child_entities":[{"handle":"ABUSE-1","roles":["abuse"],"email":"abuse@example.test"}]}],"events":[{"event_action":"registration","event_date":"2003-01-01T00:00:00.000Z"}],"nameservers":[{"ldh_name":"ns1.example.com"}]}}}},"400":{"description":"Invalid domain. `type` is one of: invalid_domain.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"invalid_domain","title":"Invalid domain","status":400,"detail":"A human-readable explanation of what went wrong."}}}},"401":{"description":"Unauthorized. `type` is one of: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"unauthorized","title":"Unauthorized","status":401,"detail":"A human-readable explanation of what went wrong."}}}},"403":{"description":"Plan required. `type` is one of: plan_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"plan_required","title":"Plan required","status":403,"detail":"A human-readable explanation of what went wrong."}}}},"404":{"description":"Not found. `type` is one of: domain_not_available, not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"domain_not_available","title":"Not found","status":404,"detail":"A human-readable explanation of what went wrong."}}}},"429":{"description":"Rate limited. `type` is one of: rate_limited, quota_exceeded.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"rate_limited","title":"Rate limited","status":429,"detail":"A human-readable explanation of what went wrong."}}}},"502":{"description":"Upstream unavailable. `type` is one of: upstream_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"upstream_unavailable","title":"Upstream unavailable","status":502,"detail":"A human-readable explanation of what went wrong."}}}},"503":{"description":"Service unavailable. `type` is one of: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"service_unavailable","title":"Service unavailable","status":503,"detail":"A human-readable explanation of what went wrong."}}}}}}},"/v1/domains/{domain}/history":{"get":{"operationId":"getDomainHistorySummary","summary":"Domain history summary","description":"A domain's history at a glance: snapshot, change, and registrar counts plus the first/last-seen window, drawn from our archive of 2B+ WHOIS/RDAP snapshots going back to 2003. Available on every plan; the full per-snapshot history is a separate endpoint.","tags":["History"],"parameters":[{"name":"domain","in":"path","required":true,"description":"The domain to look up, e.g. `example.com`. A subdomain is resolved to its registrable domain (`www.example.com` → `example.com`).","schema":{"type":"string"},"example":"example.com"}],"responses":{"200":{"description":"Success.","headers":{"X-RateLimit-Limit":{"description":"Your plan's monthly request quota.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current month.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistorySummaryResponse"},"example":{"domain":"example.com","snapshot_count":2741,"whois_snapshot_count":2000,"rdap_snapshot_count":741,"change_count":58,"registrar_count":4,"first_seen":"2003-01-01T00:00:00.000Z","last_seen":"2026-07-01T00:00:00.000Z","updated_at":"2026-07-30T00:00:00.000Z"}}}},"400":{"description":"Invalid domain. `type` is one of: invalid_domain.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"invalid_domain","title":"Invalid domain","status":400,"detail":"A human-readable explanation of what went wrong."}}}},"401":{"description":"Unauthorized. `type` is one of: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"unauthorized","title":"Unauthorized","status":401,"detail":"A human-readable explanation of what went wrong."}}}},"404":{"description":"Not found. `type` is one of: domain_not_available, not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"domain_not_available","title":"Not found","status":404,"detail":"A human-readable explanation of what went wrong."}}}},"429":{"description":"Rate limited. `type` is one of: rate_limited, quota_exceeded.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"rate_limited","title":"Rate limited","status":429,"detail":"A human-readable explanation of what went wrong."}}}},"503":{"description":"Service unavailable. `type` is one of: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"service_unavailable","title":"Service unavailable","status":503,"detail":"A human-readable explanation of what went wrong."}}}}}}},"/v1/dns/{domain}":{"get":{"operationId":"getDnsCurrent","summary":"Current DNS records","description":"The zone's current records with hosting classification. Observation begins at first interest — a first query for an unobserved domain resolves it live, records the observation, and serves it; a domain with no DNS records returns `not_found`.","tags":["DNS"],"parameters":[{"name":"domain","in":"path","required":true,"description":"The domain to look up, e.g. `example.com`. A subdomain is resolved to its registrable domain (`www.example.com` → `example.com`).","schema":{"type":"string"},"example":"example.com"}],"responses":{"200":{"description":"Success.","headers":{"X-RateLimit-Limit":{"description":"Your plan's monthly request quota.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current month.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DnsCurrentResponse"},"example":{"domain":"example.com","hostnames":[{"hostname":"example.com","hosting_class":"direct","provider_name":null,"first_seen":"2025-01-01T00:00:00.000Z","last_seen":"2026-07-29T00:00:00.000Z","records":{"A":["1.2.3.4"],"NS":["ns1.example.com","ns2.example.com"]}},{"hostname":"www.example.com","hosting_class":"cdn","provider_name":"Cloudflare","first_seen":"2025-02-01T00:00:00.000Z","last_seen":"2026-07-30T00:00:00.000Z","records":{"CNAME":["example.com"]}}],"snapshot_time":"2026-07-30T00:00:00.000Z"}}}},"400":{"description":"Invalid domain. `type` is one of: invalid_domain.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"invalid_domain","title":"Invalid domain","status":400,"detail":"A human-readable explanation of what went wrong."}}}},"401":{"description":"Unauthorized. `type` is one of: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"unauthorized","title":"Unauthorized","status":401,"detail":"A human-readable explanation of what went wrong."}}}},"404":{"description":"Not found. `type` is one of: domain_not_available, not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"domain_not_available","title":"Not found","status":404,"detail":"A human-readable explanation of what went wrong."}}}},"429":{"description":"Rate limited. `type` is one of: rate_limited, quota_exceeded.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"rate_limited","title":"Rate limited","status":429,"detail":"A human-readable explanation of what went wrong."}}}},"503":{"description":"Service unavailable. `type` is one of: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"service_unavailable","title":"Service unavailable","status":503,"detail":"A human-readable explanation of what went wrong."}}}}}}},"/v1/dns/{domain}/changes":{"get":{"operationId":"getDnsChanges","summary":"DNS change timeline","description":"The zone's change-only DNS timeline from our store-on-change ledger. An empty timeline is a valid 200 with an empty `changes` array — the coverage fields report how far back our observations go. Requires Pro API Access: on the Free plan this endpoint returns `plan_required` (403).","tags":["DNS"],"parameters":[{"name":"domain","in":"path","required":true,"description":"The domain to look up, e.g. `example.com`. A subdomain is resolved to its registrable domain (`www.example.com` → `example.com`).","schema":{"type":"string"},"example":"example.com"}],"responses":{"200":{"description":"Success.","headers":{"X-RateLimit-Limit":{"description":"Your plan's monthly request quota.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current month.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DnsChangesResponse"},"example":{"domain":"example.com","changes":[{"kind":"initial","hostname":"example.com","first_seen":"2024-06-01T00:00:00.000Z","last_seen":"2025-01-01T00:00:00.000Z","hosting_class":"direct","provider_name":null,"current":false,"change_summary":null,"records":{"A":["1.1.1.1"]}},{"kind":"change","hostname":"example.com","first_seen":"2025-01-01T00:00:00.000Z","last_seen":"2026-07-30T00:00:00.000Z","hosting_class":"direct","provider_name":null,"current":true,"change_summary":{"added_rrtypes":["A"],"removed_rrtypes":[],"changed_rrtypes":[],"detail":["A: added 2.2.2.2"]},"records":{"A":["1.1.1.1","2.2.2.2"]}}],"observed_since":"2024-06-01T00:00:00.000Z","observation_count":2,"snapshot_time":"2026-07-30T00:00:00.000Z"}}}},"400":{"description":"Invalid domain. `type` is one of: invalid_domain.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"invalid_domain","title":"Invalid domain","status":400,"detail":"A human-readable explanation of what went wrong."}}}},"401":{"description":"Unauthorized. `type` is one of: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"unauthorized","title":"Unauthorized","status":401,"detail":"A human-readable explanation of what went wrong."}}}},"403":{"description":"Plan required. `type` is one of: plan_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"plan_required","title":"Plan required","status":403,"detail":"A human-readable explanation of what went wrong."}}}},"404":{"description":"Not found. `type` is one of: domain_not_available.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"domain_not_available","title":"Not found","status":404,"detail":"A human-readable explanation of what went wrong."}}}},"429":{"description":"Rate limited. `type` is one of: rate_limited, quota_exceeded.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"rate_limited","title":"Rate limited","status":429,"detail":"A human-readable explanation of what went wrong."}}}},"503":{"description":"Service unavailable. `type` is one of: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"service_unavailable","title":"Service unavailable","status":503,"detail":"A human-readable explanation of what went wrong."}}}}}}},"/v1/certificates/{domain}":{"get":{"operationId":"getCertificateCurrent","summary":"Current TLS certificate","description":"The current leaf certificate for a host: issuer, subject, SANs, validity window, and structural chain status. Serves the stored certificate; a first query for an unobserved host probes it live (at most once per 24h), records the observation, and serves it. Certificates are host-specific, so a subdomain is looked up as-is.","tags":["Certificates"],"parameters":[{"name":"domain","in":"path","required":true,"description":"The host to look up, e.g. `example.com` or `shop.example.com`. Certificates are host-specific, so a subdomain is looked up as-is.","schema":{"type":"string"},"example":"example.com"}],"responses":{"200":{"description":"Success.","headers":{"X-RateLimit-Limit":{"description":"Your plan's monthly request quota.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current month.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertCurrentResponse"},"example":{"domain":"example.com","subject_cn":"example.com","issuer_ca":"Let's Encrypt","issuer_cn":"R3","issuer_org":"Let's Encrypt","sans":["example.com","www.example.com"],"serial":"AB12","fingerprint_sha256":"AA:BB:CC","valid_from":"2026-05-01T00:00:00.000Z","valid_to":"2026-08-01T00:00:00.000Z","key_algo":"EC","key_bits":256,"self_signed":false,"chain_status":"trusted","chain_issuers":["R3","ISRG Root X1"],"snapshot_time":"2026-07-30T00:00:00.000Z"}}}},"400":{"description":"Invalid domain. `type` is one of: invalid_domain.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"invalid_domain","title":"Invalid domain","status":400,"detail":"A human-readable explanation of what went wrong."}}}},"401":{"description":"Unauthorized. `type` is one of: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"unauthorized","title":"Unauthorized","status":401,"detail":"A human-readable explanation of what went wrong."}}}},"404":{"description":"Not found. `type` is one of: domain_not_available, not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"domain_not_available","title":"Not found","status":404,"detail":"A human-readable explanation of what went wrong."}}}},"429":{"description":"Rate limited. `type` is one of: rate_limited, quota_exceeded.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"rate_limited","title":"Rate limited","status":429,"detail":"A human-readable explanation of what went wrong."}}}},"503":{"description":"Service unavailable. `type` is one of: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"service_unavailable","title":"Service unavailable","status":503,"detail":"A human-readable explanation of what went wrong."}}}}}}},"/v1/certificates/{domain}/changes":{"get":{"operationId":"getCertificateChanges","summary":"Certificate change timeline","description":"The host's certificate change timeline from our store-on-change ledger. An empty timeline is a valid 200 with an empty `changes` array — the coverage fields report observation depth. Requires Pro API Access: on the Free plan this endpoint returns `plan_required` (403).","tags":["Certificates"],"parameters":[{"name":"domain","in":"path","required":true,"description":"The host to look up, e.g. `example.com` or `shop.example.com`. Certificates are host-specific, so a subdomain is looked up as-is.","schema":{"type":"string"},"example":"example.com"}],"responses":{"200":{"description":"Success.","headers":{"X-RateLimit-Limit":{"description":"Your plan's monthly request quota.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current month.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertChangesResponse"},"example":{"domain":"example.com","changes":[{"kind":"initial","first_seen":"2026-02-01T00:00:00.000Z","last_seen":"2026-05-01T00:00:00.000Z","current":false,"change_summary":null,"cert":{"subject_cn":"example.com","issuer_ca":"Let's Encrypt","issuer_cn":"R3","issuer_org":"Let's Encrypt","sans":["example.com","www.example.com"],"serial":"AB12","fingerprint_sha256":"OLD:FP","valid_from":"2026-05-01T00:00:00.000Z","valid_to":"2026-08-01T00:00:00.000Z","key_algo":"EC","key_bits":256,"self_signed":false,"chain_status":"trusted","chain_issuers":["R3","ISRG Root X1"]}},{"kind":"change","first_seen":"2026-05-01T00:00:00.000Z","last_seen":"2026-07-30T00:00:00.000Z","current":true,"change_summary":{"affected":["fingerprint"],"detail":["fingerprint rotated"]},"cert":{"subject_cn":"example.com","issuer_ca":"Let's Encrypt","issuer_cn":"R3","issuer_org":"Let's Encrypt","sans":["example.com","www.example.com"],"serial":"AB12","fingerprint_sha256":"AA:BB:CC","valid_from":"2026-05-01T00:00:00.000Z","valid_to":"2026-08-01T00:00:00.000Z","key_algo":"EC","key_bits":256,"self_signed":false,"chain_status":"trusted","chain_issuers":["R3","ISRG Root X1"]}}],"observed_since":"2026-02-01T00:00:00.000Z","observation_count":2,"snapshot_time":"2026-07-30T00:00:00.000Z"}}}},"400":{"description":"Invalid domain. `type` is one of: invalid_domain.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"invalid_domain","title":"Invalid domain","status":400,"detail":"A human-readable explanation of what went wrong."}}}},"401":{"description":"Unauthorized. `type` is one of: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"unauthorized","title":"Unauthorized","status":401,"detail":"A human-readable explanation of what went wrong."}}}},"403":{"description":"Plan required. `type` is one of: plan_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"plan_required","title":"Plan required","status":403,"detail":"A human-readable explanation of what went wrong."}}}},"404":{"description":"Not found. `type` is one of: domain_not_available.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"domain_not_available","title":"Not found","status":404,"detail":"A human-readable explanation of what went wrong."}}}},"429":{"description":"Rate limited. `type` is one of: rate_limited, quota_exceeded.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"rate_limited","title":"Rate limited","status":429,"detail":"A human-readable explanation of what went wrong."}}}},"503":{"description":"Service unavailable. `type` is one of: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"service_unavailable","title":"Service unavailable","status":503,"detail":"A human-readable explanation of what went wrong."}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"wis_live_<40 base62>","description":"Send your API key as `Authorization: Bearer wis_live_...`. Create a free key at https://who.is/account/api."}},"schemas":{"Event":{"type":"object","properties":{"event_action":{"type":"string"},"event_date":{"type":"string","format":"date-time"}},"required":["event_action","event_date"],"additionalProperties":false},"Nameserver":{"type":"object","properties":{"ldh_name":{"type":"string"}},"required":["ldh_name"],"additionalProperties":false},"WhoisContact":{"type":"object","description":"A WHOIS contact block. Every field is optional — upstream data is partial and redacted-as-received; present keys are emitted verbatim.","properties":{"name":{"type":"string"},"organization":{"type":"string"},"address1":{"type":"string"},"address2":{"type":"string"},"city":{"type":"string"},"state_province":{"type":"string"},"postal_code":{"type":"string"},"country":{"type":"string"},"phone":{"type":"string"},"fax":{"type":"string"},"email":{"type":"string"}},"required":[],"additionalProperties":false},"WhoisResponse":{"type":"object","properties":{"domain":{"type":"string"},"registrar":{"type":["string","null"]},"whois_server":{"type":["string","null"]},"referral_url":{"type":["string","null"]},"statuses":{"type":"array","items":{"type":"string"}},"snapshot_time":{"type":"string","format":"date-time"},"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"nameservers":{"type":"array","items":{"$ref":"#/components/schemas/Nameserver"}},"contacts":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/WhoisContact"},"description":"Contacts keyed by the role the parser found (registrant/admin/tech/…)."}},"required":["domain","registrar","whois_server","referral_url","statuses","snapshot_time","events","nameservers","contacts"],"additionalProperties":false},"RdapEntity":{"type":"object","description":"A normalized RDAP entity; recurses through `child_entities`.","properties":{"handle":{"type":["string","null"]},"roles":{"type":"array","items":{"type":"string"}},"fn":{"type":["string","null"]},"kind":{"type":["string","null"]},"email":{"type":["string","null"]},"tel":{"type":["string","null"]},"fax":{"type":["string","null"]},"org":{"type":["string","null"]},"full_address":{"type":["string","null"]},"address_array":{"type":["array","null"],"items":{"type":"string"}},"country_code":{"type":["string","null"]},"contact_uri":{"type":["string","null"]},"public_id_type":{"type":["string","null"]},"public_id":{"type":["string","null"]},"child_entities":{"type":"array","items":{"$ref":"#/components/schemas/RdapEntity"}}},"required":["roles"],"additionalProperties":false},"RdapResponse":{"type":"object","properties":{"domain":{"type":"string"},"handle":{"type":["string","null"]},"object_class_name":{"type":["string","null"]},"statuses":{"type":"array","items":{"type":"string"}},"rdap_conformance":{"type":"array","items":{"type":"string"}},"resource_url":{"type":["string","null"]},"snapshot_time":{"type":"string","format":"date-time"},"entities":{"type":"array","items":{"$ref":"#/components/schemas/RdapEntity"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"nameservers":{"type":"array","items":{"$ref":"#/components/schemas/Nameserver"}}},"required":["domain","handle","object_class_name","statuses","rdap_conformance","resource_url","snapshot_time","entities","events","nameservers"],"additionalProperties":false},"HistorySummaryResponse":{"type":"object","properties":{"domain":{"type":"string"},"snapshot_count":{"type":"integer"},"whois_snapshot_count":{"type":"integer"},"rdap_snapshot_count":{"type":"integer"},"change_count":{"type":"integer"},"registrar_count":{"type":"integer"},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["domain","snapshot_count","whois_snapshot_count","rdap_snapshot_count","change_count","registrar_count","first_seen","last_seen","updated_at"],"additionalProperties":false},"DnsChangeSummary":{"type":"object","properties":{"added_rrtypes":{"type":"array","items":{"type":"string"}},"removed_rrtypes":{"type":"array","items":{"type":"string"}},"changed_rrtypes":{"type":"array","items":{"type":"string"}},"detail":{"type":"array","items":{"type":"string"}}},"required":["added_rrtypes","removed_rrtypes","changed_rrtypes","detail"],"additionalProperties":false},"DnsHostname":{"type":"object","properties":{"hostname":{"type":"string"},"hosting_class":{"type":"string"},"provider_name":{"type":["string","null"]},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"},"records":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}},"description":"rrtype → its record-data strings (e.g. `{ \"A\": [\"1.2.3.4\"] }`)."}},"required":["hostname","hosting_class","provider_name","first_seen","last_seen","records"],"additionalProperties":false},"DnsCurrentResponse":{"type":"object","properties":{"domain":{"type":"string"},"hostnames":{"type":"array","items":{"$ref":"#/components/schemas/DnsHostname"}},"snapshot_time":{"type":"string","format":"date-time"}},"required":["domain","hostnames","snapshot_time"],"additionalProperties":false},"DnsChangeEntry":{"type":"object","properties":{"kind":{"type":"string","enum":["initial","change"]},"hostname":{"type":"string"},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"},"hosting_class":{"type":"string"},"provider_name":{"type":["string","null"]},"current":{"type":"boolean"},"change_summary":{"$ref":"#/components/schemas/DnsChangeSummary","description":"null on the initial state."},"records":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}},"description":"rrtype → its record-data strings (e.g. `{ \"A\": [\"1.2.3.4\"] }`)."}},"required":["kind","hostname","first_seen","last_seen","hosting_class","provider_name","current","change_summary","records"],"additionalProperties":false},"DnsChangesResponse":{"type":"object","properties":{"domain":{"type":"string"},"changes":{"type":"array","items":{"$ref":"#/components/schemas/DnsChangeEntry"}},"observed_since":{"type":["string","null"],"format":"date-time"},"observation_count":{"type":"integer"},"snapshot_time":{"type":["string","null"],"format":"date-time"}},"required":["domain","changes","observed_since","observation_count","snapshot_time"],"additionalProperties":false},"Cert":{"type":"object","properties":{"subject_cn":{"type":["string","null"]},"issuer_ca":{"type":["string","null"]},"issuer_cn":{"type":["string","null"]},"issuer_org":{"type":["string","null"]},"sans":{"type":"array","items":{"type":"string"}},"serial":{"type":"string"},"fingerprint_sha256":{"type":"string"},"valid_from":{"type":"string","format":"date-time"},"valid_to":{"type":"string","format":"date-time"},"key_algo":{"type":["string","null"]},"key_bits":{"type":["integer","null"]},"self_signed":{"type":"boolean"},"chain_status":{"type":"string"},"chain_issuers":{"type":"array","items":{"type":"string"}}},"required":["subject_cn","issuer_ca","issuer_cn","issuer_org","sans","serial","fingerprint_sha256","valid_from","valid_to","key_algo","key_bits","self_signed","chain_status","chain_issuers"],"additionalProperties":false},"CertCurrentResponse":{"type":"object","properties":{"domain":{"type":"string"},"subject_cn":{"type":["string","null"]},"issuer_ca":{"type":["string","null"]},"issuer_cn":{"type":["string","null"]},"issuer_org":{"type":["string","null"]},"sans":{"type":"array","items":{"type":"string"}},"serial":{"type":"string"},"fingerprint_sha256":{"type":"string"},"valid_from":{"type":"string","format":"date-time"},"valid_to":{"type":"string","format":"date-time"},"key_algo":{"type":["string","null"]},"key_bits":{"type":["integer","null"]},"self_signed":{"type":"boolean"},"chain_status":{"type":"string"},"chain_issuers":{"type":"array","items":{"type":"string"}},"snapshot_time":{"type":"string","format":"date-time"}},"required":["domain","subject_cn","issuer_ca","issuer_cn","issuer_org","sans","serial","fingerprint_sha256","valid_from","valid_to","key_algo","key_bits","self_signed","chain_status","chain_issuers","snapshot_time"],"additionalProperties":false},"CertChangeSummary":{"type":"object","properties":{"affected":{"type":"array","items":{"type":"string"}},"detail":{"type":"array","items":{"type":"string"}}},"required":["affected","detail"],"additionalProperties":false},"CertChangeEntry":{"type":"object","properties":{"kind":{"type":"string","enum":["initial","change"]},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"},"current":{"type":"boolean"},"change_summary":{"$ref":"#/components/schemas/CertChangeSummary","description":"null on the initial observation."},"cert":{"$ref":"#/components/schemas/Cert"}},"required":["kind","first_seen","last_seen","current","change_summary","cert"],"additionalProperties":false},"CertChangesResponse":{"type":"object","properties":{"domain":{"type":"string"},"changes":{"type":"array","items":{"$ref":"#/components/schemas/CertChangeEntry"}},"observed_since":{"type":["string","null"],"format":"date-time"},"observation_count":{"type":"integer"},"snapshot_time":{"type":["string","null"],"format":"date-time"}},"required":["domain","changes","observed_since","observation_count","snapshot_time"],"additionalProperties":false},"ProblemDetails":{"type":"object","description":"RFC-7807 problem document returned on every error. `type` is the machine-readable error code; `title` and `status` describe it; `detail` is a human message.","properties":{"type":{"type":"string","enum":["invalid_domain","unauthorized","plan_required","not_found","domain_not_available","rate_limited","quota_exceeded","upstream_unavailable","service_unavailable"]},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"}},"required":["type","title","status","detail"],"additionalProperties":false}}}}