Install

Install @blackevin/client, get a key, and point the SDK at the right node.

Install the SDK

npm install @blackevin/client
pnpm add @blackevin/client

One package, browser and Node both. Its only dependency is @blackevin/protocol, which is the wire format and has none of its own.

Get a key

Keys are created in the console at app.blackevin.com. A key looks like this:

ck_live_7BZ882hK4pQm1x.k1
└──────── secret ────────┘ └id┘

The part after the last dot is the key id; everything before it is the secret. See API keys for why it is shaped that way and what each half does.

A key is your whole account. Keep it on your server — a browser gets a token instead, and there is a recipe for minting one in Authentication.

Point the SDK somewhere

There is nothing to configure for the hosted service:

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

const realtime = new Blackevin.Realtime({ key: process.env.BLACKEVIN_KEY });

endpoint is for when you need something else — a self-hosted node, a local dev node, a staging environment. It resolves in this order:

  1. the endpoint option
  2. BLACKEVIN_ENDPOINT, where an environment exists (Node, Bun, Deno)
  3. wss://ws.blackevin.com

restEndpoint follows the same order with BLACKEVIN_REST_ENDPOINT, with one difference: an explicitly-given endpoint implies it. A dev or self-hosted node serves the socket and the API from one origin, so ws://127.0.0.1:3000 yields http://127.0.0.1:3000. Only the default falls through to https://api.blackevin.com, because in production those are two separate services and swapping the scheme would send REST calls to a host that serves none.

In a browser

Step 2 needs an actual environment, so it covers Node, Bun and Deno. A browser bundle has none at runtime. A web app that wants to point somewhere else per build reads its own env and passes the result:

new Blackevin.Realtime({
  endpoint: import.meta.env.VITE_BLACKEVIN_WS,
  authUrl: '/api/blackevin-token',
});

An unset variable is undefined, which falls through to the default — so the same code works in production without a branch.

What is exported

exportwhat it is
Blackevin.Realtimethe WebSocket client — channels, presence, connection state
Blackevin.Restthe HTTP client — publish, history, presence, token requests
Blackevin.BlackevinErrorthe error type carrying statusCode and a stable reason slug

Blackevin.Blackevin is an alias of Realtime, kept for symmetry with the package name. Everything exported is public API.

Next

Publish and subscribe — the shortest thing that works.

On this page