From a server

Blackevin.Rest in Node, Bun, Deno or an edge runtime — the token endpoint, publishing without a socket, history and presence.

Blackevin.Rest is the client for code that should not hold a socket: a request handler, a job, a cron, an inbound webhook. It is a separate class from Realtime rather than a mode of it, because half of a realtime client has no meaning without a connection.

Publish and read

import * as Blackevin from '@blackevin/client';

const rest = new Blackevin.Rest({ key: process.env.BLACKEVIN_KEY });

await rest.channels.get('orders:new').publish('order.created', { id: 7 });

A job, a cron or an inbound webhook publishes over HTTP with no connection to keep open. The same client reads back:

const channel = rest.channels.get('orders:new');

const messages = await channel.history({ limit: 50 });
const members = await channel.presence.get();

See the REST overview for what each call needs.

The token endpoint

The one route almost every app adds. Your server signs a short-lived, scoped token request, so the browser never holds the key:

server.ts
app.get('/api/blackevin-token', async (req, res) => {
  const user = await currentUser(req);

  res.json(
    await rest.auth.createTokenRequest({
      clientId: String(user.id),
      ttl: 3_600_000,
      capability: {
        [`chat:team-${user.teamId}`]: ['subscribe', 'publish'],
      },
    })
  );
});

Signing is local — no call to Blackevin — and uses WebCrypto rather than node:crypto, so the same code runs on an edge runtime. Authentication walks through the whole flow.

A token for the server itself

Usually a browser exchanges the token request. A server that wants to act as one client, inside a narrow capability, can do the exchange itself:

const details = await rest.auth.requestToken(
  await rest.auth.createTokenRequest({
    clientId: 'worker-1',
    capability: { 'jobs:*': ['publish'] },
  })
);

const worker = new Blackevin.Rest({ token: details.token });

A token wins over a key when both are given, so a client acting as one user never silently acts as the whole account.

On this page