Node.js SDK

The official camelmailer package is TypeScript-first, has zero runtime dependencies, and returns a { data, error } result on every call so nothing throws for a rejected request.

Install

terminal
npm install camelmailer

Requires Node.js 18+ (native fetch). Ships both ESM and CommonJS.

Quickstart

mailer.ts
import { CamelMailer } from 'camelmailer';

const camelmailer = new CamelMailer('cm_xxxx'); // or set CAMELMAILER_API_KEY

const { data, error } = await camelmailer.emails.send({
  from: 'billing@acme.com',
  to: 'ada@example.com',
  subject: 'Your receipt',
  html_body: '<p>Thanks for your purchase.</p>',
});

if (error) throw new Error(error.code + ': ' + error.message);
console.log('Queued', data.message_id);

Send with a template

Render a stored template against a template_model. Variables use Mustache-style {{ name }} syntax.

template.ts
const { data, error } = await camelmailer.emails.sendWithTemplate({
  from: 'hello@acme.com',
  to: 'ada@example.com',
  template: 'welcome',
  template_model: { name: 'Ada', product: 'Acme' },
});

Error handling

Nothing throws for request failures. error is a CamelMailerError with a stable code, the API message and an HTTP statusCode. Network failures use the code NetworkError.

errors.ts
const { data, error } = await camelmailer.emails.send({ /* … */ });

if (error) {
  switch (error.code) {
    case 'ValidationError':
      // fix the payload, do not retry
      break;
    case 'Unauthorized':
      // rotate/check the API key
      break;
    case 'NetworkError':
      // instance unreachable — retry with backoff
      break;
    default:
      console.error(error.code, error.message);
  }
  return;
}

Self-hosted instances

The client defaults to https://app.camelmailer.com. Point it at your own instance with the baseUrl option (or the CAMELMAILER_BASE_URL environment variable):

self-hosted.ts
const camelmailer = new CamelMailer('cm_xxxx', {
  baseUrl: 'https://mail.example.com',
});
Call CamelMailer from server code only (API routes, server actions) so the credential never reaches the browser. Full field reference: Messages API.

GitHub repository · npm package