npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

simplysend

v6.0.0

Published

Official Node.js SDK for Simply Send - Send transactional and marketing emails

Readme

Features

  • Strict Separation of Concerns: Exposes three dedicated client classes for Transactional API, Marketing API, and Web Setup API.
  • Lightweight & Dependency-free: Uses native fetch (requires Node.js 22+). No heavy dependencies.
  • Dual module support: Pre-built ESM (ES Modules) and CJS (CommonJS) formats.
  • Strongly Typed: Full TypeScript support with detailed interfaces.
  • Smart Attachments: Pass raw Node.js Buffer objects, and the SDK will automatically base64-encode them for you.

Installation

npm install simplysend

What's New in v6

v6 aligns the Web Setup SDK with the current WAPI contract and adds typed helpers for domain features.

  • Create domains with POST.
  • Partially update domain groups, contacts, subscription groups, templates, compliance templates, and webhooks with PATCH.
  • Configure and verify click tracking and inbound email with client.domains helpers.

Migrating from v5

This is a breaking WAPI change. Upgrade the SDK and deploy the corresponding Web Setup API changes together:

npm install simplysend@^6.0.0

If you call WAPI directly rather than through this SDK, update the following request methods:

| Operation | v5 and earlier | v6 | | --- | --- | --- | | Create domain | PUT /web-setup/domains | POST /web-setup/domains | | Update a domain group | PUT | PATCH | | Update a contact | PUT | PATCH | | Update a subscription group or subscription | PUT | PATCH | | Update a template, compliance template, or webhook | PUT | PATCH |

The existing SDK method names are unchanged. Update the package version; the SDK sends the correct v6 method automatically.

await client.domains.configureClickTracking(domainId, true);
await client.domains.verifyClickTracking(domainId);

await client.domains.configureInboundEmail(domainId, {
  enabled: true,
  inboxSubdomain: 'inbound',
});
await client.domains.verifyInboundEmail(domainId);

Client Initialization

To connect to SimplySend, you will initialize the specialized client class corresponding to the API features you need. Each constructor requires your Account ID and the respective API Key (retrieved from the Settings page in your SimplySend Dashboard).

1. SimplySendTransactionalClient

Used to send transactional emails (OTPs, receipts, alerts).

import { SimplySendTransactionalClient } from 'simplysend';

const client = new SimplySendTransactionalClient({
  accountId: 'ss_acc_123456',
  apiKey: 'ss_api_key_abcdef'
});

2. SimplySendMarketingClient

Used to send newsletters or marketing campaigns.

import { SimplySendMarketingClient } from 'simplysend';

const client = new SimplySendMarketingClient({
  accountId: 'ss_acc_123456',
  apiKey: 'ss_api_key_abcdef'
});

3. SimplySendWebSetupClient

Used for resource management (domains, templates, subscribers, webhooks).

import { SimplySendWebSetupClient } from 'simplysend';

const client = new SimplySendWebSetupClient({
  accountId: 'ss_acc_123456',
  apiKey: 'ss_api_key_abcdef'
});

Usage Examples

1. Send a Transactional Email

import { SimplySendTransactionalClient, SendTransactionalEmailResponse } from 'simplysend';

const client = new SimplySendTransactionalClient({
  accountId: 'ss_acc_123',
  apiKey: 'ss_api_key_abc'
});

try {
  const response: SendTransactionalEmailResponse = await client.email.send({
    from: 'Acme Welcome Team <[email protected]>', // Verified domain email with display name
    to: '[email protected]',                     // Valid email or "Display Name <[email protected]>"
    cc: '[email protected]',                      // Optional: CC recipient(s)
    bcc: '[email protected]',                       // Optional: BCC recipient(s)
    // Note: BCC is mutually exclusive with TO and CC. Use either TO/CC or BCC, not both.
    subject: 'Welcome!',                            // UTF-8 text, max 998 chars per line
    html: '<h1>Hello, World!</h1><p>Thank you for signing up.</p>', // Combined attachments: max 2MB
    text: 'Hello, World! Thank you for signing up.', // Optional: Plain text version for accessibility
    replyTo: '[email protected]',      // Optional: "Display Name <[email protected]>" or "[email protected]>"
    enableClickTracking: true,                      // Optional: Boolean for link tracking
    enableOpenTracking: true,                       // Optional: Boolean for open tracking
    attachments: [
      {
        name: 'invoice.pdf',                        // File name with extension
        contentType: 'application/pdf',             // MIME type (PDF, PNG, JPG, CSV, DOCX)
        content: Buffer.from('PDF content here...'), // Automatically encoded to base64 by SDK
      }
    ]
  });

  console.log('Transactional email sent. Message ID:', response.data?.messageId);
} catch (error) {
  console.error('Failed to send email:', error.message);
}

2. Send a Marketing Email

import { SimplySendMarketingClient, SendMarketingEmailResponse } from 'simplysend';

const client = new SimplySendMarketingClient({
  accountId: 'ss_acc_123',
  apiKey: 'ss_api_key_xyz'
});

try {
  const response: SendMarketingEmailResponse = await client.email.send({
    from: '[email protected]',
    to: '[email protected]',
    // Note: BCC and CC are not supported for marketing emails. Use the "to" field only.
    subject: 'June Newsletter',
    html: '<h1>Our monthly updates</h1><p>Here is what is new...</p>{{company_address_html}}{{unsubscribe_email_html}}',
    subscriptionGroupId: 'sub_group_123', // Required
    campaignId: 'camp_abc_456',           // Optional campaign tracking
    enableClickTracking: true,
    enableOpenTracking: true,
  });

  console.log('Marketing email sent. Message ID:', response.data?.messageId);
} catch (error) {
  console.error('Failed to send marketing email:', error.message);
}

3. Manage Web Setup Resources (Domains, Contacts, Subscription Groups, Subscribers)

import { SimplySendWebSetupClient } from 'simplysend';

const client = new SimplySendWebSetupClient({
  accountId: 'ss_acc_123',
  apiKey: 'ss_api_key_789'
});

// 1. Add a domain to verify
const newDomain = await client.domains.create({
  domain: 'mycompany.com',
  useCaseId: 'tx-us-east-1'
});
console.log('Verification records:', newDomain.dnsRecords);
// Publish those records, then verify the domain. If the apex already has an SPF
// TXT from Google Workspace, Microsoft 365, or another provider, merge Simply Send
// into that record — do not add a second v=spf1 TXT.
// https://simplysend.email/docs/guide/domain-verification/spf
// https://simplysend.email/blog/setup-spf-record

// Optional domain features are configured through the Web Setup API:
// PATCH /web-setup/domains/{domainId}/features/click-tracking
// PATCH /web-setup/domains/{domainId}/features/inbound-email
// POST  /web-setup/domains/{domainId}/features/{feature}/verify
// Each operation has its own API reference page. See:
// https://simplysend.email/docs/api/domains/click-tracking/configure
// https://simplysend.email/docs/api/domains/click-tracking/verify
// https://simplysend.email/docs/api/domains/inbound-email/configure
// https://simplysend.email/docs/api/domains/inbound-email/verify

// Update a domain group:
// PATCH /web-setup/domain-groups/{groupId}
// https://simplysend.email/docs/api/domain-groups/update

// 2. Create a Contact profile globally in the Contacts Directory
// Note: Contacts must exist globally before they can be subscribed to groups.
const contactResponse = await client.contacts.createContact({
  email: '[email protected]',
  firstName: 'Alice',
  lastName: 'Smith',
  phone: '+1234567890',
  globalStatus: 'active',
  consentMethod: 'single_opt_in',
  consentDetails: 'User checked physical agreement box during customer onboarding'
});
console.log('Contact created:', contactResponse.data.contact);

// 3. Create a Subscription Group (audience list)
const groupResponse = await client.contacts.createSubscriberGroup({
  name: 'Newsletter List',
  description: 'Monthly updates newsletter list'
});
const subscriptionGroupId = groupResponse.data.group.subscriptionGroupId!;
console.log('Group created:', groupResponse.data.group);

// 4. Subscribe the contact to the group list
const subscriptionResponse = await client.contacts.addSubscriber(subscriptionGroupId, {
  email: '[email protected]',
  isActive: true,
  consentMethod: 'single_opt_in',
  consentDetails: 'Footer newsletter subscription form'
});
console.log('Subscribed to group:', subscriptionResponse.data.subscriber);

// 5. Register a Webhook to subscribe to inbound email received events
const newWebhook = await client.webhooks.create({
  url: 'https://your-server.com/webhooks/simply-send',
  events: ['email_received'],
  description: 'Webhook to receive inbound support emails'
});
console.log('Webhook created successfully with ID:', newWebhook.webhookId);

Client Configurations

When initializing, each client class expects exactly the same configuration properties:

| Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | accountId | string | Yes | Your unique SimplySend Account ID, found on the Account page of the SimplySend website. | | apiKey | string | Yes | The SimplySend API Key for authentication, found on the API Keys page of the SimplySend website. |


Error Handling

The SDK exposes descriptive error classes to help you debug integration issues:

import { SimplySendTransactionalClient, SimplySendHttpError, SimplySendValidationError } from 'simplysend';

try {
  // 1. Instantiation validation (throws locally)
  const client = new SimplySendTransactionalClient({
    accountId: '', // Throws validation error locally
    apiKey: 'ss_api_key_...'
  });

  // 2. Request parameter validation (throws locally)
  await client.email.send({
    from: '[email protected]',
    to: '', // Throws validation error locally
    subject: 'Hello',
    html: '...'
  });
} catch (error) {
  if (error instanceof SimplySendValidationError) {
    // Local validation failed (field check did not hit the network)
    console.error('Validation failed on field:', error.field); // e.g. "accountId", "to"
    console.error('Message:', error.message);
  } else if (error instanceof SimplySendHttpError) {
    // API server responded with a non-2xx status code
    console.error('HTTP Status:', error.statusCode); // e.g. 403, 400
    console.error('Error Code:', error.reasonCode); // e.g. "ACCOUNT_SUSPENDED"
    console.error('Message:', error.message);
  } else {
    // Generic connection/network failure
    console.error('Network/Request Error:', error.message);
  }
}

BCC Usage

The SDK supports BCC (Blind Carbon Copy) for transactional emails. BCC recipients are hidden from other recipients.

BCC-only Send

To send a BCC-only email (no visible TO or CC recipients), provide only the bcc field:

const response = await client.email.send({
  from: '[email protected]',
  bcc: '[email protected]',
  subject: 'Subject',
  html: '<p>Email content</p>'
});

BCC with TO/CC

The SDK enforces that BCC is mutually exclusive with TO and CC. You cannot use BCC together with TO or CC - the SDK will throw a validation error:

// This will throw a SimplySendValidationError
await client.email.send({
  from: '[email protected]',
  to: '[email protected]',
  bcc: '[email protected]',  // ❌ Error: BCC cannot be used with TO
  subject: 'Subject',
  html: '<p>Email content</p>'
});

Multiple BCC Recipients

You can pass an array of BCC recipients:

const response = await client.email.send({
  from: '[email protected]',
  bcc: ['[email protected]', '[email protected]'],
  subject: 'Subject',
  html: '<p>Email content</p>'
});

Marketing Email Limitations

Marketing emails have different requirements than transactional emails for compliance reasons:

No BCC or CC Support

Marketing emails do not support BCC or CC recipients. This is because:

  • BCC addresses cannot be tracked for unsubscribes
  • Consent verification requires visible recipient information
  • RFC 8058 compliance requires clear unsubscribe mechanisms

Always use the to field for marketing emails:

// ✅ Correct - Marketing email with TO only
await marketingClient.email.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Newsletter',
  html: '<p>Content</p>',
  subscriptionGroupId: 'group_123'
});

// ❌ Error - BCC not supported for marketing emails
await marketingClient.email.send({
  from: '[email protected]',
  bcc: '[email protected]',  // Will throw validation error
  subject: 'Newsletter',
  html: '<p>Content</p>',
  subscriptionGroupId: 'group_123'
});

Domain authentication

Before sending, publish the DNS records returned by domains.create and verify the domain in the dashboard. A domain may have only one SPF TXT record. If Google Workspace, Microsoft 365, or another provider already published SPF, merge Simply Send into that record — do not add a second v=spf1 line.

License

MIT