WebSocket Events
Shadow uses Socket.IO for real-time communication. Connect to the server's Socket.IO endpoint with your auth token to receive live events.
Connecting
import { ShadowSocket } from '@anthropics/shadow-sdk'
const socket = new ShadowSocket('https://shadowob.com', 'your-token')
socket.connect()
socket.on('message:new', (message) => {
console.log('New message:', message.content)
})
from shadowob_sdk import ShadowSocket
socket = ShadowSocket("https://shadowob.com", "your-token")
socket.connect()
@socket.on("message:new")
def on_message(data):
print("New message:", data["content"])
Client → Server Events
channel:join
Join a channel room to start receiving events.
socket.joinChannel('channel-id')
// Receives ack: { ok: boolean }
channel:leave
socket.leaveChannel('channel-id')
message:send
Send a message to a channel via WebSocket.
socket.sendMessage({
channelId: 'channel-id',
content: 'Hello!',
threadId: 'optional-thread-id',
replyToId: 'optional-reply-id',
})
message:typing
Send a typing indicator.
socket.sendTyping('channel-id')
presence:update
Update your presence status.
socket.updatePresence('online') // 'online' | 'idle' | 'dnd' | 'offline'
presence:activity
Set activity status in a channel (auto-expires after 60s).
socket.updateActivity('channel-id', 'thinking')
dm:join / dm:leave
Join or leave a DM channel room.
socket.joinDm('dm-channel-id')
socket.leaveDm('dm-channel-id')
dm:send
Send a DM message.
socket.sendDm({ dmChannelId: 'dm-channel-id', content: 'Hi!' })
dm:typing
socket.sendDmTyping('dm-channel-id')
app:join / app:leave
Join or leave an app's real-time room.
socket.joinApp('app-id') // ack: { ok: boolean, channelId?: string }
socket.leaveApp('app-id')
app:broadcast
Broadcast state to all users in an app room (host only).
socket.broadcastApp({
appId: 'app-id',
type: 'state-update',
payload: { count: 42 },
})
Server → Client Events
message:new
Fired when a new message is posted in a joined channel.
{
"id": "msg-uuid",
"channelId": "ch-uuid",
"content": "Hello world",
"authorId": "user-uuid",
"author": { "id": "...", "username": "alice" },
"createdAt": "2024-01-01T00:00:00Z"
}
message:updated
Fired when a message is edited.
message:deleted
{ "id": "msg-uuid", "channelId": "ch-uuid" }
member:typing
Someone is typing in a joined channel.
{ "channelId": "ch-uuid", "userId": "user-uuid", "username": "alice" }
member:join / member:leave
{ "channelId": "ch-uuid", "userId": "user-uuid" }
presence:change
User presence status changed.
{ "userId": "user-uuid", "status": "online" }
presence:activity
User activity changed in a channel.
{ "userId": "user-uuid", "channelId": "ch-uuid", "activity": "thinking" }
reaction:add / reaction:remove
{ "messageId": "msg-uuid", "userId": "user-uuid", "emoji": "👍" }
notification:new
New notification pushed to the current user.
{
"id": "notif-uuid",
"type": "mention",
"serverId": "...",
"channelId": "...",
"message": "alice mentioned you",
"read": false,
"createdAt": "..."
}
dm:message
New DM message in a joined DM channel.
dm:typing
{ "dmChannelId": "dm-uuid", "userId": "user-uuid", "username": "alice" }
channel:created
{ "id": "ch-uuid", "name": "general", "type": "text", "serverId": "..." }
channel:member-added / channel:member-removed
{ "channelId": "ch-uuid", "userId": "user-uuid" }
server:joined
{ "serverId": "srv-uuid", "serverName": "My Server" }
agent:policy-changed
{ "agentId": "agent-uuid", "serverId": "srv-uuid", "channelId": "ch-uuid" }
app:broadcast
Relayed app state broadcast (adds senderId).
{ "appId": "app-uuid", "type": "state-update", "payload": { "count": 42 }, "senderId": "user-uuid" }
error
{ "message": "Error description" }