Skip to main content

Realtime

Overview

The realtime system exposes a lightweight HTTP/WebSocket:

  • A WebSocket endpoint for authenticated clients: ws://event.centia.io/
  • Accepts a JWT token and (for sub‑users) a list of relations they need events from.
  • Broadcasts batched event notifications to all connected clients that match relations they listen to.
  • A simple health endpoint: /pingpong.

Authentication and connection

The WebSocket endpoint is:

  • wss://event.centia.io?token=...&rel=...

Query parameters:

  • token (required): A Centia.io JWT.
  • rel (optional): Comma‑separated list of relations the client wants events from (e.g., rockhall.inductees,rockhall.stars).

Connection flow:

  1. Server validates the token in a worker.
  2. If sub-user, server enforces per‑relation access for each entry in rel. Unauthorized relations result in an error message and socket close.
  3. On success, the client is registered.

Errors are returned as JSON and the socket is closed. Examples:

  • Missing token: { "type": "error", "error": "missing_token", "message": "Missing token" }
  • Invalid token: { "type": "error", "error": "invalid_token", "message": "..." }
  • Unauthorized rel: { "type": "error", "error": "not_allowed", "message": "Not allowed to access this resource: <rel>" }

Receiving database change events

To enable database change events, set emit_events to true in the table schema:

PATCH https://api.centia.io/api/v4/schemas/my_schema/tables/my_table
Content-Type: application/json
Authorization: Bearer <token>

{
"emit_events": true
}

Events are batched and delivered to all connected clients subscribed to the table.

Batching defaults:

  • 10 notifications or
  • 2 seconds (whichever comes first),
  • checked every 1 second.

When a batch is flushed, a message is sent to the clients:

{
"type": "batch",
"db": "my_database",
"batch": {
"my_database": {
"my_schema.my_table": {
"INSERT": [["key","value"]],
"UPDATE": [["key","value"]],
"DELETE": [["key","value"]],
"full_data": [ { "col1": "val", "col2": 123 } ]
},
"another_schema.table": {}
}
}
}

Important:

  • The server broadcasts to all clients connected to that database, without further per‑table filtering at send time. If you need additional client‑side filtering, filter messages on the client.

Client examples

JavaScript (browser):

<script>
const token = "<your-jwt>";
const rel = "public.parcels,public.addresses"; // required for sub-users
const ws = new WebSocket(`ws://localhost:8088/broadcast?token=${encodeURIComponent(token)}&rel=${encodeURIComponent(rel)}`);

ws.onopen = () => {
console.log("connected");
ws.send("SELECT NOW() AS ts");
};

ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === 'batch') {
console.log("DB batch:", msg.batch);
} else {
console.log("SQL result:", msg);
}
};

ws.onclose = () => console.log("closed");
ws.onerror = (err) => console.error("ws error", err);
</script>

Node (ws):

import WebSocket from 'ws';
const token = process.env.CENTIA_TOKEN;
const ws = new WebSocket(`ws://localhost:8088/broadcast?token=${encodeURIComponent(token)}`);
ws.on('open', () => ws.send('SELECT 42 AS answer'));
ws.on('message', (data) => console.log(JSON.parse(data.toString())));