---
title: "List change feed events"
method: GET
path: "/v1/events"
tags: ["Events"]
---

# List change feed events

`GET /v1/events`

List this organization's change feed, ordered and resumable by cursor.

A consumer can be killed mid-stream and resume from its last stored
`next_cursor` without re-reading or missing anything, **as long as it
resumes within the 90-day retention window** — events older than that
are permanently expired, not archived. A consumer that has been down
longer than 90 days must resync current state instead of resuming.

A cursor is only meaningful for a FIXED filter set: it encodes a
position in this organization's overall sequence, not a position
within any particular `namespace_id`/`event_type` filter. Changing
either filter mid-stream while reusing an old cursor silently skips
whatever the previous filter combination would have matched in
between — start a fresh cursor (or none) whenever the filters change.

## Query parameters

- `cursor` string, nullable — Opaque cursor from a prior response's next_cursor. Omit to start from the beginning of the 90-day retention window.
- `namespace_id` string, nullable — Filter to events scoped to one namespace.
- `event_type` 'object.created' | 'objects.created.batch' | 'object.updated' | 'object.deleted' | 'document.created' | 'document.updated' | 'document.deleted' | 'documents.updated.batch' | 'documents.deleted.batch' | 'collection.created' | 'collection.updated' | 'collection.deleted' | 'collection.documents.written' | 'cluster.created' | 'cluster.updated' | 'cluster.deleted' | 'cluster.execution.started' | 'cluster.execution.completed' | 'cluster.execution.failed' | 'trigger.created' | 'trigger.updated' | 'trigger.deleted' | 'trigger.paused' | 'trigger.resumed' | 'trigger.fired' | 'trigger.execution.completed' | 'trigger.execution.failed' | 'taxonomy.created' | 'taxonomy.updated' | 'taxonomy.deleted' | 'alert.created' | 'alert.updated' | 'alert.deleted' | 'alert.triggered' | 'alert.execution.completed' | 'alert.execution.failed' | 'annotation.created' | 'annotation.updated' | 'annotation.deleted' — Webhook event types for real-time notifications. These events are emitted when significant state changes occur in the system. Webhooks subscribe to specific event types and receive notifications via configured channels (email, Slack, HTTP webhooks). Event Naming Convention: {resource}.{action}[.{sub-resource}[.{sub-action}]] Examples: - object.created: New object ingested - collection.documents.written: Documents indexed - cluster.execution.completed: Cluster job finished Cache Invalidation Annotations: Each event type includes a comment indicating recommended cache invalidation scope: - [KEY] = Invalidate specific document/object keys - [COLLECTION] = Invalidate collection-level cache - [NAMESPACE] = Invalidate namespace-level cache Event Categories: - Object Lifecycle: Events for individual objects (create, update, delete) - Collection Lifecycle: Events for collections (create, update, delete, documents written) - Cluster Lifecycle: Events for clusters (create, update, delete, execution status) - Trigger Lifecycle: Events for cluster triggers (create, update, fire, execution status) - Taxonomy Lifecycle: Events for taxonomies (create, update, delete) Use Cases: - Real-time sync with external systems - Audit trail and compliance logging - Automated workflows triggered by state changes - Cache invalidation for distributed systems - Notifications to team members via Slack/email
- `limit` integer

## Response `200`

Successful Response

- ListEventsResponse
  - `results` ChangeEventResponse[], required
    - `seq` integer, required — Monotonic position within this org's feed.
    - `cursor` string, required — Opaque cursor pointing AT this event.
    - `namespace_id` string, nullable — Namespace scope, if any.
    - `event_type` string, required — Same vocabulary as webhook subscriptions.
    - `resource_type` string, required — First segment of event_type.
    - `operation` string, required — insert | update | delete | other.
    - `payload` object — Shape is PER-EVENT-TYPE, not a stable contract — it mirrors whatever the originating call site already passes to WebhookClient.emit() for this event_type, and that shape may change independently of this endpoint's own versioning.
    - `created_at` string, date-time, required
  - `next_cursor` string, nullable — Pass as `cursor` on the next call to resume after these results. Unchanged from the request's cursor when this page was empty.
  - `has_more` boolean, required — Whether another page is available beyond this one.

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found
- `422` — Validation Error
- `500` — Internal Server Error

---

[API](https://skmtc.net/mixpeek/apis/mixpeek-api.md) · [All operations](https://skmtc.net/mixpeek/apis/mixpeek-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mixpeek/mixpeek-api/versions/220a3b263fda/schema)
