Event Delivery Service
The Event Delivery Service (EDS) V2 delivers real-time notifications to your integration via WebSocket, replacing the SSE-based V1 with a lower-latency, bidirectional protocol.
Prerequisites
Before connecting you need:
- An integration API Key — used in the
Authorizationheader of the WebSocket upgrade request. - A queue name — assigned to your integration. Each queue corresponds to a logical stream of events for your tenant.
Contact Empego to obtain both if you do not already have them.
In this section
- Connection — How to open a WebSocket, authenticate, and handle disconnections and errors.
- Protocol — Wire format, frame types, and field references.
- Events — Event types delivered through EDS V2 and their payload fields.
- Deduplication — At-least-once delivery semantics and how to handle duplicate events.
- FAQ — Answers to common questions about setup, connection, acknowledgement, deduplication, and protocol.
Quick Start
The following pseudo-code sketches the full client lifecycle from first connect to graceful reconnect. Adapt it to your language and WebSocket library.
// 1. Open connection
ws = WebSocket("wss://eds.empego-dev-staging.name?queue={queueName}",
headers: { "Authorization": "api-key {your-api-key}" })
// 2. On successful connection — start ping timer
ws.onOpen = function() {
pingTimer = setInterval(every 2-3 minutes) {
ws.send({ frameType: "PING" })
}
}
// 3. On incoming message — dispatch by frame type
ws.onMessage = function(frame) {
if frame.frameType == "EVENT" {
if not alreadySeen(frame.framePayload.eventId) {
markSeen(frame.framePayload.eventId)
process(frame.framePayload)
}
ws.send({ frameType: "ACK_EVENT", framePayload: { receiptId: frame.framePayload.receiptId } })
}
}
// 4. On close — reconnect unless auth failed
ws.onClose = function(code) {
clearInterval(pingTimer)
if code == 4401 {
return // fix the API key, do not retry
}
delay = initialDelay
while not connected {
wait(delay + randomJitter())
connect()
delay = min(delay * 2, maxDelay)
}
}
// 5. On error — treat as a transient disconnect
ws.onError = function(err) {
ws.close()
}
Key points:
Ping every 2–3 min
- To stay under the 10-minute API Gateway idle timeout.
Ack always
- Even for duplicates;
- Dedup on
eventId, ack onreceiptId - Ack all events (even unsupported types), failure to acknowledge an event will prevent new events to be delivered.