Using the GreyNoise Enterprise API

API Information

  • API Address: api.greynoise.io
  • Requires an active Subscription or Enterprise Trial to Access
  • Not available to Community Users (Community Users should see the Using the GreyNoise Community API

GreyNoise API Fundamentals

While typical to use, usage of GreyNoise REST API should follow these fundamental rules, based of the use case or intended usage:

  • Use the GreyNoise SDK when possible
  • For High-Volume usage, use the multi-quick API endpoint primarily to tag IPs in bulk as noise or not, then use the Context API endpoint for full IP details downstream
  • Use the METADATA TAGS endpoint for additional information on TAGS returned from the context API. This endpoint returns all known tags with metadata, so it is recommended to cache this data locally, if possible, daily and add the tag metadata to any context lookups performed.

PostMan Collection

The Full Set of API endpoints and parameters can be referenced here:

View in Postman

Basic IP Lookup Flow

  • Query the Quick IP API Endpoint. If the IP is marked as noise, continue, otherwise stop, and return code information
  • Query the Context IP API Endpoint. This will return all the details collected for the given IP. If you desire additional metadata on any TAGS returned on the IP, continue; otherwise, present the data.
from greynoise import GreyNoise

session = GreyNoise(api_key='<api_key>', integration_name="sdk-sample")
ip_address = '195.72.230.190'
output = []

quick_response = session.quick(ip_address)

for result in quick_response:
    if result['noise']:
        context_response = session.ip(ip_address)
        context_response['noise'] = result['noise']
        context_response['code'] = result['code']
        context_response['code_message'] = result['code_message']
        context_response['visualizer_url'] = 'https://viz.greynoise.io/ip/' + str(ip_address)
        output.append(context_response)
    else:
        output.append(result)

print(output)
import requests

context_url = "https://api.greynoise.io/v2/noise/context/"
quick_url = "https://api.greynoise.io/v2/noise/quick/"

headers = {"key": "<api_key>", "Accept": "application/json",
           "User-Agent": "sample-python-script"}

code_messages = {
    "0x00": "IP has never been observed scanning the Internet",
    "0x01": "IP has been observed by the GreyNoise sensor network",
    "0x02": (
        "IP has been observed scanning the GreyNoise sensor network, "
        "but has not completed a full connection, meaning this can be spoofed"
    ),
    "0x03": (
        "IP is adjacent to another host that has been directly observed "
        "by the GreyNoise sensor network"
    ),
    "0x04": "RESERVED",
    "0x05": "IP is commonly spoofed in Internet-scan activity",
    "0x06": (
        "IP has been observed as noise, but this host belongs to a cloud provider "
        "where IPs can be cycled frequently"
    ),
    "0x07": "IP is invalid",
    "0x08": (
        "IP was classified as noise, but has not been observed "
        "engaging in Internet-wide scans or attacks in over 60 days"
    ),
    "0x09": "IP was found in RIOT",
    "0x10": "IP has been observed by the GreyNoise sensor network and is in RIOT",
    "404": "IP is Invalid",
}

ip_address = '186.33.111.236'
output = {}

quick_response = requests.get(quick_url + ip_address, headers=headers)
quick_json = quick_response.json()
quick_json["code_message"] = code_messages[quick_json["code"]]

if quick_json['noise']:
    context_response = requests.get(context_url + ip_address, headers=headers)
    context_json = context_response.json()
    context_json['noise'] = quick_json['noise']
    context_json['code'] = quick_json['code']
    context_json['code_message'] = quick_json['code_message']
    context_json['visualizer_url'] = 'https://www.greynoise.io/viz/ip/' + str(ip_address)
    output = context_json
else:
    output = quick_json

print(output)

Advanced IP Lookup Flow

When creating an advanced lookup for a single IP, the following flow and logic are recommended:

  • Query the Quick IP API Endpoint.
  • If the Quick endpoint includes "riot: true," query the RIOT API endpoint and present the data
  • if the Quick endpoint includes "noise: true," query the Context API endpoint and present the data
  • If additional details on tags associated with an IP found in the Context endpoint are desired, query the Metadata TAGS API Endpoint and return the matching TAG metadata for the TAGS found on the IP Context lookup.
from greynoise import GreyNoise

session = GreyNoise(api_key='<api_key>', integration_name="sdk-sample")
ip_address = '195.72.230.190'
output = []


def build_tag_details(metadata, tags):
    detailed_tags = []
    for tag in tags:
        for detailed_tag in metadata["metadata"]:
            if tag == detailed_tag["name"]:
                detailed_tags.append(detailed_tag)
    return detailed_tags


quick_response = session.quick(ip_address)

for result in quick_response:
    context_response = {}
    riot_response = {}
    if result['noise']:
        context_response = session.ip(ip_address)
        tags_response = session.metadata()
        updated_tags = build_tag_details(tags_response, context_response["tags"])
        context_response.pop("tags")
        context_response["tags"] = updated_tags
    if result['riot']:
        riot_response = session.riot(ip_address)

    if context_response and riot_response:
        response = context_response.copy()
        response.update(riot_response)
        output.append(response)
    elif context_response:
        output.append(context_response)
    elif riot_response:
        output.append(riot_response)
    else:
        output.append(result)

print(output)
import requests

context_url = "https://api.greynoise.io/v2/noise/context/"
quick_url = "https://api.greynoise.io/v2/noise/quick/"
riot_url = "https://api.greynoise.io/v2/riot/"
metadata_url = "https://api.greynoise.io/v2/meta/metadata"

headers = {"key": "<api_key>", "Accept": "application/json",
           "User-Agent": "sample-python-script"}

ip_address = '186.33.111.236'
output = []


def build_tag_details(metadata, tags):
    detailed_tags = []
    for tag in tags:
        for detailed_tag in metadata["metadata"]:
            if tag == detailed_tag["name"]:
                detailed_tags.append(detailed_tag)
    return detailed_tags


quick_response = requests.get(quick_url + ip_address, headers=headers)

context_json = {}
riot_json = {}
if quick_response.json()['noise']:
    context_response = requests.get(context_url + ip_address, headers=headers)
    context_json = context_response.json()
    if len(context_json["tags"]) >= 1:
        tags_response = requests.get(metadata_url, headers=headers)
        tags_json = tags_response.json()
        updated_tags = build_tag_details(tags_json, context_json["tags"])
        context_json.pop("tags")
        context_json["tags"] = updated_tags
if quick_response.json()['riot']:
    riot_response = requests.get(riot_url + ip_address, headers=headers)
    riot_json = riot_response.json()

if context_json and riot_json:
    response = context_json.copy()
    response.update(riot_json)
    output.append(response)
elif context_json:
    output = context_json
elif riot_json:
    output = riot_json
else:
    output = quick_response.json()

print(output)

High Volume IP Lookups

When integrating with the GreyNoise REST API to perform a high volume of IP lookups, the Multi-Quick API Endpoint is strongly recommended to provide quick lookup data on IPs in bulk. The Multi-Quick endpoint supports either a GET (limited to 500 IPs per request) or a POST (limited to 1000 IPs per request).

The Quick Lookup will allow each requested IP to be tagged as existing in one of the GreyNoise datasets. For those tagged at "NOISE," which means GreyNoise has observed the IP scanning the internet, a secondary Context API Endpoint lookup can be done for each IP as a downstream task. For those tagged as "RIOT", which means that the IP is part of a common business service, a secondary RIOT API Endpoint lookup can be done for each IP as a downstream task.

import requests

bulk_quick_url = "https://api.greynoise.io/v2/noise/multi/quick"

headers = {"key": "<api-key>", "Accept": "application/json",
           "User-Agent": "sample-python-script"}

ip_addresses = ["1.2.3.4", "5.6.7.8", "8.8.8.8", "123.123.123.123"]
output = {}

payload = {"ips": list(ip_addresses)}
quick_response = requests.post(bulk_quick_url, headers=headers, json=payload)

print(quick_response.json())
[
    {
        "ip": "69.112.115.157",
        "noise": false,
        "riot" : false,
        "code": "0x00"
    },
    {
        "ip": "123.179.144.49",
        "noise": false,
        "riot" : false,
        "code": "0x00"
    },
    {
        "ip": "74.126.110.231",
        "noise": false,
        "riot" : false,
        "code": "0x00"
    }
]

Query (GNQL) API Sample

The GreyNoise GNQL API endpoint allows search through the GreyNoise NOISE dataset. The endpoint will take in any query in the GNQL format and provide an output of all the NOISE dataset IPs that match the query.

By default, the endpoint will return 1,000 results per page. The size parameter can be used to up the page limit to 10,000 results per page. When the total number of results exceeds the page size, a scroll token is provided in response to fetch the next set of results.

Here is a sample script for using the GreyNoise SDK to cycle through the GNQL response:

from greynoise import GreyNoise

session = GreyNoise(api_key="<api-key>", integration_name="gnql-sample")

response = session.query("last_seen:1d tags:Mirai")
data = response["data"]

scroll = response['scroll']
while scroll:
    response = session.query("last_seen:1d", scroll=scroll)
    data.extend(response["data"])
    scroll = (response['scroll'] if 'scroll' in response else False)

API Responses

IP Context Lookup Responses

{
  "actor": "Alpha Strike Labs",
  "bot": false,
  "classification": "benign",
  "cve": [
    "CVE-2021-38645",
    "CVE-2021-38649"
  ],
  "first_seen": "2019-07-29",
  "ip": "45.83.66.207",
  "last_seen": "2025-02-14",
  "metadata": {
    "asn": "AS208843",
    "category": "business",
    "city": "Berlin",
    "country": "Germany",
    "country_code": "DE",
    "destination_countries": [
      "Saudi Arabia",
      "Switzerland"
    ],
    "destination_country_codes": [
      "NG",
      "SA"
    ],
    "organization": "Alpha Strike Labs GmbH",
    "os": "unknown",
    "rdns": "",
    "region": "Berlin",
    "sensor_count": 48,
    "sensor_hits": 1527,
    "source_country": "Germany",
    "source_country_code": "DE",
    "tor": false
  },
  "raw_data": {
    "hassh": [
      {
        "fingerprint": "084386fa7ae5039bcf6f07298a05a227",
        "port": 22
      }
    ],
    "ja3": [
      {
        "fingerprint": "04b3f524166caafd433b6864250945be",
        "port": 465
      }
    ],
    "scan": [
      {
        "port": 21,
        "protocol": "tcp"
      }
    ],
    "web": {
      "paths": [
        "/rest/applinks/1.0/manifest",
        "/wsman"
      ],
      "useragents": [
        "Microsoft WinRM Client",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
      ]
    }
  },
  "seen": true,
  "spoofable": false,
  "tags": [
    "Alpha Strike Labs",
    "Web Crawler",
    "TLS/SSL Crawler",
    "Favicon Scanner",
    "SSH Connection Attempt",
    "RDP Alternative Port Crawler",
    "RDP Crawler",
    "EtherNet/IP Scanner",
    "Azure OMI RCE Attempt",
    "SSH Alternative Port Crawler",
    "ZMap Client",
    "Tridium Niagara AX Fox ICS Scanner",
    "Internet Printing Protocol Scanner",
    "Carries HTTP Referer",
    "SMBv2 Crawler"
  ],
  "vpn": false,
  "vpn_service": ""
}
{
	'error': 'Invalid IP submitted'
}
{
	'message': 'Forbidden'
}

IP Quick Lookup Responses

{
  'ip': '45.83.66.207', 
  'noise': True, 
  "riot" : false,
  'code': '0x01'
}
{
  'code': '0x07', 
  'error': 'invalid ip address submitted'
}
{
  'message': 'Forbidden'
}

IP RIOT Lookup Responses

{
  "category": "public_dns",
  "description": "Cloudflare, Inc. is an American web infrastructure and website security company, providing content delivery network (CDN) services, distributed denial of service (DDoS) mitigation, Internet security, and distributed domain name system (DNS) services. This is their public DNS offering.",
  "explanation": "Public DNS services are used as alternatives to ISP's name servers. You may see devices on your network communicating with Cloudflare Public DNS over port 53/TCP or 53/UDP to resolve DNS lookups.",
  "ip": "1.1.1.1",
  "last_updated": "2025-04-10T17:11:04Z",
  "name": "Cloudflare Public DNS",
  "reference": "https://one.one.one.one",
  "riot": true,
  "trust_level": "1"
}
{
  'message': 'IP provided is not a routable IPv4 address'
}
{
  'message': 'Forbidden'
}
{
  'ip': '45.83.66.207', 
  'riot': False
}

GNQL Query

{
  'complete': False, 
  'count': 371885, 
  'data': [
    {
  "actor": "Alpha Strike Labs",
  "bot": false,
  "classification": "benign",
  "cve": [
    "CVE-2021-38645",
    "CVE-2021-38649"
  ],
  "first_seen": "2019-07-29",
  "ip": "45.83.66.207",
  "last_seen": "2025-02-14",
  "metadata": {
    "asn": "AS208843",
    "category": "business",
    "city": "Berlin",
    "country": "Germany",
    "country_code": "DE",
    "destination_countries": [
      "Saudi Arabia",
      "Switzerland"
    ],
    "destination_country_codes": [
      "NG",
      "SA"
    ],
    "organization": "Alpha Strike Labs GmbH",
    "os": "unknown",
    "rdns": "",
    "region": "Berlin",
    "sensor_count": 48,
    "sensor_hits": 1527,
    "source_country": "Germany",
    "source_country_code": "DE",
    "tor": false
  },
  "raw_data": {
    "hassh": [
      {
        "fingerprint": "084386fa7ae5039bcf6f07298a05a227",
        "port": 22
      }
    ],
    "ja3": [
      {
        "fingerprint": "04b3f524166caafd433b6864250945be",
        "port": 465
      }
    ],
    "scan": [
      {
        "port": 21,
        "protocol": "tcp"
      }
    ],
    "web": {
      "paths": [
        "/rest/applinks/1.0/manifest",
        "/wsman"
      ],
      "useragents": [
        "Microsoft WinRM Client",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
      ]
    }
  },
  "seen": true,
  "spoofable": false,
  "tags": [
    "Alpha Strike Labs",
    "Web Crawler",
    "TLS/SSL Crawler",
    "Favicon Scanner",
    "SSH Connection Attempt",
    "RDP Alternative Port Crawler",
    "RDP Crawler",
    "EtherNet/IP Scanner",
    "Azure OMI RCE Attempt",
    "SSH Alternative Port Crawler",
    "ZMap Client",
    "Tridium Niagara AX Fox ICS Scanner",
    "Internet Printing Protocol Scanner",
    "Carries HTTP Referer",
    "SMBv2 Crawler"
  ],
  "vpn": false,
  "vpn_service": ""
}], 
	'message': 'ok', 
  'query': 'last_seen:1d', 
  'scroll': 'DnF1ZXJ5VGhlbkZldGNoBQAAAAAFvC7hFkFKSExEdUc4VEtta2syaGg2R3kzNGcAAAAABbwu4hZBSkhMRHVHOFRLbWtrMmhoNkd5MzRnAAAAAAW8LuMWQUpITER1RzhUS21razJoaDZHeTM0ZwAAAAAFvC7kFkFKSExEdUc4VEtta2syaGg2R3kzNGcAAAAABbwu5RZBSkhMRHVHOFRLbWtrMmhoNkd5MzRn'
}
{
  'message': 'Forbidden'
}