Realtime WebSocket
Moontraze RealTime lets your app receive live updates whenever documents are created, updated, or deleted — no polling needed.
Perfect for:
- Chat apps (new messages appear instantly)
- Notifications
- Live dashboards
- Collaborative editing
1. Endpoint
wss://api.moontraze.com/ws?projectId=<PROJECT_ID>&token=<USER_JWT>Replace with your own values:
| Placeholder | Where to find it |
|---|---|
<PROJECT_ID> | Dashboard → Project Settings → API Keys → Project ID |
<USER_JWT> | A valid user JWT returned by your login endpoint (e.g. /api/auth or your own auth flow) |
Both
projectIdandtokenare required. Missing either → connection closed with code1008.
💡 Tip: Moontraze Cloud host is
api.moontraze.com. Just plug in yourprojectIdandtoken.
2. Connect
JavaScript / Node
const API_HOST = 'api.moontraze.com';
const PROJECT_ID = 'your_project_id';
const JWT = 'user_jwt_token';
const ws = new WebSocket(
`wss://${API_HOST}/ws?projectId=${PROJECT_ID}&token=${JWT}`
);
ws.onopen = () => console.log('connected');
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
console.log('event:', msg);
};
ws.onclose = () => console.log('disconnected');Dart / Flutter
import 'package:web_socket_channel/web_socket_channel.dart';
final apiHost = 'api.moontraze.com'; // ← your host
final projectId = 'your_project_id'; // ← your projectid
final jwt = 'user_jwt_token'; // ← login
final uri = Uri.parse(
'wss://$apiHost/ws?projectId=$projectId&token=$jwt'
);
final channel = WebSocketChannel.connect(uri);
await channel.ready;
channel.stream.listen((raw) {
final msg = jsonDecode(raw);
print('event: $msg');
});3. Subscribe to a Path
After connecting, subscribe to any database path:
{ "action": "subscribe", "path": "chats/uid1_uid2" }Server responds:
{ "type": "subscribed", "path": "chats/uid1_uid2" }Path patterns
| Pattern | Matches |
|---|---|
chats/uid1_uid2 | Exact document/collection |
chats/uid1_uid2/** | That path and everything under it |
chats/* | One level under chats/ |
users/{uid}/messages | Template — {uid} matches any single segment |
* or ** | Everything (use with caution) |
4. Receive Events
When someone writes to your DB via /api/db (POST/PUT/DELETE), matching subscribers receive:
{
"type": "created",
"path": "chats/uid1_uid2/msg_123",
"data": {
"path": "chats/uid1_uid2/msg_123",
"docId": "msg_123",
"data": { "fromUid": "uid1", "text": "hello", "...": "..." }
},
"ts": 1737052800000
}Event types
type | Fired when |
|---|---|
created | POST /api/db succeeded |
updated | PUT /api/db succeeded |
deleted | DELETE /api/db on a document |
field_deleted | DELETE /api/db?field=... |
collection_deleted | Whole collection deleted |
5. Unsubscribe
{ "action": "unsubscribe", "path": "chats/uid1_uid2" }6. Keepalive
- Server sends a ping every 30 seconds
- Client must pong automatically (browsers do this natively)
- Client can also send:
{ "action": "ping" }Server responds with:
{ "type": "pong", "ts": 1737052800000 }7. Complete Example — Live Chat
// ─── Config ───
const API_HOST = 'api.moontraze.com'; // ← host
const PROJECT_ID = 'your_project_id'; // ← dashboard
const JWT = 'user_jwt_token'; // ← login
// 1. Connect
const ws = new WebSocket(
`wss://${API_HOST}/ws?projectId=${PROJECT_ID}&token=${JWT}`
);
// 2. Subscribe on connect
ws.onopen = () => {
ws.send(JSON.stringify({
action: 'subscribe',
path: 'chats/**'
}));
};
// 3. Handle events
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'created' && msg.path.startsWith('chats/')) {
appendMessageToUI(msg.data.data);
}
};
// 4. Cleanup
window.addEventListener('beforeunload', () => ws.close());8. Rules & Security
- Subscriptions are per-project scoped — you only receive events from your project.
- JWT is verified on connect — expired token → connection closed.
- Rules engine is NOT applied to WebSocket events. If you need per-field authorization, filter on the client.
9. Limits
| Limit | Value |
|---|---|
| Max connections per project | Soft limit — 1000 (contact us) |
| Max subscriptions per client | 100 |
| Ping interval | 30 s |
| Auto-disconnect on dead client | 30–60 s |
10. Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
close 1008: projectId and token required | Missing query params | Add ?projectId=...&token=... |
close 1008: Invalid token | JWT expired or wrong secret | Login again, get fresh JWT |
| Connected but no events | Subscribed to wrong path | Use chats/** to test |
| Events fire but UI doesn't update | Payload shape mismatch | Check msg.data.data vs msg.data |