ReachBellDocs

Server SDK (Node.js)

@reachbell/node is the server-side companion to the browser SDK. Use it from your backend to send transactional messages, track events, and manage subscribers — without writing raw HTTP calls. It's the recommended way to do anything server-side; the Server API is the underlying REST layer for endpoints the SDK doesn't wrap yet.

Requires Node 18+ (uses the built-in fetch).

Install

npm install @reachbell/node

Initialize

import { ReachBell } from '@reachbell/node';
 
const rb = new ReachBell({ apiKey: process.env.REACHBELL_API_KEY! });

Keep your API key server-side only — never ship it to the browser. (The browser uses the public key via @reachbell/sdk.)

Transactional push

Send a push to one user, identified by externalId (set via the browser SDK's identify()) or by raw token:

const r = await rb.transactional.send({
  externalId: 'user_42',
  title: 'Order shipped 📦',
  body: 'Your order arrives tomorrow.',
  url: 'https://shop.example/orders/4821',
});
 
// A 200 with delivered:false just means the user has no active subscription —
// it's a normal outcome, not an error.
if (!r.delivered) console.warn('no active subscription');

Pass a templateId (plus variables) instead of title/body to send from a saved template.

Transactional email

await rb.transactional.email({
  to: 'user@example.com',
  subject: 'Your verification code',
  htmlContent: '<p>Your code is <b>123456</b></p>',
});

senderEmail / replyTo must be on your verified sending domain.

Transactional SMS & WhatsApp

await rb.transactional.sms({ externalId: 'user_42', text: 'Your code is 123456' });
 
await rb.transactional.whatsapp({
  externalId: 'user_42',
  template: { name: 'order_update', params: ['#4821', 'shipped'] },
});

WhatsApp business-initiated messages need a pre-approved template (outside WhatsApp's 24-hour customer-service window); inside it you can send free-form text. Both channels must be configured for your project first — see SMS and WhatsApp.

Track events

Events can trigger automations:

await rb.events.track({ name: 'order_paid', externalId: 'user_42', properties: { amount: 4999 } });
await rb.events.trackBatch([ /* up to 25 events */ ]);

Subscribers

await rb.subscribers.identify({ token, externalId: 'user_42' }); // link a subscription to your user id
await rb.subscribers.delete(token);                              // remove a subscriber

Errors

Non-2xx responses and network/timeout failures throw a ReachBellError with .status (0 for network errors) and .body:

import { ReachBell, ReachBellError } from '@reachbell/node';
 
try {
  await rb.transactional.send({ externalId: 'u', title: 't', body: 'b' });
} catch (e) {
  if (e instanceof ReachBellError) console.error(e.status, e.body);
}

Escape hatch

For any endpoint not yet wrapped by a helper:

await rb.request('POST', '/some/endpoint', { any: 'payload' });