--- title: Server Events description: The events API is Livingdocs's implementation of the publish/subscribe pattern. --- The events API is Livingdocs's implementation of the publish/subscribe pattern. This allows you to send messages back and forth between features or to listen for events from the core features. Events are fire and forget thus it is possible that some calls might be lost (e.g. when there is a connection outage). If you need reliable transaction-like hooks, see [the hooks feature](/customising/server/server-hooks/llms.txt). ## Requiring events from the li-server Example: ```js const config = require('../conf') const liServer = require('@livingdocs/server')(config) liServer.events.subscribe('document.update', console.log) ``` ## Event firing: `notify` ```js events.notify(event, message) ``` - event `` - message `` The events.notify() methods emits a named event alongside a message object. ## Event subscription: `subscribe` ```js events.subscribe(event, listener) ``` - event `` - listener `` The events.subscribe() method adds a listener that gets called each time the event is fired. ## Event unsubscription: `unsubscribe` ```js events.unsubscribe(event, listener) ``` - event `` - listener `` The events.unsubscribe() method removes the listener that was called each time the event was fired. ## Events unsubscription: `unsubscribeAll` ```js events.unsubscribeAll() ``` The events.unsubscribeAll() method removes all listeners. ## Event subscribers: `subscribers` ```js events.subscribers(event) ``` - event `` The events.subscribers() method lists all the listeners of an event. ## Available Events The following lists all events, before the comma, the name of the event and behind the comma, the parameters received by a listener. > [!NOTE] > When a document or media library event is emitted, the Elasticsearch index may not have been updated yet. Hence, when fetching data from a Public API endpoint that internally queries the Elasticsearch index, the response may not immediately reflect the event. > > Currently, Livingdocs does not provide a mechanism to circumvent this limitation. Customers impacted by this are recommended to delay fetching data after receiving an event. Depending on the use case, such as when invalidating caches, it may be worth considering an alternative cache invalidation strategy. ### User - user.create, `(eventName, {user})` - user.delete, `(eventName, {user})` - user.password.request, `(eventName, {userId, identityId})` - user.password.redeem, `(eventName, {userId, identityId})` - user.password.change, `(eventName, {id, connectionId, identityId, userId})` - user.email.change, `(eventName, identity)` - user.login.success, `(eventName, {user})` - user.login.fail, `(eventName, {error})` - user.login.new-device, `(eventName, {userId, identityId})` - user.newsletter, `(eventName, {newsletter, userId, email, displayName})` ### Document - document.update, `(eventName, {user, documentVersion})` - document.delete, `(eventName, {user, documentVersion})` - document.create, `(eventName, {user, documentVersion})` Note: this event is also triggered by document transforms - document.publish, `(eventName, {user, documentVersion})` - document.unpublish, `(eventName, {user, documentVersion})` - document.copy, `(eventName, {documentVersion, originalDocumentId, isTranslation})` - document.transform, `(eventName, {documentVersion, originalContentType})` - document.build `(eventName, {user, documentVersion, reportId, deliveryHandle})` - document.build.abort `(eventName, {user, documentVersion, reportId, deliveryHandle})` (Added in: [`release-2024-07`](/operations/releases/release-2024-07/)) - document.build.userChoice `(eventName, {user, documentVersion, reportId, deliveryHandle, selectedUserChoice})` (Added in: [`release-2024-07`](/operations/releases/release-2024-07/)) - document.build.draft `(eventName, {user, documentVersion, reportId, deliveryHandle})` - document.build.draft.abort `(eventName, {user, documentVersion, reportId, deliveryHandle})` (Added in: [`release-2024-07`](/operations/releases/release-2024-07/)) - document.build.draft.userChoice `(eventName, {user, documentVersion, reportId, deliveryHandle, selectedUserChoice})` (Added in: [`release-2024-07`](/operations/releases/release-2024-07/)) ### Publication - publication.update, `(eventName, {user, documentVersion})` (Added in: [`release-2024-03`](/operations/releases/release-2024-03/)) - publication.updated, `(eventName, {user, documentVersion})` (Deprecated in: [`release-2024-03`](/operations/releases/release-2024-03/)) ### Document List - document_list.delete, `(eventName, {user, documentList})` - document_list.publish, `(eventName, {user, documentList})` - document_list.update, `(eventName), {user, documentList}` - document_list.create, `(eventName, {user, documentList})` ### Media Library Entry - mediaLibraryEntry.create, `(eventName, {userId, projectId, mediaLibraryEntry})` - mediaLibraryEntry.update, `(eventName, {userId, projectId, id, changes})` - mediaLibraryEntry.archive, `(eventName, {userId, projectId, id})` - mediaLibraryEntry.revoke, `(eventName, {userId, projectId, id, mediaLibraryEntry})` - mediaLibraryEntry.active, `(eventName, {userId, projectId, id})` (Added in: [`release-2024-03`](/operations/releases/release-2024-03/)) - mediaLibraryEntry.invalid, `(eventName, {userId, projectId, id})` (Added in: [`release-2024-03`](/operations/releases/release-2024-03/)) ### Project - project.create, `(eventName, {project})` - project.update, `(eventName, {project})` ### Category - category.update, `(eventName, {pointer, value, projectId, user})` ### Migration Removed in: [`release-2025-01`](/operations/releases/release-2025-01/) - migration.prepare, `(eventName, {migration})` - migration.accept, `(eventName, {migration})` - migration.cancel, `(eventName, {migration})`