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

@subscribeflow/sdk

v1.0.33

Published

TypeScript SDK for SubscribeFlow API - Email subscription management

Downloads

523

Readme

@subscribeflow/sdk

Official TypeScript SDK for SubscribeFlow — full type safety, tree-shakeable, zero dependencies. Manage email subscriptions, campaigns, and GDPR-compliant preference centers.

npm Version npm Downloads Node Version License Works with Claude

Dashboard | Documentation | API Reference | MCP Integration


Installation

From npm (Recommended)

Install the SDK using your preferred package manager:

# npm
npm install @subscribeflow/sdk

# yarn
yarn add @subscribeflow/sdk

# bun
bun add @subscribeflow/sdk

Or add it directly to your package.json:

{
  "dependencies": {
    "@subscribeflow/sdk": "^1.0.0"
  }
}

Local Development

If you are developing the SDK alongside your application, you can link it locally instead of installing from the registry.

Option 1: file: Protocol (Simplest)

Point your dependency directly at the local SDK directory:

# npm/yarn/pnpm
npm install /path/to/subscribeflow/sdk/typescript

# bun
bun add /path/to/subscribeflow/sdk/typescript

In package.json:

{
  "dependencies": {
    "@subscribeflow/sdk": "file:../subscribeflow/sdk/typescript"
  }
}

Option 2: npm link / bun link (Symlink)

Create a global symlink so changes to the SDK are reflected immediately without reinstalling:

# In the SDK directory
cd /path/to/subscribeflow/sdk/typescript
npm link  # or: bun link

# In your project
cd /path/to/your/project
npm link @subscribeflow/sdk  # or: bun link @subscribeflow/sdk

Advantage: Any change you make to the SDK source is immediately available in your project without reinstalling.

Option 3: Workspace (Monorepo)

For projects within the same repository, use workspaces:

// package.json (root)
{
  "workspaces": ["apps/*", "sdk/*"]
}

Best Practices for Local Development

  1. During development: Use npm link or file: for fast iteration
  2. Before committing: Switch back to the npm registry version
  3. CI/CD: Always use the npm registry

Quick Start

The following example shows how to initialize the client and create your first subscriber. You need an API key, which you can generate from your SubscribeFlow admin dashboard.

import { SubscribeFlowClient } from '@subscribeflow/sdk';

const client = new SubscribeFlowClient({
  apiKey: process.env.SUBSCRIBEFLOW_API_KEY!,
  baseUrl: 'https://api.subscribeflow.net', // optional, this is the default
});

// Create a subscriber with tags and metadata
const subscriber = await client.subscribers.create({
  email: '[email protected]',
  tags: ['newsletter', 'product-updates'],
  metadata: { source: 'website' },
});

console.log('Created subscriber:', subscriber.id);

Usage

Subscribers

Subscribers are the core entity in SubscribeFlow. Each subscriber represents a person identified by their email address. You can list, create, update, and delete subscribers, as well as manage their tag subscriptions and metadata.

// List subscribers with optional filters
// Returns paginated results with items, total count, and cursor for pagination
const { items, total, cursor } = await client.subscribers.list({
  limit: 50,
  status: 'active',
});

// Get a single subscriber by ID
const subscriber = await client.subscribers.get('subscriber-id');

// Update subscriber metadata
// Only the fields you pass will be changed; everything else stays the same
const updated = await client.subscribers.update('subscriber-id', {
  metadata: { plan: 'premium' },
});

// Permanently delete a subscriber and all associated data
await client.subscribers.delete('subscriber-id');

Tags

Tags represent topics or categories that subscribers can opt into. They are the building block of SubscribeFlow's granular preference management. Unlike traditional mailing lists, subscribers can actively discover and subscribe to tags they are interested in.

// Create a new tag with a human-readable name and a URL-safe slug
const tag = await client.tags.create({
  name: 'Product Updates',
  slug: 'product-updates',
  description: 'Get notified about new features and improvements',
});

// List all tags in your organization
const { items } = await client.tags.list();

// Update a tag's description or other properties
await client.tags.update('tag-id', {
  description: 'Updated description',
});

// Delete a tag (subscribers will be automatically unsubscribed)
await client.tags.delete('tag-id');

Templates

Templates define the content and layout of your emails. SubscribeFlow uses MJML for responsive email rendering and supports Mustache-style variables for dynamic content.

// Create a new email template with MJML content
// Variables like {{company}} will be replaced when sending
const template = await client.templates.create({
  name: 'Welcome Email',
  subject: 'Welcome to {{company}}!',
  mjml_content: '<mjml><mj-body>...</mj-body></mjml>',
  category: 'transactional',
});

// List templates, optionally filtered by category
const { items } = await client.templates.list({ category: 'transactional' });

// Look up a template by its slug (useful for send operations)
const tmpl = await client.templates.getBySlug('welcome-email');

// Preview how a template will look with specific variable values
const preview = await client.templates.preview('template-id', {
  company: 'Acme Inc',
});
console.log(preview.html);

// Update a template's subject or content
await client.templates.update('template-id', { subject: 'New Subject' });

// Delete a template
await client.templates.delete('template-id');

Email Send

Send individual transactional emails using a template. Each send requires a template slug and recipient. The optional idempotency_key prevents duplicate sends if the same request is retried.

// Send a transactional email to a single recipient
const result = await client.emails.send({
  template_slug: 'welcome-email',
  to: '[email protected]',
  variables: { company: 'Acme Inc' },
  idempotency_key: 'unique-key-123', // prevents duplicate sends on retry
});
console.log('Email queued:', result.id);

Campaigns

Campaigns let you send emails to groups of subscribers based on tag filters. Create a draft, preview the recipient count, and then send it. Running campaigns can be cancelled.

// Create a campaign draft targeting subscribers with specific tags
const campaign = await client.campaigns.create({
  name: 'February Newsletter',
  template_id: 'template-uuid',
  tag_filter: { include_tags: ['newsletter'], match: 'any' },
});

// List campaigns filtered by status
const campaigns = await client.campaigns.list({ status: 'draft' });

// Preview how many subscribers will receive this campaign
const count = await client.campaigns.countRecipients('campaign-id');
console.log(`Will send to ${count.count} subscribers`);

// Send the campaign (moves from draft to sending)
const sendResult = await client.campaigns.send('campaign-id');

// Cancel a running campaign (emails already sent cannot be recalled)
await client.campaigns.cancel('campaign-id');

Email Triggers

Triggers automatically send emails in response to events. For example, you can send a welcome email whenever a new subscriber is created. Triggers can be activated or deactivated without deleting them.

// Create a trigger that fires when a subscriber is created
const trigger = await client.triggers.create({
  event_type: 'subscriber.created',
  template_id: 'welcome-template-uuid',
  description: 'Send welcome email on signup',
});

// List all triggers
const triggers = await client.triggers.list();

// Deactivate a trigger without deleting it
await client.triggers.update('trigger-id', { is_active: false });

// Permanently delete a trigger
await client.triggers.delete('trigger-id');

Webhooks

Webhooks let your application receive real-time notifications when events occur in SubscribeFlow. Each webhook endpoint receives signed HTTP POST requests that you can verify using the signing secret.

// Register a new webhook endpoint for specific event types
const webhook = await client.webhooks.create({
  url: 'https://your-app.com/webhooks/subscribeflow',
  events: ['subscriber.created', 'tag.subscribed'],
  description: 'Main webhook endpoint',
});

// Important: the signing secret is only returned on creation — store it securely
console.log('Signing secret:', webhook.signing_secret);

// List all registered webhook endpoints
const { items } = await client.webhooks.list();

// Update the events a webhook listens to
await client.webhooks.update('webhook-id', {
  events: ['subscriber.created', 'subscriber.deleted'],
});

// Test a webhook by sending a sample payload to your endpoint
const result = await client.webhooks.test('webhook-id', 'subscriber.created');
if (result.success) {
  console.log('Webhook is working!');
}

// Rotate the signing secret (invalidates the old one immediately)
const rotated = await client.webhooks.rotateSecret('webhook-id');
console.log('New secret:', rotated.signing_secret);

// View delivery history to debug failed deliveries
const deliveries = await client.webhooks.listDeliveries('webhook-id');

// Get aggregate delivery statistics
const stats = await client.webhooks.getDeliveryStats('webhook-id');
console.log(`Success rate: ${stats.success_rate}%`);

// Retry a specific failed delivery
await client.webhooks.retryDelivery('webhook-id', 'delivery-id');

// Remove a webhook endpoint
await client.webhooks.delete('webhook-id');

Preference Center

The Preference Center allows subscribers to manage their own email preferences. Generate a secure token for a subscriber, then use it to access their preferences. This powers the self-service UI where subscribers can subscribe to new tags, unsubscribe, export their data, or delete their account (GDPR compliance).

// Generate a time-limited preference center token for a subscriber
const tokenResponse = await client.subscribers.generatePreferenceToken('subscriber-id');

// Create a preference center client using the token
const prefCenter = client.preferenceCenter(tokenResponse.token);

// Retrieve the subscriber's current preferences and all available tags
const info = await prefCenter.getInfo();

// Subscribe or unsubscribe from individual tags
await prefCenter.subscribeTag('tag-id');
await prefCenter.unsubscribeTag('tag-id');

// Export all subscriber data as JSON (GDPR Art. 20 — Right to Data Portability)
const exportData = await prefCenter.exportData();

// Permanently delete the subscriber account (GDPR Art. 17 — Right to Erasure)
await prefCenter.deleteAccount();

Error Handling

All API errors are thrown as SubscribeFlowError instances with structured error details. You can use instanceof checks to handle specific error types.

import { SubscribeFlowClient, SubscribeFlowError } from '@subscribeflow/sdk';

try {
  await client.subscribers.get('non-existent-id');
} catch (error) {
  if (error instanceof SubscribeFlowError) {
    console.error('API Error:', error.message);
    console.error('Status:', error.status);   // HTTP status code (e.g. 404)
    console.error('Type:', error.type);       // Machine-readable error type
    console.error('Detail:', error.detail);   // Human-readable description
  }
}

Configuration

The client accepts configuration options when initialized. Only the apiKey is required.

const client = new SubscribeFlowClient({
  // Required: Your API key (starts with sf_live_ or sf_test_)
  apiKey: 'sf_live_xxx',

  // Optional: API base URL (default: https://api.subscribeflow.net)
  baseUrl: 'https://api.subscribeflow.net',
});

Local API Instance

When developing against a local SubscribeFlow backend, point the client to your local server:

const client = new SubscribeFlowClient({
  apiKey: 'sf_dev_xxx',
  baseUrl: 'http://localhost:8000',
});

TypeScript Support

This SDK is written in TypeScript and provides full type definitions out of the box. You can import component schemas directly for use in your own type declarations.

import type { paths, components } from '@subscribeflow/sdk';

// Use component schemas for your own types
type Subscriber = components['schemas']['SubscriberResponse'];
type Tag = components['schemas']['TagResponse'];

// All API operations are fully type-safe
const subscriber: Subscriber = await client.subscribers.get('id');

Regenerating Types

If the API changes, you can regenerate the TypeScript types from the OpenAPI schema:

# Make sure the backend is running
make backend

# Fetch OpenAPI schema and generate types
curl http://localhost:8000/openapi.json -o openapi.json
bunx openapi-typescript openapi.json -o src/api-types.ts

MCP Server (Claude Integration)

The MCP server for Claude Desktop and Claude Code is available via the Python SDK. Install subscribeflow[mcp] to use natural-language commands with your SubscribeFlow account.

See the MCP Integration Guide for setup instructions.

Links

License

MIT