Listening for content changes through the API.

The listen endpoint can be used to receive events whenever documents are modified:

GET /data/listen/<dataset>?query=<GROQ-query>

This endpoint follows the server-sent events protocol using the mime-type text/event-stream. The backend will hold the connection open and stream events as they occur for any documents matching the GROQ query.


  • querystring

    The GROQ-query used to filter the events. Only the filter portion of the query will be used, anything else will be ignored.

  • $-params

    Parameters to the query, if any (see the /data/query endpoint for details).

  • includeResultboolean

    Include the resulting document in addition to the changes.

  • includePreviousRevisionboolean

    Include the document as it looked before the change.

  • visibilitystring

    Specifies whether events should be sent as soon as a transaction has been committed (transaction, default), or only after they are available for queries (query). Note that this is best-effort, and listeners with query may in certain cases (notably with deferred transactions) receive events that are not yet visible to queries. The visibility event field will indicate the actual visibility.

  • evs_preamble

    Send a prolog of 2056 no-op characters for compatibility with older browsers.


A line starting with a colon is a comment and should be ignored. You will occasionally receive a single line with just one colon, as this is used for keep-alive.

welcome event

Sent when the listener is set up and ready to serve mutations:

event: welcome
data: {"listenerName": "Ua6BR3GwQ14cnZXrgwCdsF"}

mutation events

Sent whenever a document matching the listener's query is mutated:

event: mutation
id: lqgiok-skp-eja-k6z-9wrng7k5e#38123cba-286c-45a0-a6d1-3cc4dc43748a
data: <JSON-payload on a single line>

The payload is one single line of JSON, which in expanded form looks like this:

  // eventId: A unique id for this event, comprised of the transaction id and the document id
  "eventId": "pzeuul-awl-b69-ij3-g8862vgf3#drafts.38123cba-286c-45a0-a6d1-3cc4dc43748a",

  // documentId: The document changed by these mutations
  "documentId": "drafts.38123cba-286c-45a0-a6d1-3cc4dc43748a",

  // transactionId: The id of the transaction (one transaction may touch several documents, 
  // so you may get several messages with the same transactionId)
  "transactionId": "pzeuul-awl-b69-ij3-g8862vgf3",

  // transition: "update" means the document was updated, "appear" means the document just now started
  // matching your query. "disappear" means the document now left your scope. Appear/disappear may mean
  // the document is created/deleted, but it may also mean the properties of your document started/stopped
  // matching your query.
  "transition": "update",
  // identity: The identifier of the user submitting the changes
  "identity": "pJNdYiKyA",
  // mutations: an array of mutations as they were submitted in a call to /data/mutate. There may be several,
  // but they will all be from the same transaction, and they will all pertain to the document specified in
  // documentId.
  "mutations": [],
  // result: if includeResult url-parameter was submitted, this will contain the entire document as it looks after
  // the mutations.
  "result": {},
  // previous: if includePreviousRevision url-parameter was submitted, this will contain the document as it looked
  // before the mutations.
  "previous": {},
  // previousRev: The previous revision tag of the document before the changes (the current revision tag is always stored with
  // the document under the _rev key)
  "previousRev": "08p48x-bog-ro2-8sh-brvd69hcd",
  // resultRev: The revision tag after the changes. Due to the distributed nature of the Sanity backend, mutation events may 
  // appear out of order, in a very correct client the mutations must be reassembled to an unbroken chain where previousRev 
  // matches the resultRev of the previous mutation event.
  "resultRev": "pzeuul-awl-b69-ij3-g8862vgf3",
  // timestamp: The timestamp of the transaction causing this change
  "timestamp": "2017-11-22T10:24:01.801339Z",
  // visibility: Whether the change that triggered this event is visible to queries (query) or only to
  // subsequent transactions (transaction). The listener client can specify a preferred visbility through
  // the visibility parameter.
  "visibility": "transaction"

channelError events

Sent when there is an error during processing, typically when there is a syntax error in the query.

event: channelError
message: {"message": <the error message>}

disconnect events

Sent when the client should disconnect and stay disconnected, typically following a fatal channelError event (e.g. query syntax error) where reconnecting would simply repeat the error.

event: disconnect
data: {"reason": <a string describing the reason>}

Was this article helpful?