---
updatedAt: 2026-08-25T15:12:32.000Z
agentTools:
  projectIndex: https://docs.greynoise.io/llms.txt
---

# Fetch the next feed-event batch

Return events after the named consumer's server-held checkpoint. If the
consumer has no checkpoint, reading begins at the oldest event still
inside retention. Omitting `consumer` uses the `default` consumer.

Fetching is read-only. Repeating this request before acknowledgement can
return the same events. Process the complete batch, then send the response
`cursor` to the acknowledge endpoint with the same consumer name. The
next scheduled fetch does not need to retain or submit that cursor.

If a stored checkpoint has fallen outside retention, reading resumes at
the oldest retained event and `retention.gap_detected` is true. Session
events are webhook-only and are never returned.


# 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": "Event Feeds",
      "description": "Consume and search workspace-scoped feed events retained for approximately\n90 days.\n\nPull consumers keep their checkpoints on the server. Fetching is read-only;\nacknowledge the returned signed cursor only after processing the complete\nbatch. Event search uses a separate stateless pagination cursor and never\nchanges a pull consumer's checkpoint.\n\nSession events are webhook-only and are not retained, searchable, or\navailable through the pull API. Access depends on the workspace's Feeds and\nEvent Feed API entitlements.\n\nFor an end-to-end integration workflow, see\n[Using the Feeds API to Retrieve Events](https://docs.greynoise.io/docs/using-the-feeds-api-to-retrieve-events).\n"
    }
  ],
  "security": [
    {
      "APIKeyHeaderAuth": []
    }
  ],
  "paths": {
    "/v3/feeds/{feed_id}/events": {
      "get": {
        "tags": [
          "Event Feeds"
        ],
        "operationId": "FetchFeedEvents",
        "summary": "Fetch the next feed-event batch",
        "description": "Return events after the named consumer's server-held checkpoint. If the\nconsumer has no checkpoint, reading begins at the oldest event still\ninside retention. Omitting `consumer` uses the `default` consumer.\n\nFetching is read-only. Repeating this request before acknowledgement can\nreturn the same events. Process the complete batch, then send the response\n`cursor` to the acknowledge endpoint with the same consumer name. The\nnext scheduled fetch does not need to retain or submit that cursor.\n\nIf a stored checkpoint has fallen outside retention, reading resumes at\nthe oldest retained event and `retention.gap_detected` is true. Session\nevents are webhook-only and are never returned.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/eventFeedId"
          },
          {
            "in": "query",
            "name": "consumer",
            "required": false,
            "description": "Name of the independent server-held checkpoint.",
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/EventFeedConsumerName"
                }
              ],
              "default": "default"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Maximum number of events to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The next event batch for the named consumer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventFeedFetchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/EventFeedBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/EventFeedUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/EventFeedForbidden"
          },
          "404": {
            "$ref": "#/components/responses/EventFeedNotFound"
          },
          "408": {
            "$ref": "#/components/responses/EventFeedRequestTimeout"
          },
          "500": {
            "$ref": "#/components/responses/EventFeedUnexpectedError"
          },
          "502": {
            "$ref": "#/components/responses/EventFeedBadGateway"
          },
          "504": {
            "$ref": "#/components/responses/EventFeedGatewayTimeout"
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://api.greynoise.io"
    },
    {
      "url": "http://api.greynoise.io"
    }
  ],
  "components": {
    "securitySchemes": {
      "APIKeyHeaderAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "key"
      }
    },
    "responses": {
      "EventFeedBadRequest": {
        "description": "A path parameter, query parameter, request body, filter, or cursor is invalid.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventFeedError"
            },
            "example": {
              "error": "bad request",
              "code": 400
            }
          }
        }
      },
      "EventFeedUnauthorized": {
        "description": "The API key or authenticated user is missing or invalid.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventFeedError"
            },
            "example": {
              "error": "unauthorized",
              "code": 401
            }
          }
        }
      },
      "EventFeedForbidden": {
        "description": "The caller cannot access the workspace or the required entitlement is not enabled.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventFeedError"
            },
            "example": {
              "error": "event feed API entitlement required",
              "code": 403
            }
          }
        }
      },
      "EventFeedNotFound": {
        "description": "The workspace-scoped feed or consumer was not found.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventFeedError"
            },
            "example": {
              "error": "not found",
              "code": 404
            }
          }
        }
      },
      "EventFeedRequestTimeout": {
        "description": "The request was canceled before it completed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventFeedError"
            },
            "example": {
              "error": "request timeout",
              "code": 408
            }
          }
        }
      },
      "EventFeedUnexpectedError": {
        "description": "An unexpected error occurred while processing the request.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventFeedError"
            },
            "example": {
              "error": "internal server error",
              "code": 500
            }
          }
        }
      },
      "EventFeedBadGateway": {
        "description": "The Event Feed service was unavailable or returned an invalid response.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventFeedError"
            },
            "example": {
              "error": "bad gateway",
              "code": 502
            }
          }
        }
      },
      "EventFeedGatewayTimeout": {
        "description": "The Event Feed service did not complete the request before its deadline.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/EventFeedError"
            },
            "example": {
              "error": "gateway timeout",
              "code": 504
            }
          }
        }
      }
    },
    "parameters": {
      "eventFeedId": {
        "name": "feed_id",
        "in": "path",
        "description": "Feed UUID. The feed must belong to the authenticated workspace.",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "schemas": {
      "EventFeedError": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Safe, human-readable error message."
          },
          "code": {
            "type": "integer",
            "description": "HTTP status code."
          },
          "recovery": {
            "$ref": "#/components/schemas/EventFeedRecovery"
          }
        }
      },
      "EventFeedRecovery": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "action"
        ],
        "properties": {
          "action": {
            "type": "string",
            "description": "Recovery action for a cursor that has fallen outside retention.",
            "enum": [
              "fetch_without_cursor",
              "restart_search"
            ]
          }
        }
      },
      "EventFeedEventType": {
        "type": "string",
        "description": "Retained event type. `session-received` and `new-tag-activity` events are\nnot retained and therefore are not available to pull consumers or search.\n",
        "enum": [
          "ip-classification-change",
          "cve-status-change",
          "cve-activity-spike",
          "vendor-cve-spike",
          "tag-spike",
          "new-callback-ip",
          "new-callback-file",
          "credential-observed"
        ]
      },
      "EventFeedEvent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "event_type",
          "payload",
          "created_at"
        ],
        "properties": {
          "event_type": {
            "$ref": "#/components/schemas/EventFeedEventType"
          },
          "payload": {
            "type": "object",
            "additionalProperties": true,
            "description": "Event-type-specific JSON payload."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the event entered the retained feed log."
          }
        }
      },
      "EventFeedRetention": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "oldest_available_at",
          "gap_detected"
        ],
        "properties": {
          "oldest_available_at": {
            "type": "string",
            "format": "date-time",
            "description": "Beginning of the currently retained event window."
          },
          "gap_detected": {
            "type": "boolean",
            "description": "True when a stale consumer checkpoint was automatically resumed at\nthe oldest retained event, meaning some events are no longer available.\n"
          }
        }
      },
      "EventFeedFetchResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "events",
          "has_more",
          "consumer",
          "retention"
        ],
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventFeedEvent"
            }
          },
          "cursor": {
            "type": "string",
            "maxLength": 2048,
            "description": "Opaque signed position for acknowledging the last event in this batch.\nOmitted when the response has no acknowledgeable event.\n"
          },
          "has_more": {
            "type": "boolean",
            "description": "Whether more events currently follow this batch."
          },
          "consumer": {
            "$ref": "#/components/schemas/EventFeedConsumerName"
          },
          "retention": {
            "$ref": "#/components/schemas/EventFeedRetention"
          }
        },
        "example": {
          "events": [
            {
              "event_type": "ip-classification-change",
              "payload": {
                "ip": "198.51.100.42",
                "old_classification": "unknown",
                "new_classification": "malicious"
              },
              "created_at": "2026-08-07T14:21:18Z"
            }
          ],
          "cursor": "eyJ2IjoxLCJ3IjoiLi4uIn0.signature",
          "has_more": false,
          "consumer": "scheduled-lambda",
          "retention": {
            "oldest_available_at": "2026-05-09T00:00:00Z",
            "gap_detected": false
          }
        }
      },
      "EventFeedConsumerName": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$",
        "description": "Stable consumer name beginning with an alphanumeric character and\ncontaining only alphanumerics, period, underscore, or hyphen.\n",
        "example": "scheduled-lambda"
      }
    }
  }
}
```