---
updatedAt: 2026-07-31T14:20:52.000Z
agentTools:
  projectIndex: https://docs.greynoise.io/llms.txt
---

# Workspace Diff

Compare GNQL query results between two workspaces. Returns per-IP
diff results showing which IPs exist in each workspace and the
field-level differences between them.

Workspace IDs can be copied from **Plan details** in the [GreyNoise Visualizer](https://viz.greynoise.io): click the user menu in the top right, then select **Plan details**. The workspace ID is shown under the workspace name.


# OpenAPI definition

```json
{
  "openapi": "3.0.0",
  "info": {
    "description": "GreyNoise is a cybersecurity company that collects and analyzes Internet-wide scan and attack traffic. Use GreyNoise to contextualize existing alerts, filter false-positives, identify compromised devices, and track emerging threats.",
    "version": "3.0.0",
    "title": "GreyNoise API",
    "contact": {
      "email": "hello@greynoise.io"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.greynoise.io/terms"
    }
  },
  "tags": [
    {
      "name": "Compare",
      "description": "Endpoints for comparing GNQL query results across workspaces. Compare IP\npresence and statistics between a source and target workspace to identify\ndifferences in observed activity.\n"
    }
  ],
  "security": [
    {
      "APIKeyHeaderAuth": []
    }
  ],
  "paths": {
    "/v3/workspaces/diff": {
      "post": {
        "tags": [
          "Compare"
        ],
        "summary": "Workspace Diff",
        "operationId": "WorkspaceDiff",
        "description": "Compare GNQL query results between two workspaces. Returns per-IP\ndiff results showing which IPs exist in each workspace and the\nfield-level differences between them.\n\nWorkspace IDs can be copied from **Plan details** in the [GreyNoise Visualizer](https://viz.greynoise.io): click the user menu in the top right, then select **Plan details**. The workspace ID is shown under the workspace name.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkspaceDiffRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK - diff results returned successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceDiffResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://api.greynoise.io"
    },
    {
      "url": "http://api.greynoise.io"
    }
  ],
  "components": {
    "securitySchemes": {
      "APIKeyHeaderAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "key"
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request - request syntax is invalid for the specified endpoint.\nVerify request syntax and try again.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorMessage"
            },
            "example": {
              "message": "Invalid parameter"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Unauthorized. Please check your API key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorMessage"
            },
            "example": {
              "message": "Unauthorized"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Forbidden - request is not authorized due to an invalid API key or plan limitations.\nIf due to plan limitations, contact sales@greynoise.io to upgrade your plan and unlock full results.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorMessage"
            },
            "example": {
              "message": "Forbidden"
            }
          }
        }
      },
      "UnexpectedError": {
        "description": "Unexpected error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorMessage"
            },
            "example": {
              "message": "Encountered error while performing request"
            }
          }
        }
      }
    },
    "schemas": {
      "ErrorMessage": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          }
        },
        "required": [
          "message"
        ]
      },
      "WorkspaceDiffRequest": {
        "type": "object",
        "required": [
          "query"
        ],
        "properties": {
          "source_workspace": {
            "type": "string",
            "description": "The source workspace to compare from. Defaults to the workspace\nassociated with the request's API key when omitted. Accepts either\na workspace UUID or one of the aliases `greynoise` (GreyNoise\nproduction / GoG), `community` (community dataset; requires the\ncommunity dataset entitlement), or `personal` (the caller's\nworkspace).\n"
          },
          "target_workspace": {
            "type": "string",
            "description": "The target workspace to compare against. Accepts a workspace UUID or\none of the aliases `greynoise`, `community`, or `personal`. Defaults\nto the GreyNoise production (GoG) workspace when omitted.\n"
          },
          "query": {
            "type": "string",
            "description": "GNQL query string to filter IPs in both workspaces.",
            "example": "classification:malicious"
          },
          "size": {
            "type": "integer",
            "description": "Number of IP diff results to return per page. Defaults to 10, maximum\n1000. Larger result sets are retrieved by paging with `next_token`.\n",
            "default": 10,
            "minimum": 1,
            "maximum": 1000
          },
          "next_token": {
            "type": "string",
            "description": "Pagination token from a previous response to fetch the next page of results."
          },
          "require_both_workspaces": {
            "type": "boolean",
            "description": "When true, only return IPs that exist in both workspaces.",
            "default": false
          },
          "ips_from_source": {
            "type": "boolean",
            "description": "When true, only return IPs sourced from the source workspace.",
            "default": false
          }
        }
      },
      "WorkspaceDiffResult": {
        "type": "object",
        "properties": {
          "ip_diffs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IPDiffResult"
            }
          },
          "source_workspace_name": {
            "type": "string",
            "description": "Display name of the source workspace."
          },
          "target_workspace_name": {
            "type": "string",
            "description": "Display name of the target workspace."
          },
          "count": {
            "type": "integer",
            "description": "Total number of IPs compared."
          },
          "next_token": {
            "type": "string",
            "description": "Token for paginating through additional results."
          }
        }
      },
      "IPDiffResult": {
        "type": "object",
        "properties": {
          "ip": {
            "type": "string",
            "description": "The IP address being compared.",
            "example": "1.2.3.4"
          },
          "in_source_workspace": {
            "type": "boolean",
            "description": "Whether the IP exists in the source workspace."
          },
          "in_target_workspace": {
            "type": "boolean",
            "description": "Whether the IP exists in the target workspace."
          },
          "source_workspace_name": {
            "type": "string",
            "description": "Display name of the source workspace."
          },
          "target_workspace_name": {
            "type": "string",
            "description": "Display name of the target workspace."
          },
          "diff_result": {
            "$ref": "#/components/schemas/DiffResult"
          }
        }
      },
      "DiffResult": {
        "type": "object",
        "description": "Field-level differences between the IP record in each workspace.",
        "properties": {
          "differences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Difference"
            }
          },
          "identical": {
            "type": "boolean",
            "description": "True if the records are identical across both workspaces."
          },
          "truncated": {
            "type": "array",
            "description": "Paths whose `differences` are a prefix rather than the complete set.\nA path is capped at 1000 entries per operation; the comparison\nitself is exact, only the listing is cut. Absent when nothing was\ntruncated. Use the per-IP diff to retrieve a capped path in full.\n",
            "items": {
              "$ref": "#/components/schemas/DiffTruncation"
            }
          }
        }
      },
      "DiffTruncation": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "description": "JSON path whose differences were capped.",
            "example": "raw_data.scan"
          },
          "operation": {
            "type": "string",
            "enum": [
              "added",
              "removed",
              "modified"
            ],
            "description": "The operation whose entries were capped for this path."
          },
          "returned": {
            "type": "integer",
            "description": "Number of entries present in `differences` for this path and operation.",
            "example": 1000
          },
          "total": {
            "type": "integer",
            "description": "Total number of differing entries found for this path and operation.",
            "example": 65534
          }
        }
      },
      "Difference": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "description": "JSON path of the differing field.",
            "example": "metadata.organization"
          },
          "operation": {
            "type": "string",
            "enum": [
              "added",
              "removed",
              "modified"
            ],
            "description": "The type of change detected."
          },
          "source_value": {
            "description": "The value in the source workspace (present for removed and modified operations)."
          },
          "target_value": {
            "description": "The value in the target workspace (present for added and modified operations)."
          }
        }
      }
    }
  }
}
```