Shodan · Arazzo Workflow

Shodan Search to Host Detail

Version 1.0.0

Estimate a search, run it, then drill into the first matching host.

1 workflow 1 source API 1 provider
View Spec View on GitHub SecuritySearchInternetDevicesIoTVulnerabilitiesCVEAttack SurfaceThreat IntelligenceReconnaissanceNetworkDNSScanningPublic APIsArazzoWorkflows

Provider

shodan

Workflows

search-to-host-detail
Count, search, and inspect the top matching host for a Shodan query.
Runs a credit-free count for the query, executes the search to retrieve matches and facets, then retrieves the full host record for the first matched IP.
3 steps inputs: apiKey, facets, page, query outputs: facets, firstMatchIp, ports, total
1
countResults
getHostCount
Determine how many results the query would return, along with a facet summary, without consuming query credits.
2
runSearch
searchHosts
Execute the search to retrieve the matching banners and any requested facet breakdowns.
3
hostDetail
getHost
Retrieve the full host record for the first matching IP, returning every indexed service found on the host.

Source API Descriptions

Arazzo Workflow Specification

shodan-search-to-host-detail-workflow.yml Raw ↑
arazzo: 1.0.1
info:
  title: Shodan Search to Host Detail
  summary: Estimate a search, run it, then drill into the first matching host.
  description: >-
    A complete search-and-pivot pattern. The workflow first checks how many
    results a query would return without spending query credits, runs the
    search to retrieve the matching banners, and then pivots into a full host
    lookup for the first matching IP. Every step spells out its request inline
    so the flow can be read and executed without opening the underlying OpenAPI
    description.
  version: 1.0.0
sourceDescriptions:
- name: shodanRest
  url: ../openapi/shodan-rest-openapi.yml
  type: openapi
workflows:
- workflowId: search-to-host-detail
  summary: Count, search, and inspect the top matching host for a Shodan query.
  description: >-
    Runs a credit-free count for the query, executes the search to retrieve
    matches and facets, then retrieves the full host record for the first
    matched IP.
  inputs:
    type: object
    required:
    - apiKey
    - query
    properties:
      apiKey:
        type: string
        description: Shodan API key passed as the `key` query parameter.
      query:
        type: string
        description: Shodan search query (e.g. "product:nginx country:US").
      facets:
        type: string
        description: Comma-separated facet definitions (e.g. "country:5,port:10").
      page:
        type: integer
        description: The page of search results to retrieve.
        default: 1
  steps:
  - stepId: countResults
    description: >-
      Determine how many results the query would return, along with a facet
      summary, without consuming query credits.
    operationId: getHostCount
    parameters:
    - name: key
      in: query
      value: $inputs.apiKey
    - name: query
      in: query
      value: $inputs.query
    - name: facets
      in: query
      value: $inputs.facets
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      total: $response.body#/total
      facets: $response.body#/facets
  - stepId: runSearch
    description: >-
      Execute the search to retrieve the matching banners and any requested
      facet breakdowns.
    operationId: searchHosts
    parameters:
    - name: key
      in: query
      value: $inputs.apiKey
    - name: query
      in: query
      value: $inputs.query
    - name: facets
      in: query
      value: $inputs.facets
    - name: page
      in: query
      value: $inputs.page
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      total: $response.body#/total
      matches: $response.body#/matches
      firstMatchIp: $response.body#/matches/0/ip_str
  - stepId: hostDetail
    description: >-
      Retrieve the full host record for the first matching IP, returning every
      indexed service found on the host.
    operationId: getHost
    parameters:
    - name: key
      in: query
      value: $inputs.apiKey
    - name: ip
      in: path
      value: $steps.runSearch.outputs.firstMatchIp
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      ip: $response.body#/ip_str
      ports: $response.body#/ports
      vulns: $response.body#/vulns
  outputs:
    total: $steps.countResults.outputs.total
    facets: $steps.countResults.outputs.facets
    firstMatchIp: $steps.runSearch.outputs.firstMatchIp
    ports: $steps.hostDetail.outputs.ports