openapi: 3.1.1
info:
  title: Have I Been Squatted API
  version: v1
  summary: OpenAPI description for the public production v1 HTTP API.
  description: >
    This specification documents the HTTP wire format used by the v1 API.
    Lookup endpoints stream newline-delimited JSON objects. Certificate
    Transparency and usage endpoints return regular JSON bodies.
  contact:
    name: Have I Been Squatted
    email: hello@haveibeensquatted.com
    url: https://haveibeensquatted.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
externalDocs:
  description: API guides and account documentation
  url: https://docs.haveibeensquatted.com/guides/api/
servers:
  - url: https://api.haveibeensquatted.com/v1
    description: Production v1 API
security:
  - bearerAuth: []
tags:
  - name: Lookup
    description: Streaming domain lookup and analysis endpoints.
  - name: Certificate Transparency
    description: Search and hydrate certificate transparency records.
  - name: Usage
    description: Usage reporting for the authenticated API key.
paths:
  /lookup/squat/{domain}:
    get:
      tags:
        - Lookup
      summary: Look up typosquatted permutations for a domain.
      description: >
        Streams newline-delimited JSON objects as work completes. Each line is a
        message with an `op` field and operation-specific `data`.
      operationId: lookupSquat
      parameters:
        - $ref: "#/components/parameters/DomainPath"
      responses:
        "200":
          description: Streaming line-delimited lookup result messages.
          content:
            application/x-ndjson:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/StreamMessage"
              examples:
                sample:
                  summary: Progress followed by a GeoIP result
                  value:
                    - op: Meta
                      data:
                        kind: Progress
                        data:
                          - 12
                          - 100
                    - op: GeoIp
                      permutation:
                        domain:
                          fqdn: examp1e.com
                          tld: com
                          domain: examp1e
                        kind: Replacement
                      data:
                        ip: 203.0.113.10
                        asn:
                          number: 64496
                          organization: Example Networks
                        country:
                          continent: North America
                          iso_code: US
          x-line-delimited: true
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/TooManyRequests"
  /lookup/nxdomain/{domain}:
    get:
      tags:
        - Lookup
      summary: Look up unregistered permutations for a domain.
      description: >
        Streams newline-delimited JSON objects as work completes. Each line is a
        message with an `op` field and operation-specific `data`.
      operationId: lookupNxdomain
      parameters:
        - $ref: "#/components/parameters/DomainPath"
      responses:
        "200":
          description: Streaming line-delimited lookup result messages.
          content:
            application/x-ndjson:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/StreamMessage"
              examples:
                sample:
                  summary: NXDOMAIN metadata message
                  value:
                    - op: Nxdomain
                      permutation:
                        domain:
                          fqdn: exampel.com
                          tld: com
                          domain: exampel
                        kind: Transposition
                      data:
                        query:
                          name: exampel.com
                          type: A
                        trusted: false
                        soa:
                          mname: ns1.example.net
          x-line-delimited: true
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/TooManyRequests"
  /analyze/{domain}:
    get:
      tags:
        - Lookup
      summary: Analyze a domain for infrastructure and threat signals.
      description: >
        Streams newline-delimited JSON objects as work completes. Each line is a
        message with an `op` field and operation-specific `data`.
      operationId: analyzeDomain
      parameters:
        - $ref: "#/components/parameters/DomainPath"
      responses:
        "200":
          description: Streaming line-delimited analysis messages.
          content:
            application/x-ndjson:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/StreamMessage"
              examples:
                sample:
                  summary: DNS and classification signals
                  value:
                    - op: Dns
                      data:
                        a:
                          - 203.0.113.10
                        aaaa: []
                        mx: []
                        txt:
                          - v=spf1 -all
                        cname: []
                        ns:
                          - ns1.example.net
                    - op: Classification
                      data:
                        legitimate: 0.02
                        phishing: 0.96
                        parked: 0.02
          x-line-delimited: true
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/TooManyRequests"
  /ct/search:
    get:
      tags:
        - Certificate Transparency
      summary: Search certificate transparency names by pattern.
      description: >
        Returns a JSON array of matching names. The response may include the
        `X-Has-More-Value` header when more matches exist than were returned in
        the body for the requested limit.
      operationId: ctSearch
      parameters:
        - $ref: "#/components/parameters/CtPattern"
        - $ref: "#/components/parameters/CtKind"
        - $ref: "#/components/parameters/CtLimit"
        - $ref: "#/components/parameters/IncludePrecert"
        - $ref: "#/components/parameters/CtField"
      responses:
        "200":
          description: Certificate transparency search results.
          headers:
            X-Has-More-Value:
              $ref: "#/components/headers/XHasMoreValue"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CTSearchResult"
              examples:
                sampleResults:
                  summary: Search results with occurrence metadata
                  value:
                    - name: google.example
                      labels:
                        tld: example
                        etld1: google.example
                        domain: google
                      is_precert: false
                      log_id: 86
                      index: 3800460171
                      occurrences_count: 1
                      last_seen_ts: 1776777317
                      occurrences:
                        - log_id: 86
                          kind: 0
                          ts_sec: 1776777317
                          index: 3800460171
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/TooManyRequests"
  /ct/search/domains:
    get:
      tags:
        - Certificate Transparency
      summary: Search certificate transparency data for exact FQDNs.
      description: >
        Repeat the `fqdn` query parameter to request multiple exact names in one
        call.
      operationId: ctSearchDomains
      parameters:
        - $ref: "#/components/parameters/CtFqdnList"
        - $ref: "#/components/parameters/IncludePrecert"
      responses:
        "200":
          description: Certificate transparency search results for the requested names.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CTSearchResult"
              examples:
                sampleResults:
                  summary: Exact-name lookup
                  value:
                    - name: www.example.com
                      labels:
                        tld: com
                        etld1: example.com
                        domain: example
                        subdomain: www
                      is_precert: false
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/TooManyRequests"
  /ct/hydrate:
    get:
      tags:
        - Certificate Transparency
      summary: Hydrate certificate transparency occurrences into certificate details.
      operationId: ctHydrate
      parameters:
        - $ref: "#/components/parameters/CtOccurrenceList"
      responses:
        "200":
          description: Hydrated occurrence results.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/HydrateItem"
              examples:
                sampleResults:
                  summary: Hydrated certificate material
                  value:
                    - log_id: 86
                      index: 3800460171
                      cert:
                        fingerprint_sha256: 029c1fe2988ab96ab443daf7faec8a5d2a1781381f965921e5462be42589a3f7
                        serial: 5d1913cd13ae6797948d0241bfefd77a81c
                        subject_dn: CN=backbonerestored.info
                        issuer_dn: C=US, O=Let's Encrypt, CN=R13
                        not_before: 1776777317
                        not_after: 1784553316
                        ttl_days: 89
                        key_alg: 1.2.840.113549.1.1.1
                        key_size_bits: 4104
                        sig_alg_oid: 1.2.840.113549.1.1.11
                        san_dns:
                          - backbonerestored.info
                        san_dns_count: 1
                        san_ip: []
                        is_ca: false
                        path_len: null
                        policy_oids: []
                        ocsp_uris: []
                        crl_dp: []
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/TooManyRequests"
  /meta/usage:
    get:
      tags:
        - Usage
      summary: Retrieve usage totals and hourly breakdown.
      operationId: getUsage
      parameters:
        - $ref: "#/components/parameters/UsageWindow"
      responses:
        "200":
          description: Usage information for the requested window.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageResponse"
              examples:
                sampleUsage:
                  summary: 24-hour usage window
                  value:
                    period:
                      start: "2026-04-21T10:00:00Z"
                      end: "2026-04-22T10:00:00Z"
                    totals:
                      lookup_requests: 4
                      ct_requests: 0
                      total_requests: 4
                    hourly:
                      - timestamp: "2026-04-22T10:00:00Z"
                        lookup_requests: 4
                        ct_requests: 0
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/TooManyRequests"
  /v1/retrieve/save/{uuid}:
    put:
      tags:
        - Lookup
      summary: Extend retained lookup result retention.
      operationId: saveLookupResult
      parameters:
        - $ref: "#/components/parameters/StoredResultUuid"
        - $ref: "#/components/parameters/RetrievalContentType"
      responses:
        "200":
          description: Updated retention metadata.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SaveLookupResultResponse"
            text/csv:
              schema:
                type: string
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
  /v1/retrieve/{uuid}:
    get:
      tags:
        - Lookup
      summary: Fetch a retained lookup result as NDJSON.
      operationId: retrieveLookupResultNdjsonDefault
      parameters:
        - $ref: "#/components/parameters/StoredResultUuid"
      responses:
        "200":
          description: Retained lookup result as NDJSON events.
          content:
            application/x-ndjson:
              schema:
                type: string
                description: Newline-delimited JSON lookup events.
        "404":
          description: Stored result was not found.
  /v1/retrieve/{uuid}/ndjson:
    get:
      tags:
        - Lookup
      summary: Fetch a retained lookup result as NDJSON.
      operationId: retrieveLookupResultNdjson
      parameters:
        - $ref: "#/components/parameters/StoredResultUuid"
      responses:
        "200":
          description: Retained lookup result as NDJSON events.
          content:
            application/x-ndjson:
              schema:
                type: string
                description: Newline-delimited JSON lookup events.
        "404":
          description: Stored result was not found.
  /v1/retrieve/{uuid}/json:
    get:
      tags:
        - Lookup
      summary: Fetch a retained lookup result as merged JSON.
      operationId: retrieveLookupResultJson
      parameters:
        - $ref: "#/components/parameters/StoredResultUuid"
      responses:
        "200":
          description: Retained lookup result as merged JSON.
          content:
            application/json:
              schema:
                type: string
                description: Merged lookup result object.
        "404":
          description: Stored result was not found.
  /v1/retrieve/{uuid}/csv:
    get:
      tags:
        - Lookup
      summary: Fetch a retained lookup result as CSV.
      operationId: retrieveLookupResultCsv
      parameters:
        - $ref: "#/components/parameters/StoredResultUuid"
      responses:
        "200":
          description: Retained lookup result as CSV.
          content:
            text/csv:
              schema:
                type: string
        "404":
          description: Stored result was not found.
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: >
        Bearer API key created in the Have I Been Squatted application. Keys in
        current documentation begin with `ak_`.
  parameters:
    DomainPath:
      name: domain
      in: path
      required: true
      description: Domain name to look up or analyze.
      schema:
        type: string
      example: example.com
    CtPattern:
      name: pattern
      in: query
      required: true
      description: Search pattern used by Certificate Transparency search.
      schema:
        type: string
        minLength: 1
      example: ^example
    CtKind:
      name: kind
      in: query
      required: false
      description: Search strategy kind.
      schema:
        type: string
        default: regex
      example: regex
    CtLimit:
      name: limit
      in: query
      required: false
      description: Requested maximum number of search results.
      schema:
        type: integer
        minimum: 1
        default: 100
      example: 100
    IncludePrecert:
      name: include_precert
      in: query
      required: false
      description: Include precertificate-only results where supported.
      schema:
        type: boolean
        default: false
      example: false
    CtField:
      name: field
      in: query
      required: false
      description: Optional field selector for CT pattern search.
      schema:
        type: string
      example: cn
    CtFqdnList:
      name: fqdn
      in: query
      required: true
      description: One or more fully qualified domain names to search exactly.
      style: form
      explode: true
      schema:
        type: array
        minItems: 1
        items:
          type: string
      example:
        - www.example.com
        - api.example.com
    CtOccurrenceList:
      name: occ
      in: query
      required: true
      description: One or more occurrence IDs in `{log_id}:{index}` format.
      style: form
      explode: true
      schema:
        type: array
        minItems: 1
        items:
          type: string
          pattern: "^[0-9]+:[0-9]+$"
      example:
        - "86:3800460171"
    UsageWindow:
      name: t
      in: query
      required: false
      description: Usage window length in minutes.
      schema:
        type: integer
        minimum: 1
        default: 1440
      example: 1440
    StoredResultUuid:
      name: uuid
      in: path
      required: true
      description: Stored lookup result UUID emitted by a lookup stream.
      schema:
        type: string
        format: uuid
    RetrievalContentType:
      name: content-type
      in: query
      required: false
      description: Response format for retrieval-owned lookup result endpoints. `ndjson` is supported for retained result downloads and is the default there; history and save responses support `json` and `csv`.
      schema:
        type: string
        enum:
          - ndjson
          - json
          - csv
  headers:
    XHasMoreValue:
      description: >
        Present on `/ct/search` responses. `true` means the search found more
        matching names than were returned in the body for the effective limit.
      schema:
        type: string
        enum:
          - "true"
          - "false"
    RetryAfter:
      description: Seconds until the client should retry after a rate limit response.
      schema:
        type: number
    XRateLimitLimit:
      description: Maximum allowed request count for the current rate limit window.
      schema:
        type: integer
  responses:
    BadRequest:
      description: The request was invalid for the target endpoint.
    Unauthorized:
      description: Missing, expired, revoked, or otherwise invalid API key.
    Forbidden:
      description: The API key does not have the required scope for this endpoint.
    TooManyRequests:
      description: The API key is rate limited.
      headers:
        Retry-After:
          $ref: "#/components/headers/RetryAfter"
        X-RateLimit-Limit:
          $ref: "#/components/headers/XRateLimitLimit"
  schemas:
    Domain:
      type: object
      required:
        - fqdn
        - tld
        - domain
      properties:
        fqdn:
          type: string
        tld:
          type: string
        domain:
          type: string
      additionalProperties: false
    PermutationKind:
      type: string
      enum:
        - Addition
        - Bitsquatting
        - Hyphenation
        - Insertion
        - Omission
        - Repetition
        - Replacement
        - Subdomain
        - Transposition
        - VowelSwap
        - VowelShuffle
        - Keyword
        - Tld
        - Homoglyph
        - Mapped
        - DoubleVowelInsertion
        - CertificateTransparency
        - FauxTld
        - UserContext
        - Unknown
    Permutation:
      type: object
      required:
        - domain
        - kind
      properties:
        domain:
          $ref: "#/components/schemas/Domain"
        kind:
          $ref: "#/components/schemas/PermutationKind"
      additionalProperties: false
    MetaKind:
      type: string
      enum:
        - Progress
        - Error
        - Heartbeat
        - Done
        - Timeout
        - StoredResult
    MetaData:
      type: object
      required:
        - kind
      properties:
        kind:
          $ref: "#/components/schemas/MetaKind"
        data: {}
      additionalProperties: false
    GeoIpAsn:
      type:
        - object
        - "null"
      properties:
        number:
          type:
            - integer
            - "null"
        organization:
          type:
            - string
            - "null"
    GeoIpCountry:
      type:
        - object
        - "null"
      properties:
        continent:
          type:
            - string
            - "null"
        iso_code:
          type:
            - string
            - "null"
    GeoIpData:
      type: object
      required:
        - ip
      properties:
        ip:
          type: string
        asn:
          $ref: "#/components/schemas/GeoIpAsn"
        country:
          $ref: "#/components/schemas/GeoIpCountry"
      additionalProperties: false
    Classification:
      type: object
      required:
        - legitimate
        - phishing
        - parked
      properties:
        legitimate:
          type: number
        phishing:
          type: number
        parked:
          type: number
      additionalProperties: false
    DnsRecords:
      type: object
      properties:
        a:
          type: array
          items:
            type: string
        aaaa:
          type: array
          items:
            type: string
        mx:
          type: array
          items:
            type: string
        txt:
          type: array
          items:
            type: string
        cname:
          type: array
          items:
            type: string
        ns:
          type: array
          items:
            type: string
      additionalProperties: false
    SmtpMetadata:
      type: object
      required:
        - is_positive
        - response
      properties:
        is_positive:
          type: boolean
        response:
          type: string
      additionalProperties: false
    NxdomainMetadata:
      type: object
      required:
        - query
        - trusted
      properties:
        query:
          type: object
          additionalProperties: true
        trusted:
          type: boolean
        soa:
          oneOf:
            - type: object
              additionalProperties: true
            - type: "null"
      additionalProperties: false
    RedirectKind:
      type: string
      enum:
        - InitialRequest
        - Http
        - Javascript
        - Client
    CertificateDetails:
      type: object
      required:
        - subject_name
        - san_list
        - issuer
        - valid_from
        - valid_to
        - certificate_transparency_compliance
        - certificate_id
      properties:
        subject_name:
          type: string
        san_list:
          type: array
          items:
            type: string
        issuer:
          type: string
        valid_from:
          type: number
        valid_to:
          type: number
        certificate_transparency_compliance:
          type: string
        certificate_id:
          type: integer
        signed_certificate_timestamp_list:
          type: array
          items:
            type: object
            additionalProperties: true
        key_exchange_group:
          type:
            - string
            - "null"
        mac:
          type:
            - string
            - "null"
        protocol:
          type: string
        key_exchange:
          type: string
        cipher:
          type: string
      additionalProperties: false
    Redirect:
      type: object
      required:
        - url
        - kind
      properties:
        url:
          type: string
          format: uri
        kind:
          $ref: "#/components/schemas/RedirectKind"
        status:
          type:
            - integer
            - "null"
        certificate:
          oneOf:
            - $ref: "#/components/schemas/CertificateDetails"
            - type: "null"
      additionalProperties: false
    RedirectChain:
      type: array
      items:
        $ref: "#/components/schemas/Redirect"
    ParsedX509Certificate:
      type: object
      required:
        - fingerprint_sha256
        - serial
        - subject_dn
        - issuer_dn
        - not_before
        - not_after
        - ttl_days
        - key_alg
        - key_size_bits
        - sig_alg_oid
        - san_dns
        - san_dns_count
        - san_ip
        - is_ca
        - path_len
        - policy_oids
        - ocsp_uris
        - crl_dp
      properties:
        fingerprint_sha256:
          type: string
        serial:
          type: string
        subject_dn:
          type: string
        issuer_dn:
          type: string
        not_before:
          type: integer
        not_after:
          type: integer
        ttl_days:
          type: integer
        key_alg:
          type: string
        key_size_bits:
          type: integer
        sig_alg_oid:
          type: string
        san_dns:
          type: array
          items:
            type: string
        san_dns_count:
          type: integer
        san_ip:
          type: array
          items:
            type: string
        is_ca:
          type: boolean
        path_len:
          type:
            - integer
            - "null"
        policy_oids:
          type: array
          items:
            type: string
        ocsp_uris:
          type: array
          items:
            type: string
        crl_dp:
          type: array
          items:
            type: string
      additionalProperties: false
    PassiveDNSRecord:
      type: object
      required:
        - rrtype
        - rrname
        - rdata
        - time_first
        - time_last
        - count
      properties:
        rrtype:
          type: string
        rrname:
          type: string
        rdata:
          type: string
        time_first:
          type: integer
        time_last:
          type: integer
        count:
          type: integer
      additionalProperties: false
    PassiveTLSRecord:
      type: object
      required:
        - certificates
        - subjects
      properties:
        certificates:
          type: array
          items:
            type: string
        subjects:
          type: array
          items:
            type: string
      additionalProperties: false
    PassiveTLSMap:
      type: object
      additionalProperties:
        $ref: "#/components/schemas/PassiveTLSRecord"
    SearchResultLabels:
      type: object
      required:
        - tld
        - etld1
        - domain
      properties:
        tld:
          type: string
        etld1:
          type: string
        domain:
          type: string
        registrable_domain:
          type:
            - string
            - "null"
        subdomain:
          type:
            - string
            - "null"
      additionalProperties: false
    OccurrenceRec:
      type: object
      required:
        - log_id
        - kind
        - ts_sec
        - index
      properties:
        log_id:
          type: integer
        kind:
          type: integer
        ts_sec:
          type: integer
        index:
          type: integer
      additionalProperties: false
    HydratedOccurrence:
      type: object
      required:
        - log_id
        - kind
        - ts_sec
        - index
        - cert
      properties:
        log_id:
          type: integer
        kind:
          type: integer
        ts_sec:
          type: integer
        index:
          type: integer
        cert:
          $ref: "#/components/schemas/ParsedX509Certificate"
      additionalProperties: false
    CTSearchResult:
      type: object
      required:
        - name
        - labels
        - is_precert
      properties:
        name:
          type: string
        labels:
          $ref: "#/components/schemas/SearchResultLabels"
        is_precert:
          type: boolean
        log_id:
          type:
            - integer
            - "null"
        index:
          type:
            - integer
            - "null"
        occurrences_count:
          type:
            - integer
            - "null"
        last_seen_ts:
          type:
            - integer
            - "null"
        occurrences:
          oneOf:
            - type: "null"
            - type: array
              items:
                oneOf:
                  - $ref: "#/components/schemas/OccurrenceRec"
                  - $ref: "#/components/schemas/HydratedOccurrence"
        cert:
          oneOf:
            - $ref: "#/components/schemas/ParsedX509Certificate"
            - type: "null"
      additionalProperties: false
    HydrateItem:
      type: object
      required:
        - log_id
        - index
      properties:
        log_id:
          type: integer
        index:
          type: integer
        cert:
          oneOf:
            - $ref: "#/components/schemas/ParsedX509Certificate"
            - type: "null"
        error:
          type:
            - string
            - "null"
      additionalProperties: false
    UsagePeriod:
      type: object
      required:
        - start
        - end
      properties:
        start:
          type: string
          format: date-time
        end:
          type: string
          format: date-time
      additionalProperties: false
    UsageTotals:
      type: object
      required:
        - lookup_requests
        - ct_requests
        - total_requests
      properties:
        lookup_requests:
          type: integer
        ct_requests:
          type: integer
        total_requests:
          type: integer
      additionalProperties: false
    HourlyUsage:
      type: object
      required:
        - timestamp
        - lookup_requests
        - ct_requests
      properties:
        timestamp:
          type: string
          format: date-time
        lookup_requests:
          type: integer
        ct_requests:
          type: integer
      additionalProperties: false
    UsageResponse:
      type: object
      required:
        - period
        - totals
        - hourly
      properties:
        period:
          $ref: "#/components/schemas/UsagePeriod"
        totals:
          $ref: "#/components/schemas/UsageTotals"
        hourly:
          type: array
          items:
            $ref: "#/components/schemas/HourlyUsage"
      additionalProperties: false
    SaveLookupResultResponse:
      type: object
      required:
        - uuid
        - ttl
        - saved_at
      properties:
        uuid:
          type: string
          format: uuid
        ttl:
          type: integer
          description: Unix timestamp when the retained result expires.
        saved_at:
          type: integer
          description: Unix timestamp when retention was extended.
      additionalProperties: false
    Operation:
      type: string
      enum:
        - Levenshtein
        - GeoIp
        - IpEnumeration
        - HttpBanner
        - Rdap
        - WhoIs
        - Classification
        - Meta
        - Screenshot
        - Dns
        - Technologies
        - RedirectChain
        - RegistrationMetadata
        - Nxdomain
        - MxCheck
        - OriginX509
        - PassiveDns
        - PassiveTls
        - CertificateTransparency
    StreamMessageBase:
      type: object
      required:
        - op
      properties:
        op:
          $ref: "#/components/schemas/Operation"
        permutation:
          oneOf:
            - $ref: "#/components/schemas/Permutation"
            - type: "null"
    MetaStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: Meta
            data:
              oneOf:
                - $ref: "#/components/schemas/MetaData"
                - type: "null"
    GeoIpStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: GeoIp
            data:
              oneOf:
                - $ref: "#/components/schemas/GeoIpData"
                - type: "null"
    ClassificationStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: Classification
            data:
              oneOf:
                - $ref: "#/components/schemas/Classification"
                - type: "null"
    DnsStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: Dns
            data:
              oneOf:
                - $ref: "#/components/schemas/DnsRecords"
                - type: "null"
    RedirectChainStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: RedirectChain
            data:
              oneOf:
                - $ref: "#/components/schemas/RedirectChain"
                - type: "null"
    MxCheckStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: MxCheck
            data:
              oneOf:
                - $ref: "#/components/schemas/SmtpMetadata"
                - type: "null"
    NxdomainStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: Nxdomain
            data:
              oneOf:
                - $ref: "#/components/schemas/NxdomainMetadata"
                - type: "null"
    OriginX509StreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: OriginX509
            data:
              oneOf:
                - $ref: "#/components/schemas/ParsedX509Certificate"
                - type: "null"
    PassiveDnsStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: PassiveDns
            data:
              oneOf:
                - type: array
                  items:
                    $ref: "#/components/schemas/PassiveDNSRecord"
                - type: "null"
    PassiveTlsStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: PassiveTls
            data:
              oneOf:
                - $ref: "#/components/schemas/PassiveTLSMap"
                - type: "null"
    CertificateTransparencyStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              const: CertificateTransparency
            data:
              oneOf:
                - $ref: "#/components/schemas/CTSearchResult"
                - type: "null"
    GenericStreamMessage:
      allOf:
        - $ref: "#/components/schemas/StreamMessageBase"
        - type: object
          properties:
            op:
              enum:
                - Levenshtein
                - IpEnumeration
                - HttpBanner
                - Rdap
                - WhoIs
                - Screenshot
                - Technologies
                - RegistrationMetadata
            data: {}
    StreamMessage:
      description: >
        One line from a streaming lookup response. The exact shape of `data`
        depends on `op`.
      oneOf:
        - $ref: "#/components/schemas/MetaStreamMessage"
        - $ref: "#/components/schemas/GeoIpStreamMessage"
        - $ref: "#/components/schemas/ClassificationStreamMessage"
        - $ref: "#/components/schemas/DnsStreamMessage"
        - $ref: "#/components/schemas/RedirectChainStreamMessage"
        - $ref: "#/components/schemas/MxCheckStreamMessage"
        - $ref: "#/components/schemas/NxdomainStreamMessage"
        - $ref: "#/components/schemas/OriginX509StreamMessage"
        - $ref: "#/components/schemas/PassiveDnsStreamMessage"
        - $ref: "#/components/schemas/PassiveTlsStreamMessage"
        - $ref: "#/components/schemas/CertificateTransparencyStreamMessage"
        - $ref: "#/components/schemas/GenericStreamMessage"
      discriminator:
        propertyName: op
        mapping:
          Meta: "#/components/schemas/MetaStreamMessage"
          GeoIp: "#/components/schemas/GeoIpStreamMessage"
          Classification: "#/components/schemas/ClassificationStreamMessage"
          Dns: "#/components/schemas/DnsStreamMessage"
          RedirectChain: "#/components/schemas/RedirectChainStreamMessage"
          MxCheck: "#/components/schemas/MxCheckStreamMessage"
          Nxdomain: "#/components/schemas/NxdomainStreamMessage"
          OriginX509: "#/components/schemas/OriginX509StreamMessage"
          PassiveDns: "#/components/schemas/PassiveDnsStreamMessage"
          PassiveTls: "#/components/schemas/PassiveTlsStreamMessage"
          CertificateTransparency: "#/components/schemas/CertificateTransparencyStreamMessage"
          Levenshtein: "#/components/schemas/GenericStreamMessage"
          IpEnumeration: "#/components/schemas/GenericStreamMessage"
          HttpBanner: "#/components/schemas/GenericStreamMessage"
          Rdap: "#/components/schemas/GenericStreamMessage"
          WhoIs: "#/components/schemas/GenericStreamMessage"
          Screenshot: "#/components/schemas/GenericStreamMessage"
          Technologies: "#/components/schemas/GenericStreamMessage"
          RegistrationMetadata: "#/components/schemas/GenericStreamMessage"
