41 KiB
| title | name | category | tags | editor | contributors | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| MESSAGING-API | Messaging API definition | Standards Track |
|
Oleksandr Kozlov <oleksandr@status.im> |
|
Abstract
This document specifies an Application Programming Interface (API) that is RECOMMENDED for developers of the WAKU2 clients to implement, and for consumers to use as a single entry point to its functionalities.
This API extends the core protocols with additional functionality required for peer-to-peer messaging applications, including:
- Defines a set of events which MAY be used for subscription to track message propagation, node state, and error handling.
- Defines a set of method calls which MAY be used for invocation of protocol operations.
- Abstracts new primitives to be accessed in a RESTful manner via Waku REST API.
This document defines the specifications and guidelines necessary for implementing the API, ensuring interoperability and consistency across the Waku protocol family.
Design Requirements
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC2119.
Definitions
This section defines key terms and concepts used throughout this document. Each term is detailed in dedicated subsections to ensure clarity and consistency in interpretation.
Multiaddr - a self-describing format for encoding network address of a remote peer as per libp2p addressing specification.
Motivation
Real-world application development has exposed challenges in achieving comprehensive usability guarantees for core Waku protocols. Although recommendations such as P2P-RELIABILITY have been introduced to enhance protocol robustness, the fragmented landscape of guidelines and the requirement to re-implement reliability strategies across diverse use cases remain evident.
A significant challenge has been the lack of a unified abstraction for message exchange. Developers require a straightforward mechanism to send, receive, and track messages—whether originating from a node or propagated throughout its connected network.
API design
Requirements
This API is designed for generic use and ease of implementation across nwaku, js-waku,
and traditional REST architectures.
From this point forward,
relevant code blocks will be provided in JSON format, HTTP format or by using TypeScript syntax.
Initial configuration
The Messaging API is an abstraction layer built upon the basic functionality provided by a node.
The configuration definitions that follow omit implementation-specific details,
focusing exclusively on settings explicitly required by the Messaging API.
{
mode: "edge" | "relay";
clusterId: number;
shards: number[];
storeNodes?: string[];
serviceNodes?: string[];
bootstrapNodes: string[];
confirmStored?: boolean;
confirmReceived?: boolean;
confirmContentTopics?: string[];
}
Properties
mode
This property defines behavior of the node and MUST be specified.
If edge selected the node MUST use LIGHTPUSH for sending messages,
and FILTER for receiving messages.
If relay selected the node MUST:
- Implement RELAY protocol.
- Host endpoint for LIGHTPUSH and FILTER.
- Serve PEER-EXCHANGE protocol.
edge mode SHOULD be used if node functions in resource restricted environment,
where as relay SHOULD be used if node has no hard restrictions.
clusterId
This property MUST be provided. It signifies which cluster a node MUST be operating at as per RELAY-SHARDING.
shards
This property MUST be provided. An array of shard under a specified cluster that node MUST operate at as per RELAY-SHARDING.
storeNodes
A list of Multiaddr addresses to remote peers that SHOULD be used for retrieving past messages or performing infrequent queries using the STORE protocol.
If not provided, nodes discovered through the network SHOULD be used.
serviceNodes
A list of Multiaddr addresses to remote peers that SHOULD be used for obtaining various network resources.
These resources MAY include:
- infrequent STORE queries;
- a LIGHTPUSH endpoint for broadcasting data;
- a FILTER endpoint for receiving circulating data.
If not provided, nodes discovered through the network SHOULD be used.
bootstrapNodes
This property MUST be provided.
A list of Multiaddr addresses to remote peers that SHOULD be used for any applicable method of discovery that MAY include:
confirmStored
An optional property that defaults to false.
If set to true and confirmContentTopics are provided, a recurring background STORE query (as described in the Message Storage API section) MUST be initiated.
If set to true without confirmContentTopics, the background STORE query (as described in the Messaging Storage API section) MUST only be initiated after the Subscribe API is called.
If set to false, the stored property on the MessageRecord (defined in the Message Storage API) MUST NOT be populated, unless History API is triggered.
confirmReceived
An optional property that defaults to true.
If set to true, the node MUST initiate a network listener for messages circulated under confirmContentTopics via either FILTER or RELAY using the Subscribe API.
If set to true but confirmContentTopics are not provided, the received property on the MessageRecord (as defined in the Message Storage API) MUST be populated only after the Subscribe API is called.
If set to false, the received property MUST NOT be populated, unless Subscribe API is called.
confirmContentTopics
An optional property that SHOULD be provided in conjunction with either confirmStored or confirmReceived.
It includes an array of contentTopics that the node MUST start monitoring in the background upon initialization,
as defined in the TOPICS specification.
Programmatic API / REST API
No methods or REST endpoints are provided for initial configuration.
Instead, the initial configuration MUST be supplied at node creation time according to the guidelines of the chosen implementation.
Send
The Send API is responsible for broadcasting messages across the network using the configured protocol.
The node SHOULD select the appropriate protocol based on its configuration and the protocols that are mounted:
- If the initial configuration specifies mode: "edge", then LIGHTPUSH MUST be used to send messages.
- If the initial configuration specifies mode: "relay", then RELAY MUST be used to send messages.
The Send API is also responsible for ensuring message delivery and MUST attempt retries as described in the Retry section.
Retry
If a message fails to satisfy any of the following conditions, it MUST be automatically resent:
- The message is not successfully sent using LIGHTPUSH or RELAY.
- The message is not acknowledged by
Message Storage APIdescribed below. - Retry attempts MUST NOT continue if the node’s health state changes to unhealthy (as defined in the
Health APIdescribed below). - Retry attempts MUST resume when the node’s health state transitions to either
minimally healthyorhealthydefined in theHealth APIbelow.
Retry attempts MUST occur in the background using a fixed retry count and exponential backoff, as follows:
- A total of 3 retry attempts MUST be made following the initial send attempt.
- The retry intervals MUST be 1 second, then 2 seconds, and finally 4 seconds, respectively.
- The decision to retry MUST be based on the underlying protocol’s response from a remote peer.
Request prioritization
Send requests MUST be prioritized based on their submission time and retry status. Freshly scheduled requests MUST be served before those undergoing retry attempts. Among retry attempts, processing MUST occur in descending order of recency—that is, from the most recently scheduled or retried request to the oldest.
Programmatic API
type RequestID = string;
type Message = {
meta?: UInt8Array;
timestamp?: number;
ephemeral?: boolean;
payload: UInt8Array;
};
interface ISend {
public send(encoder: Encoder, message: Message): RequestID;
public cancelRequest(requestId: RequestID): void;
public getPendingRequests(): RequestID[];
};
Encoder
The Encoder object encapsulates the logic for message handling.
It MUST ensure that messages are encoded into the appropriate format for transmission.
Additionally, it MUST provide information regarding the pubsubTopic and contentTopic to which messages SHOULD be sent.
The specific types of encoders, their extended functionalities, and the mechanisms for their instantiation are considered out of scope for this document.
Message
A Message object MUST conform to the MESSAGE specification.
- The payload property MUST be provided.
- All other properties are optional; if omitted, they SHOULD be supplied by the
Encoder.
RequestID
A RequestID is a GUID string that uniquely identifies a message send operation.
This GUID MAY be used to cancel a scheduled request or to retrieve information about the associated message from the Message Storage API.
send
An Encoder and a Message MUST be provided as parameters.
When invoked, the method schedules the message to be sent via LIGHTPUSH or RELAY based on the node’s configuration.
The method MUST throw an error if the pubsubTopic provided by the Encoder is not supported by the underlying node.
The method MUST return the associated RequestID for the scheduled send attempt.
If the send operation fails, it MAY be retried from the Message Storage API using the RequestID.
Additionally, send operation can be monitored by subscribing to message:sent or message:error events described in Event Source API below.
cancelRequest
Cancels a scheduled send attempt associated with a given RequestID.
A call to this method MUST be ignored if the request has already been fulfilled (i.e., if it has succeeded, failed, or been canceled previously) or if the provided RequestID is invalid.
getPendingRequests
Returns an array of unique RequestID values corresponding to send operations that are still pending.
A request is considered pending if it has not yet succeeded,
and it may be actively retrying or scheduled for sending but has not yet been served.
No duplicate RequestID values MUST appear in the returned array.
REST API
send
Request:
POST /send HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"timestamp": 0,
"ephemeral": false,
"meta": "ZXhhbXBsZQ==",
"pubsubTopic": "string",
"contentTopic": "string",
"payload": "ZXhhbXBsZQ=="
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"requestId": "9978c4f1-4465-4537-9d95-0cf016fb1080"
}
Example for 404:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "Failed to send message. Target pubsubTopic 'string' not supported."
}
cancelRequest
Request:
POST /send/cancel HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"requestId": "9978c4f1-4465-4537-9d95-0cf016fb1080"
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "ok"
}
getPendingRequests
Request:
GET /send/requests HTTP/1.1
Accept: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
"9978c4f1-4465-4537-9d95-0cf016fb1080"
]
Subscribe
The Subscribe API SHOULD be used to initiate a subscription over FILTER or RELAY for continuous message retrieval.
When the Subscribe API is invoked, the following behaviors MUST occur.
A subscription is established via FILTER or RELAY based on the node’s configuration for ongoing message reception.
If confirmStored is set to true,
a recurring STORE query MUST be initiated for the specified contentTopics to continuously update the stored property in the MessageRecord (as defined in the Message Storage API) for messages circulating in the network after the Subscribe API call.
For details on the recurring query, refer to the Message Storage API section.
Once the Subscribe API is called, the received property in the MessageRecord (as described in the Message Storage API) MUST be populated.
When the subscription is active, the API MUST trigger the message:* event group as described in the Event Source API section.
Programmatic API
type SubscriptionID = string;
type SubscriptionListener = (message: MessageRecord) => void | Promise<void>;
interface ISubscribe {
public subscribe(decoder: Decoder, fn: SubscriptionListener): SubscriptionID;
public unsubscribe(id: SubscriptionID): void;
public getActiveSubscriptions(): SubscriptionID[];
}
SubscriptionID
A unique identifier (GUID string) representing a subscription. This ID MUST be used to manage active subscriptions, allowing them to be terminated when they are no longer needed.
SubscriptionListener
A callback function that is invoked whenever a new MessageRecord is received.
It processes the incoming message and MAY return a Promise to support asynchronous handling.
The MessageRecord is defined in the Message Storage API section.
subscribe
Registers a new subscription to listen for messages processed by a given Decoder.
The subscription is based on the pubsubTopic and contentTopic provided by the Decoder,
which determine the scope of the subscription and the messages to be received.
The subscription is uniquely identified by a SubscriptionID,
which MUST be used for managing the subscription (e.g., for later unsubscribing).
The method MUST throw an error if the pubsubTopic provided by the Decoder is not supported by the underlying node.
No specific order is guaranteed for callback invocation;
subscription callbacks MUST be executed as messages are received from the protocol in use.
If confirmStored is set to true, a recurring STORE query MUST be started.
unsubscribe
Removes a previously created subscription identified by its unique SubscriptionID.
Once unsubscribed, the associated SubscriptionListener MUST NOT receive any further messages.
If the provided SubscriptionID does not correspond to an active subscription,
the call MUST be ignored.
If recurring STORE query was initiated by this SubscriptionID, it MUST be stopped.
getActiveSubscriptions
Returns an array of unique SubscriptionID values representing all currently active subscriptions.
Each identifier corresponds to a subscription that is in effect,
and no duplicate values MUST be present in the returned array.
Decoder
The Decoder object encapsulates the logic for processing received messages.
It MUST ensure that incoming messages are decoded from their received format into a usable structure.
Additionally, it MUST filter messages based on the contentTopic to ensure that only relevant messages are processed.
The specific types of decoders, their extended functionalities,
and their instantiation mechanisms are considered out of scope for this document.
REST API
Reading messages is performed via the /messages?subscriptionId="<GUID>" endpoint,
as detailed in the Message Storage API section.
subscribe
Request:
POST /subscribe HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"pubsubTopic": "/waku/2/rs/0/2",
"contentTopic": "/example/2/rfc/proto"
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"subscriptionId": "9978c4f1-4465-4537-9d95-0cf016fb1080"
}
Error for 404:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "Cannot create subscription. clusterId 0 is not supported."
}
unsubscribe
Request:
POST /unsubscribe HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"subscriptionId": "9978c4f1-4465-4537-9d95-0cf016fb1080"
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "ok"
}
getActiveSubscriptions
Request:
GET /subscriptions HTTP/1.1
Accept: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
"9978c4f1-4465-4537-9d95-0cf016fb1080",
"a1b2c3d4-5678-90ab-cdef-1234567890ab"
]
Message Storage
The Message Storage API SHOULD be used to retrieve information about messages that have been sent,
received, or stored.
Message storage is populated by:
- Messages sent by the underlying node via the
Send API. - Messages received through an active subscription initiated by the
Subscribe API. - Messages fetched using the
History API.
Messages can be identified by:
- The
message hashas described in the MESSAGE specification. - The
contentTopicassociated with the message, as defined in the TOPICS specification. - The
RequestIDdescribed in theSend APIsection. - The
SubscriptionIDdescribed in theSubscribe APIsection.
These identifiers SHOULD be passed to the appropriate methods described below to retrieve or manage messages.
Depending on the presence of the confirmStored or confirmReceived options in the Initial configuration, the Message Storage API will trigger either the Subscribe API or the periodic STORE query as described in the Acknowledgements section below.
Once a message is added to the Message Storage API, or if any details about it change,
the appropriate events from the message:* event family (as described in the Event Source API section) MUST be invoked after the message is added or updated in the underlying storage.
Acknowledgements
Message acknowledgement is a background operation that performs the following functions:
- It subscribes to FILTER or RELAY and marks messages as
receivedwhen detected. - It periodically queries STORE and marks messages as
storedwhen available.
This operation MUST be initiated if either of the following conditions is met:
- Either
confirmStoredorconfirmReceivedis set totrueandconfirmContentTopicsis provided. - The
Subscribe APIhas been initiated for one or morecontentTopics.
The recurring STORE query MUST prioritize the storeNodes specified in the initial configuration before using other available nodes.
These queries SHOULD occur once every 60 seconds for all confirmContentTopics provided as part of the initial configuration.
Furthermore, if the node’s health status transitions to unhealthy (as defined by the Health API),
the periodic STORE query MUST be halted,
and it MUST resume once the health status transitions to either minimally healthy or healthy.
Recurring STORE query and background subscription to confirmContentTopics is a subscription defined in the Subscribe API and can be handled the same way.
This background subscription has a reserved SubscriptionID of 1692854c-cbde-4afe-901f-1c86ecbd9ea1.
Additionally, the stored property MUST be updated for any other messages received via the History API.
Programmatic API
type MessageRecord = {
sending?: boolean;
sent?: boolean;
stored: boolean;
received: boolean;
requestId?: RequestID;
message: IWakuMessage;
error?: unknown;
};
interface MessageStorage {
getByRequestId(id: RequestID): MessageRecord | undefined;
getByHash(hash: string, skip?: number, take?: number): MessageRecord | undefined;
getByContentTopic(contentTopic: string, skip?: number, take?: number): MessageRecord[];
getBySubscriptionId(id: SubscriptionID, skip?: number, take?: number): MessageRecord[];
}
Properties of MessageRecord
sending
Defaults to false.
Indicates whether a message, originating from the underlying node,
is currently in the process of being transmitted via the Send API.
This property is set to true while the message is actively being sent or during retry attempts.
Once the send operation completes (either successfully or if retry attempts are halted),
the property MUST transition back to false.
This property is not applicable to messages that are received by the node.
sent
Defaults to false.
This field is applicable only to messages sent by the underlying node.
Indicates whether a message, sent by the underlying node via the Send API,
was successfully transmitted.
Once a message is sent successfully, the sent property becomes true and remains unchanged.
If the transmission fails, the property transitions to false and the error field is populated with implementation-specific details.
This update occurs only after the sending property has transitioned back to false.
stored
Defaults to false.
Indicates whether a message has been confirmed to be present in the underlying STORE protocol.
This property is populated based on a recurring STORE query described in Acknowledgements section or via the History API.
Once a message is confirmed as stored, the stored property MUST be updated to true as a final state.
If an error occurs during reception, the error field MUST be populated with implementation-specific details.
received
Defaults to false.
Indicates whether a message was successfully received from the network via Subscribe API.
Once a message is received, the received property MUST be updated to true as a final state.
If an error occurs during reception, the error field MUST be populated with implementation-specific details.
requestId
Defaults to null.
An optional property applicable only to messages sent by the underlying node via the Send API.
When present, it corresponds to the RequestID from the Send API, remains constant once set.
message
This includes, but is not limited to, the following attributes:
payload: MUST contain the message data payload.contentTopic: MUST specify a string identifier used for content-based filtering.meta: If present, contains an arbitrary application-specific variable-length byte array (maximum 64 bytes) for supplementary details.version: If present, contains a version number to distinguish different types of payload encryption; if omitted, it SHOULD be interpreted as version 0.timestamp: If present, indicates the time the message was generated (in Unix epoch nanoseconds); if omitted, it SHOULD be interpreted as 0.ephemeral: If present andtrue, the message is considered transient and SHOULD not be persisted; if omitted orfalse, the message is considered non-ephemeral.
For a complete description of the message attributes, refer to the MESSAGE specification.
error
An optional property that, if present, indicates that an error occurred during the processing of the message—whether while sending or upon receiving.
This may include network, protocol, decoding errors, or other implementation-specific issues.
Once set, the error persists; however, if a message that initially encountered an error (e.g., associated with a RequestID) is later successfully transmitted, the error information MUST be cleared.
Methods
getByRequestId
Retrieves the MessageRecord corresponding to the specified RequestID associated with a send request for a particular message.
If the provided RequestID is invalid or no associated MessageRecord exists,
the method MUST return nothing.
getByHash
Retrieves the MessageRecord corresponding to the provided message hash.
The hash is computed deterministically based on the message content,
as described in the MESSAGE specification.
If the provided hash is invalid or no associated MessageRecord exists,
the method MUST return nothing.
getByContentTopic
Retrieves an array of MessageRecord objects corresponding to messages that were circulated under the specified contentTopic.
The method accepts two optional parameters for pagination:
skip: A non-negative integer specifying the number of initial matching records to bypass. Ifskipexceeds the total number of matching records, the method MUST return an empty array.take: A non-negative integer specifying the maximum number of records to return. Iftakeis 0, the method MUST return an empty array. Iftakeis greater than the number of available records, all remaining matching records are returned.
If both skip and take are omitted, the method MUST return all matching records.
If no records match the specified contentTopic, an empty array MUST be returned.
getBySubscriptionId
Retrieves an array of MessageRecord objects corresponding to messages received under the specified SubscriptionID (as defined in the Subscribe API section).
The method accepts two optional parameters for pagination:
skip: A non-negative integer specifying the number of initial matching records to bypass. Ifskipexceeds the total number of matching records, the method MUST return an empty array.take: A non-negative integer specifying the maximum number of records to return. Iftakeis 0, the method MUST return an empty array. Iftakeis greater than the number of available records, all remaining matching records are returned.
If both skip and take are omitted, the method MUST return all matching records.
If no records match the specified SubscriptionID, an empty array MUST be returned.
REST API
By RequestID
Request:
GET /message?requestId=xyz789 HTTP/1.1
Accept: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"sending": true,
"sent": false,
"stored": false,
"received": false,
"requestId": "xyz789",
"message": {
"payload": "U29tZSBvdGhlciBkYXRh",
"contentTopic": "/example/another-topic"
}
}
Error for 404:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "Message with requestId 'xyz789' not found"
}
By hash
Request:
GET /message?hash=abc123 HTTP/1.1
Accept: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"sending": false,
"sent": false,
"stored": true,
"received": false,
"message": {
"payload": "SGVsbG8gd29ybGQ=",
"contentTopic": "/example/topic"
}
}
Error for 404:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "Message with hash 'abc123' not found"
}
By contentTopic
Request:
GET /messages?contentTopic=/messaging/2/api/utf8&skip=0&take=10 HTTP/1.1
Accept: application/json
Note: If skip and take are omitted, the request URL would be:
GET /messages?contentTopic=/messaging/2/api/utf8 HTTP/1.1
Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"sent": false,
"stored": false,
"received": true,
"message": {
"payload": "SW5pdGlhbCBtZXNzYWdl",
"contentTopic": "/messaging/2/api/utf8"
}
}
]
Error for 404:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "No messages found for contentTopic '/messaging/2/api/utf8'"
}
By subscriptionId
Request:
GET /messages?subscriptionId=1692854c-cbde-4afe-901f-1c86ecbd9ea1&skip=0&take=10 HTTP/1.1
Accept: application/json
Note: When omitting pagination parameters, the URL would be:
GET /messages?subscriptionId=1692854c-cbde-4afe-901f-1c86ecbd9ea1 HTTP/1.1
Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"sent": false,
"stored": false,
"received": true,
"message": {
"payload": "SW5pdGlhbCBtZXNzYWdl",
"contentTopic": "/messaging/2/api/utf8"
}
}
]
Error for 404:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "No messages found for subscriptionId '1692854c-cbde-4afe-901f-1c86ecbd9ea1'"
}
Health Indicator
The Health Indicator API SHOULD be used to monitor the health of a node operating under the Messaging API.
The specific criteria for determining the health state MAY vary depending on the protocols the node utilizes.
We define three health states:
- unhealthy;
- minimally healthy;
- healthy;
The Health Indicator API SHOULD be used to monitor the operational health of a node operating under the Messaging API.
The criteria for determining a node’s health state MAY vary depending on the protocols in use and the node’s configuration.
Detailed criteria for each health state are provided in the subsequent sections.
For the purposes of this specification, three health states are defined:
unhealthy: Indicates that the node is in a degraded state and may not reliably process or transmit messages.minimally healthy: Indicates that the node meets the minimum operational requirements, although performance or reliability may be impacted.healthy: Indicates that the node is operating optimally, with full support for message processing and transmission.
Furthermore, any change in the node’s health state MUST trigger a health:change event via the Event Source API immediately after the state transition occurs.
Refer to Event Source API for more details.
Health states
unhealthy
Indicates that the node’s connectivity is insufficient for reliable operation. In this state:
- No connections to service nodes are available, regardless of protocol.
- No peers are present in the RELAY mesh.
minimally healthy
Indicates that the node meets the minimum connectivity requirements necessary to function, although performance or reliability may be compromised. In this state:
- The node has at least one connection to a service node implementing FILTER and one connection to a service node implementing LIGHTPUSH.
- The RELAY mesh includes connections to at least four other peers.
healthy
Indicates that the node’s connectivity meets or exceeds optimal operational thresholds. In this state:
- The node has at least two connections to service nodes implementing FILTER and at least two connections to service nodes implementing LIGHTPUSH.
- The RELAY mesh includes connections to at least six other peers.
Programmatic API
enum HealthStatus {
Unhealthy = "Unhealthy",
MinimallyHealthy = "MinimallyHealthy",
Healthy = "Healthy"
}
node.healthIndicator == "MinimallyHealthy";
REST API
Request:
GET /health HTTP/1.1
Accept: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
status: "MinimallyHealthy"
}
Event source
One component of the Messaging API is an event emitter that SHOULD be used to track various internal activities.
Consumers MAY subscribe to this event source to monitor message propagation,
network changes, or the health status of the node.
Events are dispatched only after an actual change to the underlying data occurs,
ensuring that notifications reflect genuine updates.
For accessing events via the REST API, long polling SHOULD be used.
Programmatic API
type EventHandler = (event: CustomEvent<unknown>): void;
interface IEvents {
public addEventListener(eventName: string, fn: EventHandler): void;
public removeEventListener(eventName: string, fn: EventHandler): void;
}
CustomEvent
A container object that holds the payload of an event along with implementation-specific metadata.
The detail property carries the event payload, while other metadata may vary based on the Waku implementation.
EventHandler
A callback function that is invoked whenever an event with a supported eventName is dispatched.
Event handlers are triggered in the order in which they were added (i.e., in the order of subscription).
The function receives a CustomEvent containing the event payload.
addEventListener
Registers an event listener for a specified eventName using the provided EventHandler.
If the given eventName is not supported, the call MUST be silently ignored.
Additionally, if an exception is thrown within the function passed to addEventListener,
that error MUST be ignored and not affect subsequent event handling.
removeEventListener
Removes a previously registered event listener for the specified eventName and EventHandler.
If the eventName is not supported or the EventHandler was not previously registered,
the call MUST be silently ignored.
Events
health:change
This event MUST be emitted whenever the node’s health state changes,
as determined by the Health Indicator API.
The event’s payload (accessible via event.detail) is the new HealthStatus value (Unhealthy, MinimallyHealthy, or Healthy).
The event is dispatched immediately after the underlying data is updated to reflect the health state change.
Programmatic API:
node.events.addEventListener("health:change", (event: CustomEvent<HealthStatus>) => {
// event.detail holds the new HealthStatus value
console.log(event.detail);
});
For accessing health change events via the REST API, long polling SHOULD be used.
Refer to Health Indicator API section for REST API endpoint.
message:change
This event MUST be dispatched whenever any of the key properties of a MessageRecord change.
Specifically stored, received,sent or sending.
The event payload (accessible via event.detail) is the updated MessageRecord reflecting the changes.
node.events.addEventListener("message:change", (event: CustomEvent<MessageRecord>) => {
// event.detail holds the updated MessageRecord
console.log(event.detail);
});
For the REST API, long polling over the Message Store API SHOULD be used.
message:sent
This event MUST be dispatched immediately after a message that originated from the underlying node transitions from being in the sending state
(i.e., when sending becomes false) to a state where it is confirmed as successfully transmitted (i.e., sent becomes true).
The payload is the MessageRecord reflecting this updated status.
node.events.addEventListener("message:sent", (event: CustomEvent<MessageRecord>) => {
// event.detail holds the updated MessageRecord
console.log(event.detail);
});
For the REST API, long polling over the Message Store API SHOULD be used.
message:error
This event MUST be dispatched when an error occurs during the processing of a message whether while sending or receiving.
In such cases, the error property of the corresponding MessageRecord is populated with implementation-specific error information.
The event payload is the MessageRecord containing the error details.
Once a previously errored message is successfully transmitted, the error information MUST be cleared and an updated event (such as message:sent or message:change) should be dispatched.
node.events.addEventListener("message:error", (event: CustomEvent<MessageRecord>) => {
// event.detail holds the updated MessageRecord
console.log(event.detail);
});
For the REST API, long polling over the Message Store API SHOULD be used.
message:received
This event MUST be dispatched when a message is successfully received from the network via the Subscribe API.
At that point, the received property in the corresponding MessageRecord is updated to true.
The payload is the updated MessageRecord.
node.events.addEventListener("message:received", (event: CustomEvent<MessageRecord>) => {
// event.detail holds the updated MessageRecord
console.log(event.detail);
});
For the REST API, long polling over the Message Store API SHOULD be used.
message:stored
This event MUST be dispatched when a message is confirmed to be stored in the underlying STORE protocol or via the History API.
When the message is stored, the stored property in the corresponding MessageRecord is updated to true.
The payload is the updated MessageRecord.
node.events.addEventListener("message:stored", (event: CustomEvent<MessageRecord>) => {
// event.detail holds the updated MessageRecord
console.log(event.detail);
});
For the REST API, long polling over the Message Store API SHOULD be used.
Security/Privacy Considerations
Copyright
Copyright and related rights waived via CC0.