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.5

Published

TypeScript SDK for SubscribeFlow API - Email subscription management

Readme

@subscribeflow/sdk

Official TypeScript SDK for the SubscribeFlow API.

Installation

Von GitHub (Empfohlen)

# npm
npm install git+https://github.com/talent-factory/subscribe-flow.git#subdirectory=sdk/typescript

# yarn
yarn add git+https://github.com/talent-factory/subscribe-flow.git#subdirectory=sdk/typescript

# bun
bun add github:talent-factory/subscribe-flow#subdirectory=sdk/typescript

In package.json:

{
  "dependencies": {
    "@subscribeflow/sdk": "git+https://github.com/talent-factory/subscribe-flow.git#subdirectory=sdk/typescript"
  }
}

Lokale Entwicklung

Für parallele Entwicklung von SDK und Anwendung gibt es mehrere Optionen:

Option 1: file: Protokoll (Einfachste)

# npm/yarn/pnpm
npm install /pfad/zu/subscribeflow/sdk/typescript

# bun
bun add /pfad/zu/subscribeflow/sdk/typescript

In package.json:

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

Option 2: npm link / bun link (Symlink)

# Im SDK-Verzeichnis
cd /pfad/zu/subscribeflow/sdk/typescript
npm link  # oder: bun link

# In deinem Projekt
cd /pfad/zu/deinem/projekt
npm link @subscribeflow/sdk  # oder: bun link @subscribeflow/sdk

Vorteil: Änderungen am SDK sind sofort verfügbar ohne Neuinstallation.

Option 3: Workspace (Monorepo)

Für Projekte im selben Repository:

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

Best Practice für lokale Entwicklung

  1. Während der Entwicklung: npm link oder file: verwenden
  2. Vor dem Commit: Auf GitHub-URL umstellen
  3. CI/CD: GitHub-URL nutzen

Quick Start

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
const subscriber = await client.subscribers.create({
  email: '[email protected]',
  tags: ['newsletter', 'product-updates'],
  metadata: { source: 'website' },
});

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

Usage

Subscribers

// List subscribers
const { items, total, cursor } = await client.subscribers.list({
  limit: 50,
  status: 'active',
});

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

// Update a subscriber
const updated = await client.subscribers.update('subscriber-id', {
  metadata: { plan: 'premium' },
});

// Delete a subscriber
await client.subscribers.delete('subscriber-id');

Tags

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

// List tags
const { items } = await client.tags.list();

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

// Delete a tag
await client.tags.delete('tag-id');

Templates

// Create an email template
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
const { items } = await client.templates.list({ category: 'transactional' });

// Get a template by slug
const tmpl = await client.templates.getBySlug('welcome-email');

// Preview a template
const preview = await client.templates.preview('template-id', {
  company: 'Acme Inc',
});
console.log(preview.html);

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

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

Email Send

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

Campaigns

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

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

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

// Send the campaign
const sendResult = await client.campaigns.send('campaign-id');

// Cancel a running campaign
await client.campaigns.cancel('campaign-id');

Email Triggers

// Create an event-based trigger
const trigger = await client.triggers.create({
  event_type: 'subscriber.created',
  template_id: 'welcome-template-uuid',
  description: 'Send welcome email on signup',
});

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

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

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

Webhooks

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

// The signing secret is only returned on creation
console.log('Signing secret:', webhook.signing_secret);

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

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

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

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

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

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

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

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

Preference Center

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

// Access the preference center with the token
const prefCenter = client.preferenceCenter(tokenResponse.token);

// Get subscriber preferences and available tags
const info = await prefCenter.getInfo();

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

// Export all data (DSGVO)
const exportData = await prefCenter.exportData();

// Delete account (DSGVO)
await prefCenter.deleteAccount();

Error Handling

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);
    console.error('Type:', error.type);
    console.error('Detail:', error.detail);
  }
}

Configuration

const client = new SubscribeFlowClient({
  // Required: Your API key
  apiKey: 'sf_live_xxx',

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

Lokale API-Instanz

Für Entwicklung gegen eine lokale SubscribeFlow-Instanz:

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.

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

// Use component schemas
type Subscriber = components['schemas']['SubscriberResponse'];
type Tag = components['schemas']['TagResponse'];

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

Regenerating Types

If the API changes, you can regenerate the TypeScript types:

# 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

Links

License

MIT