Building a Realtime Dashboard with Apinator

Learn how to build a live analytics dashboard that updates in real time using Apinator WebSockets, with less than 20 lines of client code.

Modern dashboards need live data. Users expect metrics to update without hitting refresh. In this post we'll walk through building a realtime dashboard with Apinator — from publishing events on the server to rendering live charts in the browser.

Why WebSockets for dashboards?

Polling works, but it's wasteful. Every client hammers your API on a fixed interval regardless of whether data has changed. WebSockets flip the model: the server pushes only when there's something new.

With Apinator, a dashboard update is a single HTTP call on the server side, and a lightweight WebSocket subscription on the client.

Setting up the server

Install the Node.js server SDK:

npm install @apinator/server

Create a client and publish events whenever your metrics change:

import { ApinatorServer } from '@apinator/server';

const apinator = new ApinatorServer({
  appId: process.env.APINATOR_APP_ID,
  apiKey: process.env.APINATOR_API_KEY,
  apiSecret: process.env.APINATOR_API_SECRET,
});

// Call this whenever a metric changes
await apinator.publish('dashboard', 'metric-updated', {
  key: 'active_users',
  value: 1247,
  delta: +12,
});

That's it on the server. No persistent connections to manage.

Subscribing on the client

Install the JS client SDK:

npm install @apinator/sdk

Connect and listen for updates:

import { RealtimeClient } from '@apinator/sdk';

const client = new RealtimeClient({ appKey: 'your-app-key' });
const channel = client.subscribe('dashboard');

channel.bind('metric-updated', (data) => {
  updateChart(data.key, data.value);
});

The updateChart function does whatever your UI framework requires — set state, mutate a store, call a chart library method. Apinator handles the delivery.

Presence for "who's viewing"

Want to show how many people are viewing the dashboard right now? Switch to a presence channel:

const channel = client.subscribe('presence-dashboard', {
  auth: { endpoint: '/auth/channel' },
  userInfo: { name: currentUser.name },
});

channel.bind('realtime:member_added', (member) => {
  addViewer(member);
});

The backend counts members automatically. No additional infrastructure needed.

Wrapping up

You now have a dashboard that:

  • Pushes metric updates the moment they happen
  • Shows live viewer counts with presence channels
  • Requires no polling infrastructure

The full example code is available in the documentation.