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:
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'
}
Updated 6 days ago