GreyNoise Integration Guide
Overview
The GreyNoise integration lets your NINA workflows query GreyNoise's v3 API — an internet scan-and-attack-traffic intelligence platform built from a global network of sensors. Use it to classify scanning/attack traffic by IP, hunt with GNQL (GreyNoise's own Lucene-based query language), track CVE exploitation activity, pull Threat Brief articles, inspect sensor session data (packet captures, Tactics detections), manage query-based blocklists, compare workspaces, and download Psychic model/snapshot files.
The API is organized into 16 resources: ip-lookup, gnql, recall, ip-timeline, cve, tags, community, threat-briefs, business-service-intelligence, sessions, tactics, blocklists, compare, psychic, callback, utility — 58 operations in total.
Status
The integration is spec-driven: every operation is generated directly from GreyNoise's own published per-operation API reference (one OpenAPI fragment per operation, merged into a single spec). An operation appears only if GreyNoise's docs define it — nothing is synthesized. The retired v2 surface (quick, context, riot, similarity, daily/hourly summary) is deliberately excluded; see Migrating from v2 below.
Supported resources: ip-lookup, gnql, recall, ip-timeline, cve, tags, community, threat-briefs, business-service-intelligence, sessions, tactics, blocklists, compare, psychic, callback, utility.
Out of scope (for now):
- OAuth flows — authentication is by API key only.
- Workspace listing — GreyNoise publishes no endpoint that enumerates workspaces, so there is no dropdown for
workspace_idorsource_workspace/target_workspace. Find your workspace ID as described below and enter it manually.
Credential Configuration
Before using the integration you must configure a credential.
Authentication Method
The GreyNoise integration uses API Key authentication. The key is sent on every request as the key header.
| Field | Description | Example |
|---|---|---|
| API Key | Your GreyNoise API key (required) | AbCdEf12… |
| Base URL | Optional override of the API host. Defaults to https://api.greynoise.io when left empty. | https://api.greynoise.io |
| Workspace ID | Optional default workspace UUID. Used as the fallback for the workspace_id parameter on the 11 workspace-scoped operations in blocklists (6 ops) and tactics (5 ops) whenever that parameter is left empty on the operation itself. An explicit workspace_id on the operation always wins over this default. | (a workspace UUID) |
How to get your API Key and Workspace ID:
- Sign in to the GreyNoise Visualizer with your GreyNoise account.
- Click the user menu in the top right and select Plan details. Your API key and workspace ID (shown under the workspace name) are both listed there.
- Paste the API key into the credential's API Key field. Only set Workspace ID on the credential if you plan to call
blocklists/tacticsoperations without passingworkspace_idexplicitly every time.
A free Community API key works for the community resource (getCommunityIP) and a reduced set of other endpoints; most of the resources below require a paid GreyNoise plan with the relevant entitlement — see Plan gating.
Creating a GreyNoise Credential
- Navigate to the Credentials section in NINA.
- Click Add New Credential.
- Fill in the credential details:
- Name: A descriptive name (e.g., "GreyNoise Production").
- Integration Service: Select "GreyNoise".
- Auth Type: "API Key" (selected automatically).
- API Key: Your GreyNoise API key.
- Base URL / Workspace ID: Leave blank unless you need a non-default API host or a default workspace.
- Click Test Connection to verify the credential (this calls
GET /ping). - Click Save.
Supported Resources and Operations
This is a representative summary; the full operation list is always available in the node's Operation dropdown.
IP Lookup (ip-lookup)
Scan and attack context for one or many IP addresses.
| Operation | Purpose |
|---|---|
v3IP | Context for a single IP: time ranges, metadata (network owner, ASN, reverse DNS, country), associated actors, activity tags, raw scan/web data. quick=true returns a reduced payload faster. workspace_labels adds community/personal dataset overlays alongside the default greynoise dataset. |
v3MultiIP | The same context for up to 10,000 IPs in one call (ips in the body). quick and workspace_labels are query parameters even though this is a POST. |
GNQL (gnql)
GreyNoise Query Language search over the observed-traffic dataset.
| Operation | Purpose |
|---|---|
gnqlV3Query | Full GNQL search. format=csv|json; scroll pages through results (incompatible with format=csv); quick returns a reduced payload; exclude drops named fields from the response. |
gnqlV3MetadataQuery | Same search, but always excludes raw_data and lets you exclude further fields — cheaper when you only need metadata. |
gnqlV3Stats | Aggregate stats (top organizations, actors, tags, ASNs, countries, classifications, operating systems) for a query; count caps how many top items per category. |
Recall (recall)
GNQL over time.
| Operation | Purpose |
|---|---|
gnqlTimeSeries | Hourly GNQL records for a time range (start/end); format=csv|json; limit/offset paginate. |
gnqlTimeSeriesStats | Unique-IP counts per query, bucketed by interval. interval is required and accepts only hour or day — any other value is rejected. |
IP Timeline (ip-timeline)
Daily and hourly activity breakdown for a single IP.
| Operation | Purpose |
|---|---|
getIPTimelineFieldSummary | Activity breakdown for one field (e.g. classification) over days of lookback, with granularity (Xh/Xd) and cursor/limit pagination. Requires an additional subscription license. |
CVE (cve)
Exploitation activity and vulnerability intelligence.
| Operation | Purpose |
|---|---|
getCVE | Details for a single CVE by ID (e.g. CVE-2021-44228). |
listCVEs | Browse CVEs GreyNoise tracks, sorted by published, updated, or cvss; exploitable_only restricts to network-attack-vector CVEs. Requires the feature-search-cves-bulk entitlement. |
bulkCVELookup | Up to 10,000 CVE IDs in a single call. Requires a business email address and appropriate entitlements. |
Tags (tags)
Activity tag metadata.
| Operation | Purpose |
|---|---|
listTags | List tags (id, name, slug, category, intention, description, related CVEs and tags), filterable by name (partial), slug (exact), or cve. |
Community (community)
Free, reduced-scope IP lookup.
| Operation | Purpose |
|---|---|
getCommunityIP | Community-tier subset of IP context — works with a free Community API key. |
Threat Briefs (threat-briefs)
Threat brief articles, categories, and RSS feeds.
| Operation | Purpose |
|---|---|
listArticles | Paginated Threat Brief articles; filter by category/search, sort with sort_by/sort_desc. |
getArticle | A single article by ID. |
listArticleCategories | Available article categories. |
getPublicRSSFeed | Public, unauthenticated RSS 2.0 feed — community category only. |
getRSSFeedToken | Returns the workspace's private RSS feed URL, issuing one on first access. Requires an entitlement beyond the public community category. |
getPrivateRSSFeed | Fetches the entitlement-filtered feed content for a given token. |
generateRSSFeedToken | Rotates the private feed URL, invalidating the previous one (documented but not exercised — see note below). |
Business Service Intelligence (business-service-intelligence)
Business service (formerly RIOT) lookups, trust levels, and dataset statistics — commonly plan-gated (see Plan gating).
| Operation | Purpose |
|---|---|
getBSILookup | Single-IPv4 BSI provider match; IPv6 → 400. Requires an additional subscription license. |
getBSIBulkLookup | Up to 1,000 IPv4 addresses in one call, order preserved. Same license requirement. |
getBSICategory / getBSICompany / getBSITrust | Aggregate BSI counts by category / company / trust level; date=now or date=YYYY-MM-DD. |
getBSIDownload | Full gzipped NDJSON bulk-data file for a date. Same license requirement. |
Sessions (sessions)
Sensor session data: search, statistics, connections, and packet captures.
| Operation | Purpose |
|---|---|
getSessions | Paginated session list; filter by query (Lucene) and time range; scope=workspace|demo. |
getSessionById | A single session by ID. |
getSessionConnections | Graph of connections between source/destination fields. |
getSessionCounts | Aggregated counts grouped by one or more fields. |
getSessionFields | Discover which fields are available for querying/sorting/aggregation. |
getSessionTimeseries | Session volume over time, optionally grouped by field. |
getSessionUniqueValues | Unique values for one field, returned as CSV, with optional counts. |
getSessionPcap | Raw PCAP bytes for one session (binary → base64 in this node's output). |
exportSessionData | PCAP or raw-payload export for one session (type=pcap|rawSource|rawDestination). Not available with scope=demo — returns 403. |
exportSessionsPcap | PCAP export for many sessions matching a query. Not available with scope=demo — returns 403. |
scope controls the dataset: workspace (your own sensors — requires the Sensors entitlement) or demo (GreyNoise's sample dataset — requires the Swarm entitlement). A workspace with no deployed sensors returns zero sessions under scope=workspace; use scope=demo to explore the shape of the data.
Tactics (tactics)
Tactic detections for a workspace, their destination IPs and artifacts.
| Operation | Purpose |
|---|---|
searchTacticsDetections | Search detections (sessions matched to MITRE ATT&CK techniques/tactics) for a workspace. Cursor-paginated; a body is required (send {} for no filters). techniques/tactics combine with OR; all other filters combine with AND. |
getTacticsDetection | A single detection: full ordered command timeline and full touched-file set, each independently paginated (commands_page, artifacts_page), plus per-protocol destination-IP counts. |
listTacticsDetectionDestinationIPs | Paginated unique destination IPs for a detection. include_lateral=true also returns RFC 1918/loopback addresses. |
listTacticsDetectionFiles | File metadata (path, size, type, hashes) touched by a detection's session; mutations_only=true restricts to created/modified files. |
getTacticsHostArtifactContent | Contents of one file by path (requires session_id too). Small files come back inline as base64; larger ones as a short-lived presigned link. Gated by a separate Tactics file-content entitlement. |
Blocklists (blocklists)
Query-based blocklists for a workspace and their resolved IPs.
| Operation | Purpose |
|---|---|
listBlocklists | List a workspace's blocklists; limit/offset paginate. |
getBlocklist | A single blocklist by ID. |
getBlocklistIPs | The IPs currently matching a blocklist's GNQL query; size caps the count (defaults to the blocklist's own ip_limit). |
createBlocklist | Create a blocklist from a GNQL query. Write operation — documented for completeness, not exercised during development. |
updateBlocklist | Update an existing blocklist's query/name/limit/enabled state. Write operation — not exercised. |
deleteBlocklist | Delete a blocklist. Write operation — not exercised. |
Compare (compare)
Compare workspaces: IP differences, statistics differences, and unique-IP jobs.
| Operation | Purpose |
|---|---|
workspaceDiff | Per-IP diff of a GNQL query's results between a source and target workspace (UUID or the aliases greynoise, community, personal). |
workspaceStatsDiff | Aggregate stats diff between two workspaces for a query. |
startUniqueIPsJob | Start an async job to find IPs unique to a source workspace vs. a target one. Returns a job ID. |
getUniqueIPsJobStatus | Poll a job by ID; the response includes the unique IPs once the job completes. |
Psychic (psychic)
Model and snapshot dataset downloads.
| Operation | Purpose |
|---|---|
postPsychicModelDownload | Download a Psychic model file (models 1–4), latest or a specific date/date range; format=bin|mmdb (MaxMind DB). Gated by a per-model entitlement, plus a lookback-days entitlement for historical dates. |
postPsychicSnapshotDownload | Download a precomputed snapshot (7 or 30 days for models 1–3, or the latest for model 4). Same entitlement requirements. |
Callback (callback)
Callback (C2 detection) IP lookups, listings, exports, and overview statistics — commonly plan-gated.
| Operation | Purpose |
|---|---|
callbackGetIP | Detail for a single callback IP: attack stage, scanner associations, downloaded malware files. |
callbackListIPs | Paginated, filterable list of callback IPs (stage, dates, file attributes, scanner IPs). |
callbackOverview | Aggregate statistics over the same filters. |
callbackExportIPs | Newline-delimited plain-text export of matching callback IPs. |
Utility (utility)
Service utilities.
| Operation | Purpose |
|---|---|
ping | Connectivity and key check — this is what Test Connection calls. |
Key Concepts
- Output envelope — the single most common mapping mistake. Every operation returns
{"success": true, "data": …}. A downstream node must readdata.<field>(e.g.data.classification,data.metadata.organization) — the fields GreyNoise returns are never at the top level of the node's output. - Text and binary responses. Text bodies (CSV, RSS XML, plain text) come back as
{"success":true,"content_type":"text/csv","data":"<the text>"}. Binary bodies (PCAP, gzip, MaxMind DB) come back as{"success":true,"content_type":"…","encoding":"base64","data":"<base64>"}— a workflow must base64-decodedatato recover the file. There is no response size limit on this node: results stream through, so large exports and packet captures are handled the same way as a small JSON response. - HTTP 206 partial results. A number of operations can return partial data when your plan restricts what GreyNoise is allowed to send back. When that happens the envelope also carries
"partial_content": trueand a"partial_content_message"explaining it. Branch onpartial_contentrather than trusting the result as complete. - Plan gating. A
403with a message likefeature not allowedmeans your account's plan lacks that module — it is not a credential error. Business Service Intelligence lookups and the Callback (C2 detection) family are commonly gated this way; Psychic downloads, the private Threat Briefs RSS feed, and Tactics file content each have their own separate entitlement too. A different 403 flavour,export is not available for demo data, means you calledexportSessionData/exportSessionsPcapwithscope=demo. - Sessions scope. Sessions and Tactics-style operations take
scope:workspace(your own sensors, requires the Sensors entitlement) ordemo(GreyNoise's sample dataset, requires the Swarm entitlement). A workspace with no deployed sensors returns zero sessions underscope=workspace— that's expected, not a broken query; switch toscope=demoto see sample data.exportSessionDataandexportSessionsPcaprefusescope=demowith a 403. - Pagination is passed through, not automated.
scroll(GNQL),cursor,page/page_size,size,limit,offsetare all forwarded to GreyNoise as-is — nothing in this node auto-paginates. A workflow loops explicitly, feeding each response's continuation token/offset back in as the next call's parameter. gnqlTimeSeriesStatsrequiresinterval, and only acceptshourorday— any other value is rejected.- An IP GreyNoise has never observed returns HTTP 404, not an empty result.
8.8.8.8is a real-world example of this: GreyNoise has no scanning/attack data for it, sov3IP/getCommunityIPon that address return a 404 ("ip not found") rather than a 200 with empty fields. Don't read a 404 here as a broken credential. - Migrating from v2. This node exposes only GreyNoise's current v3 (and stable v1) surface. The old v2 endpoints —
quick,context,riot,similarity, and the daily/hourly summary endpoints — are retired and are not exposed here;/v3/gnql/statsis the current replacement for the old/v2/experimental/gnql/stats. If you're porting a workflow built against those v2 endpoints, consult GreyNoise's own v2→v3 migration guide at docs.greynoise.io for the full endpoint-by-endpoint mapping.
Parameter Merging
The GreyNoise integration uses NINA's standard parameter merging.
Parameter Sources (in order of precedence)
- Node Parameters — values set directly on the integration node.
- Extracted Parameters — the merged input data, passed through unchanged (GreyNoise has no operation-specific extraction logic).
- Input Data — the merged output of upstream nodes.
Path vs. body vs. query
Each operation routes its parameters from a fixed, generated table — not a heuristic based on HTTP method. This matters because three POST operations mix body and query parameters: v3MultiIP (quick, workspace_labels are query params on a POST), searchTacticsDetections (page_size, cursor, exclude_non_interactive are query params), and listTacticsDetectionFiles (mutations_only is a query param). No GET or DELETE operation takes a body. A parameter not declared for the operation you're calling is dropped rather than guessed at, so double-check the operation's parameter list in the node before assuming a field will be sent.
workspace_id path parameters fall back to the credential's Workspace ID when left empty on the operation (see Credential Configuration); every other parameter must be supplied explicitly.
Examples
Enrich a single IP
{
"resource": "ip-lookup",
"operation": "v3IP",
"parameters": { "ip": "1.2.3.4" }
}
(1.2.3.4 is a placeholder — substitute the IP you're investigating. Remember that an IP GreyNoise has never observed, such as 8.8.8.8, returns 404 rather than an empty result.)
A downstream node reads the result from data, e.g. data.classification, data.actor, data.metadata.organization, data.metadata.country, data.tags — never the bare field name, since everything GreyNoise returns is nested one level under this node's data envelope.
Hunt with GNQL
{
"resource": "gnql",
"operation": "gnqlV3Query",
"parameters": { "query": "cve:CVE-2021-44228", "size": 50 }
}
(cve:CVE-2021-44228 — Log4Shell — is one of GNQL's own documented example queries; any GNQL-valid query string works the same way. Add "scroll": "<token>" from a previous response to page through more results.)
GreyNoise's own GNQL response nests the matched IP records under its own data field alongside a count and a scroll continuation token — so once wrapped in this node's envelope, a downstream node reads data.data for the array of matched records and data.count for the total match count. Watch for that double data: the outer one is this node's envelope, the inner one is GreyNoise's own response shape.
Integration in Workflow Context
Common Workflow Patterns
- IP enrichment on an alert — SIEM/EASM alert → extract the source IP →
ip-lookup/v3IP(orv3MultiIPfor a batch) → branch ondata.classification/data.actor→ alert/report Output. - CVE-driven hunting — vulnerability feed or patch advisory →
gnql/gnqlV3Querywithcve:<id>→ aggregate matched IPs → Output. - C2 / callback triage — schedule →
callback/callbackListIPsorcallbackOverview(requires the Callback entitlement) → correlate against EASM assets. - Tactics detection drill-down — schedule →
tactics/searchTacticsDetections→ for a detection of interest,getTacticsDetectionfor its command timeline andgetTacticsHostArtifactContentfor a specific touched file. - Blocklist sync —
compare/workspaceDifforblocklists/getBlocklistIPs→ feed the resulting IP list into a firewall/EDR block action.
Response Structure
Every operation returns one of these three envelope shapes, chosen from the runtime Content-Type of GreyNoise's response — never guessed from the operation alone:
{ "success": true, "data": { "...": "GreyNoise's JSON response, passed through verbatim" } }
{ "success": true, "content_type": "text/csv", "data": "field1,field2\n1,2\n" }
{ "success": true, "content_type": "application/vnd.tcpdump.pcap", "encoding": "base64", "data": "<base64-encoded bytes>" }
When GreyNoise returns HTTP 206, both partial_content and partial_content_message are added alongside whichever of the three shapes above applies:
{
"success": true,
"partial_content": true,
"partial_content_message": "GreyNoise returned partial content (HTTP 206): plan limitations restricted the fields and/or data in this response.",
"data": { "...": "..." }
}
Each operation's exact response fields are GreyNoise's own — consult the operation description in the node, or GreyNoise's API reference, for the complete field list of a given endpoint.
Troubleshooting
| Issue | Resolution |
|---|---|
| HTTP 400 (invalid request) | GreyNoise returns a field-level message, preserved in the error (invalid request (400): <message>). Fix the parameter it names. |
| HTTP 401 (invalid api key) | The API key is wrong or expired. Re-check the credential. |
| HTTP 402 (payment required) | Your GreyNoise account's billing needs attention. Contact GreyNoise about your subscription. |
| HTTP 403 "feature not allowed" | The plan lacks the module for that operation (commonly Business Service Intelligence or Callback). Not a credential error — check your plan's entitlements. |
| HTTP 403 "export is not available for demo data" | You called exportSessionData/exportSessionsPcap with scope=demo. Use scope=workspace for exports. |
| HTTP 404 (unknown route) | The node's schema and the live API disagree — this indicates a bug in the node, not your input. |
| HTTP 404 (data-level) | No data exists for what you asked — e.g. an IP GreyNoise has never observed (8.8.8.8 is a real example), an unknown CVE, or a session/blocklist ID that doesn't exist. Not a credential error. |
| HTTP 413 (payload too large) | Reduce the batch size — fewer IPs per v3MultiIP/getBSIBulkLookup call, fewer CVEs per bulkCVELookup. |
| HTTP 429 (rate limited) | Slow down; this node does not auto-retry. Add delays between loop iterations. |
| HTTP 503 (data being prepared) | GreyNoise is still computing the result (e.g. a blocklist's IPs while it refreshes). Retry after a short delay. |
| Sessions query returns nothing | Check scope: a workspace with no deployed sensors returns zero sessions under scope=workspace. Try scope=demo to confirm the query itself is correct. |
Best Practices
- Read
data.<field>, always. Every response — JSON, text, or binary — is wrapped in this node's envelope; nothing GreyNoise returns is at the top level. - Branch on
partial_content. Treat a206-flagged result as incomplete rather than trusting it as the full answer. - Base64-decode binary output before writing a file. PCAPs, Psychic models, and BSI bulk downloads all arrive as base64 text inside
data. - Treat 403 as a plan question first. Check entitlements (Business Service Intelligence, Callback, Psychic, Tactics file-content, private RSS) before assuming the credential is broken.
- Page explicitly. Loop on
scroll/cursor/page/offsetyourself — this node forwards pagination parameters but never automates the loop. - Use
scope=demoto explore,scope=workspaceto export. Demo data is great for validating a Sessions/Tactics query shape, butexportSessionData/exportSessionsPcaprequirescope=workspace. - Treat the four write operations as documented, not verified.
createBlocklist,updateBlocklist,deleteBlocklist, andgenerateRSSFeedTokenmutate account state and were deliberately not exercised during this integration's development — test them carefully against a non-production workspace before relying on them. - Porting a v2 workflow? Consult GreyNoise's own v2→v3 migration guide — the endpoints this node exposes are v3 (plus a couple of stable v1 ones), not the retired v2 surface.