SmallPlate

Pub/Sub API

Real-time message fan-out with Server-Sent Events and WebSockets

WARNING: pubsub API is currently broken! The docs are also incorrect.

Pub/Sub provides real-time message fan-out. Publishers send messages to a channel, and subscribers receive them over Server-Sent Events or WebSockets.

Endpoints

MethodEndpointDescription
POST/{plateId}/pubsub/{channel}/publishPublish a message
GET/{plateId}/pubsub/{channel}/subscribeSubscribe with SSE
GET/{plateId}/pubsub/{channel}/wsSubscribe with WebSocket
GET/{plateId}/pubsub/{channel}/clientGenerate a temporary client WebSocket path
POST/{plateId}/publish/{channel}Legacy publish alias
GET/{plateId}/subscribe/{channel}Legacy SSE alias
GET/{plateId}/ws/subscribe/{channel}Legacy WebSocket alias

Publish Simple Message

const plateId = "[id]";
const apiKey = "your-api-key";
const baseUrl = "[base-url]";

const response = await fetch(`${baseUrl}/${plateId}/pubsub/alerts/publish`, {
  method: "POST",
  headers: {
    "Authorization": apiKey,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    message: "Server restarted"
  })
});

const data = await response.json();
console.log(data);

Publish Structured Object

const plateId = "[id]";
const apiKey = "your-api-key";
const baseUrl = "[base-url]";

const response = await fetch(`${baseUrl}/${plateId}/pubsub/user:123:events/publish`, {
  method: "POST",
  headers: {
    "Authorization": apiKey,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    message: {
      type: "login",
      userId: "123",
      timestamp: "2026-03-15T12:00:00Z"
    }
  })
});

const data = await response.json();
console.log(data);

Subscribe with Server-Sent Events

const plateId = "[id]";
const apiKey = "your-api-key";
const baseUrl = "[base-url]";

const eventSource = new EventSource(`${baseUrl}/${plateId}/pubsub/alerts/subscribe`, {
  headers: {
    "Authorization": apiKey
  }
});

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log("Received:", data);
};

eventSource.onerror = (error) => {
  console.error("Connection closed", error);
  eventSource.close();
};

Subscribe with Pattern (SSE)

const plateId = "[id]";
const apiKey = "your-api-key";
const baseUrl = "[base-url]";

const eventSource = new EventSource(
  `${baseUrl}/${plateId}/pubsub/user:*/subscribe?pattern=true`,
  {
    headers: {
      "Authorization": apiKey
    }
  }
);

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log("Received:", data);
};

Subscribe with WebSocket

const plateId = "[id]";
const apiKey = "your-api-key";
const baseUrl = "[base-url]".replace("http", "ws");

const ws = new WebSocket(`${baseUrl}/${plateId}/pubsub/alerts/ws`);

ws.onopen = () => {
  ws.send(JSON.stringify({ auth: apiKey }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log("Received:", data);
};

ws.onerror = (error) => {
  console.error("WebSocket error:", error);
};

ws.onclose = () => {
  console.log("WebSocket closed");
};

Generate Client WebSocket Path

Use this endpoint when you want to generate a temporary socket path for clients without exposing your API key.

GET /{plateId}/pubsub/{channel}/client

Query Parameters

NameTypeDefaultDescription
patternbooleanfalseUse pattern subscription mode (same behavior as SSE/WS subscribe routes)
max_durinteger (ms)0Max connection duration in milliseconds (0 = unlimited)
expiry or ttlinteger (ms)300000Max time allowed before the client connects (0 to 600000)
max_usesinteger1Number of allowed successful WebSocket connections (0 = unlimited)

The response returns a relative path value. Append it to your base URL (with ws:// or wss://) to connect.

const plateId = "[id]";
const apiKey = "your-api-key";
const baseHttpUrl = "[base-url]";

const createResp = await fetch(
  `${baseHttpUrl}/${plateId}/pubsub/alerts/client?max_dur=60000&expiry=300000&max_uses=1`,
  {
    method: "GET",
    headers: {
      "Authorization": apiKey
    }
  }
);

const createData = await createResp.json();
const wsBase = baseHttpUrl.replace(/^http/, "ws");
const ws = new WebSocket(`${wsBase}${createData.data.path}`);

ws.onmessage = (event) => {
  console.log("Received:", JSON.parse(event.data));
};

Notes

  • Published payloads are JSON-encoded.
  • Subscription payloads decode JSON when possible and fall back to plain strings.
  • Client socket connect route (/{plateId}/s/{token}) can return: invalid_client_socket (unknown token), expired_client_socket (token TTL elapsed), and exhausted_client_socket (max uses reached).
  • Legacy publish/subscribe routes are still supported.

On this page