@subscribeflow/sdk
v1.0.5
Published
TypeScript SDK for SubscribeFlow API - Email subscription management
Maintainers
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/typescriptIn 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/typescriptIn 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/sdkVorteil: Ä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
- Während der Entwicklung:
npm linkoderfile:verwenden - Vor dem Commit: Auf GitHub-URL umstellen
- 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.tsLinks
License
MIT
