Events API
Base path: /api/workspaces/{workspaceId}/events
The event system allows workspace members and extensions to broadcast platform events. Events are workspace-scoped and dispatched to all subscribed extensions.
Authorization: Requires
ADMINrole or workspace membership.
Publish an Event
POST /api/workspaces/{workspaceId}/events/publish
Content-Type: application/jsonRequest Body (PublishEventDTO)
| Field | Type | Required | Description |
|---|---|---|---|
eventKey | string | ✅ | Dot-separated event identifier (e.g. crm.deal.closed) |
schemaVersion | string | — | Payload schema version (e.g. 1.0) |
actor | string | — | ID or name of the entity publishing the event |
payload | object | — | Arbitrary key-value payload map |
Example
curl -X POST http://localhost:8080/api/workspaces/ws-uuid/events/publish \
-H "Content-Type: application/json" \
-b cookies.txt \
-d '{
"eventKey": "crm.deal.closed",
"schemaVersion": "1.0",
"actor": "user-uuid",
"payload": {
"dealId": "deal-123",
"amount": "5000.00",
"currency": "USD"
}
}'Response 200 OK
{ "code": "SUCCESS" }Well-Known Event Keys
| Event Key | Published By | Description |
|---|---|---|
crm.deal.closed | CRM extension | A deal was closed |
crm.product.created | CRM extension | A product was created |
platform.notification | Any extension | Cross-extension notification to a chat channel |
chat.message.received | Chat extension | A new message was received |
Cross-Extension Notifications
Any extension can post a message to a chat channel by publishing the platform.notification event with the following payload:
{
"eventKey": "platform.notification",
"payload": {
"channel": "deals",
"message": "Deal #123 closed for $5,000!",
"sender": "crm-bot"
}
}Well-known channels:
| Channel | Description |
|---|---|
general | General workspace notifications |
deals | CRM deal activity |
{conversationId} | Any specific conversation ID |
Extensions do not need to depend on the chat extension — publishing
platform.notificationis the only requirement.
Dispatch Flow
When an event is published:
- Platform records the
PlatformEvent(eventKey, tenantId, actor, payload, occurredAt) - Queries
ext_event_subscriptionfor subscribers matching(workspaceId, eventKey) - Filters only enabled, installed extensions
- For each subscriber:
EXTERNAL_SERVICE: HTTPPOSTto{serviceBaseUrl}/eventsIN_PROCESS:InProcessEventGatewayreflects over the plugin'sPlatformEventHandler, finds methods annotated with@EventHandler(eventKey = "..."), deserializes payload, and invokes
Async handlers (async = true) run on a dedicated eventExecutor thread pool and do not block the publisher.
Dead Letter Events
If an event delivery fails, it is stored in the dead_letter_event table for later inspection or replay.