---
title: Websocket
description: Websocket protocol schemas
---

{/* ⚠️  AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs go in content/docs/guides/. */}

WebSocket Event Protocol

Defines the schema for WebSocket-based real-time communication in ObjectStack.

Supports event subscriptions, filtering, presence tracking, and collaborative editing.

Industry alignment: Firebase Realtime Database, Socket.IO, Pusher

<Callout type="info">
**Source:** `packages/spec/src/api/websocket.zod.ts`
</Callout>

## TypeScript Usage

```typescript
import { AckMessage, CursorMessage, CursorPosition, DocumentState, EditMessage, EditOperation, EditOperationType, ErrorMessage, EventFilter, EventFilterCondition, EventMessage, EventPattern, EventSubscription, FilterOperator, PingMessage, PongMessage, PresenceMessage, PresenceState, PresenceUpdate, SimpleCursorPosition, SimplePresenceState, SubscribeMessage, UnsubscribeMessage, UnsubscribeRequest, WebSocketConfig, WebSocketEvent, WebSocketMessage, WebSocketMessageType, WebSocketPresenceStatus, WebSocketServerConfig } from '@objectstack/spec/api';
import type { AckMessage, CursorMessage, CursorPosition, DocumentState, EditMessage, EditOperation, EditOperationType, ErrorMessage, EventFilter, EventFilterCondition, EventMessage, EventPattern, EventSubscription, FilterOperator, PingMessage, PongMessage, PresenceMessage, PresenceState, PresenceUpdate, SimpleCursorPosition, SimplePresenceState, SubscribeMessage, UnsubscribeMessage, UnsubscribeRequest, WebSocketConfig, WebSocketEvent, WebSocketMessage, WebSocketMessageType, WebSocketPresenceStatus, WebSocketServerConfig } from '@objectstack/spec/api';

// Validate data
const result = AckMessage.parse(data);
```

---

## AckMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **ackMessageId** | `string` | ✅ | ID of the message being acknowledged |
| **success** | `boolean` | ✅ | Whether the operation was successful |
| **error** | `string` | optional | Error message if operation failed |


---

## CursorMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **cursor** | `Object` | ✅ | Cursor position |


---

## CursorPosition

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **userId** | `string` | ✅ | User identifier |
| **sessionId** | `string` | ✅ | Session identifier |
| **documentId** | `string` | ✅ | Document identifier being edited |
| **position** | `Object` | optional | Cursor position in document |
| **selection** | `Object` | optional | Selection range (if text is selected) |
| **color** | `string` | optional | Cursor color for visual representation |
| **userName** | `string` | optional | Display name of user |
| **lastUpdate** | `string` | ✅ | ISO 8601 datetime of last cursor update |


---

## DocumentState

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **documentId** | `string` | ✅ | Document identifier |
| **version** | `integer` | ✅ | Current document version |
| **content** | `string` | ✅ | Current document content |
| **lastModified** | `string` | ✅ | ISO 8601 datetime of last modification |
| **activeSessions** | `string[]` | ✅ | Active editing session IDs |
| **checksum** | `string` | optional | Content checksum for integrity verification |


---

## EditMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **operation** | `Object` | ✅ | Edit operation |


---

## EditOperation

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **operationId** | `string` | ✅ | Unique operation identifier |
| **documentId** | `string` | ✅ | Document identifier |
| **userId** | `string` | ✅ | User who performed the edit |
| **sessionId** | `string` | ✅ | Session identifier |
| **type** | `Enum<'insert' \| 'delete' \| 'replace'>` | ✅ | Type of edit operation |
| **position** | `Object` | ✅ | Starting position of the operation |
| **endPosition** | `Object` | optional | Ending position (for delete/replace operations) |
| **content** | `string` | optional | Content to insert/replace |
| **version** | `integer` | ✅ | Document version before this operation |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when operation was created |
| **baseOperationId** | `string` | optional | Previous operation ID this builds upon (for OT) |


---

## EditOperationType

### Allowed Values

* `insert`
* `delete`
* `replace`


---

## ErrorMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **code** | `string` | ✅ | Error code |
| **message** | `string` | ✅ | Error message |
| **details** | `any` | optional | Additional error details |


---

## EventFilter

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **conditions** | `Object[]` | optional | Array of filter conditions |
| **and** | `[#](./#)[]` | optional | AND logical combination of filters |
| **or** | `[#](./#)[]` | optional | OR logical combination of filters |
| **not** | `[#](./#)` | optional | NOT logical negation of filter |


---

## EventFilterCondition

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **field** | `string` | ✅ | Field path to filter on (supports dot notation, e.g., "user.email") |
| **operator** | `Enum<'eq' \| 'ne' \| 'gt' \| 'gte' \| 'lt' \| 'lte' \| 'in' \| 'nin' \| 'contains' \| 'startsWith' \| 'endsWith' \| 'exists' \| 'regex'>` | ✅ | Comparison operator |
| **value** | `any` | optional | Value to compare against (not needed for "exists" operator) |


---

## EventMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **subscriptionId** | `string` | ✅ | Subscription ID this event belongs to |
| **eventName** | `string` | ✅ | Event name |
| **object** | `string` | optional | Object name the event relates to |
| **payload** | `any` | ✅ | Event payload data |
| **userId** | `string` | optional | User who triggered the event |


---


---

## EventSubscription

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **subscriptionId** | `string` | ✅ | Unique subscription identifier |
| **events** | `string[]` | ✅ | Event patterns to subscribe to (supports wildcards, e.g., "record.*", "user.created") |
| **objects** | `string[]` | optional | Object names to filter events by (e.g., ["account", "contact"]) |
| **filters** | `[__schema0](./__schema0)` | optional | Advanced filter conditions for event payloads |
| **channels** | `string[]` | optional | Channel names for scoped subscriptions |


---

## FilterOperator

### Allowed Values

* `eq`
* `ne`
* `gt`
* `gte`
* `lt`
* `lte`
* `in`
* `nin`
* `contains`
* `startsWith`
* `endsWith`
* `exists`
* `regex`


---

## PingMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |


---

## PongMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **pingMessageId** | `string` | optional | ID of ping message being responded to |


---

## PresenceMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **presence** | `Object` | ✅ | Presence state |


---

## PresenceState

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **userId** | `string` | ✅ | User identifier |
| **sessionId** | `string` | ✅ | Unique session identifier |
| **status** | `Enum<'online' \| 'away' \| 'busy' \| 'offline'>` | ✅ | Current presence status |
| **lastSeen** | `string` | ✅ | ISO 8601 datetime of last activity |
| **currentLocation** | `string` | optional | Current page/route user is viewing |
| **device** | `Enum<'desktop' \| 'mobile' \| 'tablet' \| 'other'>` | optional | Device type |
| **customStatus** | `string` | optional | Custom user status message |
| **metadata** | `Record<string, any>` | optional | Additional custom presence data |


---

## PresenceUpdate

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **status** | `Enum<'online' \| 'away' \| 'busy' \| 'offline'>` | optional | Updated presence status |
| **currentLocation** | `string` | optional | Updated current location |
| **customStatus** | `string` | optional | Updated custom status message |
| **metadata** | `Record<string, any>` | optional | Updated metadata |


---

## SimpleCursorPosition

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **userId** | `string` | ✅ | User identifier |
| **recordId** | `string` | ✅ | Record identifier being edited |
| **fieldName** | `string` | ✅ | Field name being edited |
| **position** | `number` | ✅ | Cursor position (character offset from start) |
| **selection** | `Object` | optional | Text selection range (if text is selected) |


---

## SimplePresenceState

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **userId** | `string` | ✅ | User identifier |
| **userName** | `string` | ✅ | User display name |
| **status** | `Enum<'online' \| 'away' \| 'offline'>` | ✅ | User presence status |
| **lastSeen** | `number` | ✅ | Unix timestamp of last activity in milliseconds |
| **metadata** | `Record<string, any>` | optional | Additional presence metadata (e.g., current page, custom status) |


---

## SubscribeMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **subscription** | `Object` | ✅ | Subscription configuration |


---

## UnsubscribeMessage

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **request** | `Object` | ✅ | Unsubscribe request |


---

## UnsubscribeRequest

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **subscriptionId** | `string` | ✅ | Subscription ID to unsubscribe from |


---

## WebSocketConfig

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **url** | `string` | ✅ | WebSocket server URL |
| **protocols** | `string[]` | optional | WebSocket sub-protocols |
| **reconnect** | `boolean` | ✅ | Enable automatic reconnection |
| **reconnectInterval** | `integer` | ✅ | Reconnection interval in milliseconds |
| **maxReconnectAttempts** | `integer` | ✅ | Maximum reconnection attempts |
| **pingInterval** | `integer` | ✅ | Ping interval in milliseconds |
| **timeout** | `integer` | ✅ | Message timeout in milliseconds |
| **headers** | `Record<string, string>` | optional | Custom headers for WebSocket handshake |


---

## WebSocketEvent

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `Enum<'subscribe' \| 'unsubscribe' \| 'data-change' \| 'presence-update' \| 'cursor-update' \| 'error'>` | ✅ | Event type |
| **channel** | `string` | ✅ | Channel identifier (e.g., "record.account.123", "user.456") |
| **payload** | `any` | ✅ | Event payload data |
| **timestamp** | `number` | ✅ | Unix timestamp in milliseconds |


---

## WebSocketMessage

### Union Options

This schema accepts one of the following structures:

#### Option 1

**Type:** `subscribe`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **subscription** | `Object` | ✅ | Subscription configuration |

---

#### Option 2

**Type:** `unsubscribe`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **request** | `Object` | ✅ | Unsubscribe request |

---

#### Option 3

**Type:** `event`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **subscriptionId** | `string` | ✅ | Subscription ID this event belongs to |
| **eventName** | `string` | ✅ | Event name |
| **object** | `string` | optional | Object name the event relates to |
| **payload** | `any` | ✅ | Event payload data |
| **userId** | `string` | optional | User who triggered the event |

---

#### Option 4

**Type:** `presence`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **presence** | `Object` | ✅ | Presence state |

---

#### Option 5

**Type:** `cursor`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **cursor** | `Object` | ✅ | Cursor position |

---

#### Option 6

**Type:** `edit`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **operation** | `Object` | ✅ | Edit operation |

---

#### Option 7

**Type:** `ack`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **ackMessageId** | `string` | ✅ | ID of the message being acknowledged |
| **success** | `boolean` | ✅ | Whether the operation was successful |
| **error** | `string` | optional | Error message if operation failed |

---

#### Option 8

**Type:** `error`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **code** | `string` | ✅ | Error code |
| **message** | `string` | ✅ | Error message |
| **details** | `any` | optional | Additional error details |

---

#### Option 9

**Type:** `ping`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |

---

#### Option 10

**Type:** `pong`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **messageId** | `string` | ✅ | Unique message identifier |
| **type** | `string` | ✅ |  |
| **timestamp** | `string` | ✅ | ISO 8601 datetime when message was sent |
| **pingMessageId** | `string` | optional | ID of ping message being responded to |

---


---

## WebSocketMessageType

### Allowed Values

* `subscribe`
* `unsubscribe`
* `event`
* `ping`
* `pong`
* `ack`
* `error`
* `presence`
* `cursor`
* `edit`


---

## WebSocketPresenceStatus

### Allowed Values

* `online`
* `away`
* `busy`
* `offline`


---

## WebSocketServerConfig

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **enabled** | `boolean` | ✅ | Enable WebSocket server |
| **path** | `string` | ✅ | WebSocket endpoint path |
| **heartbeatInterval** | `number` | ✅ | Heartbeat interval in milliseconds |
| **reconnectAttempts** | `number` | ✅ | Maximum reconnection attempts for clients |
| **presence** | `boolean` | ✅ | Enable presence tracking |
| **cursorSharing** | `boolean` | ✅ | Enable collaborative cursor sharing |


---

