@sendmailos/sdk 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +353 -4
- package/dist/index.d.mts +860 -6
- package/dist/index.d.ts +860 -6
- package/dist/index.js +685 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +685 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,6 +33,8 @@ await client.emails.send({
|
|
|
33
33
|
|
|
34
34
|
- **Type-safe**: Full TypeScript support with exported types
|
|
35
35
|
- **Lightweight**: Zero dependencies for core SDK
|
|
36
|
+
- **Industry Templates**: 50+ pre-built templates for different industries
|
|
37
|
+
- **Agency Workspaces**: Manage multiple clients from one account
|
|
36
38
|
- **Pixel Tracking**: Track website visitors and link to email campaigns
|
|
37
39
|
- **React Components**: Pre-built components and hooks
|
|
38
40
|
- **Webhook Verification**: Secure signature verification utilities
|
|
@@ -43,7 +45,7 @@ await client.emails.send({
|
|
|
43
45
|
### Emails
|
|
44
46
|
|
|
45
47
|
```typescript
|
|
46
|
-
// Send transactional email
|
|
48
|
+
// Send transactional email (Single Brand)
|
|
47
49
|
await client.emails.send({
|
|
48
50
|
to: 'user@example.com',
|
|
49
51
|
subject: 'Hello!',
|
|
@@ -52,6 +54,16 @@ await client.emails.send({
|
|
|
52
54
|
fromEmail: 'hello@acme.com',
|
|
53
55
|
});
|
|
54
56
|
|
|
57
|
+
// Send email (Multi-Brand / SaaS Platform)
|
|
58
|
+
// Workspace auto-detected from fromEmail domain - no extra params needed!
|
|
59
|
+
await platform.emails.send({
|
|
60
|
+
to: 'customer@example.com',
|
|
61
|
+
subject: 'Your order is ready!',
|
|
62
|
+
html: '<h1>Order Ready!</h1>',
|
|
63
|
+
fromName: 'Pizza Palace',
|
|
64
|
+
fromEmail: 'orders@pizzapalace.com', // ← Workspace auto-detected
|
|
65
|
+
});
|
|
66
|
+
|
|
55
67
|
// Send with template
|
|
56
68
|
await client.emails.sendTemplate({
|
|
57
69
|
to: 'user@example.com',
|
|
@@ -63,24 +75,38 @@ await client.emails.sendTemplate({
|
|
|
63
75
|
### Subscribers
|
|
64
76
|
|
|
65
77
|
```typescript
|
|
66
|
-
// Create subscriber
|
|
78
|
+
// Create subscriber (Single Brand)
|
|
67
79
|
const { subscriber } = await client.subscribers.create({
|
|
68
80
|
email: 'user@example.com',
|
|
69
81
|
firstName: 'John',
|
|
70
82
|
tags: ['newsletter', 'premium']
|
|
71
83
|
});
|
|
72
84
|
|
|
85
|
+
// Create subscriber (Multi-Brand / SaaS Platform)
|
|
86
|
+
const { subscriber } = await platform.subscribers.create({
|
|
87
|
+
email: 'customer@example.com',
|
|
88
|
+
firstName: 'Jane',
|
|
89
|
+
domain: 'pizzapalace.com', // Required for multi-brand
|
|
90
|
+
tags: ['loyalty-member']
|
|
91
|
+
});
|
|
92
|
+
|
|
73
93
|
// List subscribers
|
|
74
94
|
const { subscribers, total } = await client.subscribers.list({
|
|
75
95
|
limit: 50,
|
|
76
96
|
offset: 0
|
|
77
97
|
});
|
|
98
|
+
|
|
99
|
+
// List subscribers for a specific client (Multi-Brand)
|
|
100
|
+
const { subscribers } = await platform.subscribers.list({
|
|
101
|
+
domain: 'pizzapalace.com',
|
|
102
|
+
limit: 50
|
|
103
|
+
});
|
|
78
104
|
```
|
|
79
105
|
|
|
80
106
|
### Campaigns
|
|
81
107
|
|
|
82
108
|
```typescript
|
|
83
|
-
// Send campaign
|
|
109
|
+
// Send campaign (Single Brand)
|
|
84
110
|
await client.campaigns.send({
|
|
85
111
|
name: 'Weekly Newsletter',
|
|
86
112
|
subject: 'What\'s new this week',
|
|
@@ -89,17 +115,340 @@ await client.campaigns.send({
|
|
|
89
115
|
html: '<h1>Hello {{first_name}}!</h1>',
|
|
90
116
|
tags: ['newsletter'] // Filter by subscriber tags
|
|
91
117
|
});
|
|
118
|
+
|
|
119
|
+
// Send campaign (Multi-Brand / SaaS Platform)
|
|
120
|
+
// Workspace auto-detected from fromEmail domain
|
|
121
|
+
await platform.campaigns.send({
|
|
122
|
+
name: 'Pizza Promo',
|
|
123
|
+
subject: 'New menu items!',
|
|
124
|
+
fromName: 'Pizza Palace',
|
|
125
|
+
fromEmail: 'promo@pizzapalace.com', // ← Workspace auto-detected
|
|
126
|
+
html: '<h1>Check out our new items!</h1>',
|
|
127
|
+
sourceDomains: ['pizzapalace.com'] // Only send to subscribers from this domain
|
|
128
|
+
});
|
|
92
129
|
```
|
|
93
130
|
|
|
94
131
|
### Domains
|
|
95
132
|
|
|
96
133
|
```typescript
|
|
97
|
-
// Add sending domain
|
|
134
|
+
// Add sending domain (Single Brand)
|
|
98
135
|
const { domain } = await client.domains.create({
|
|
99
136
|
domain: 'yourcompany.com'
|
|
100
137
|
});
|
|
101
138
|
|
|
102
139
|
console.log('DNS Records to add:', domain.dnsRecords);
|
|
140
|
+
|
|
141
|
+
// Add client domain (Multi-Brand / SaaS Platform)
|
|
142
|
+
// Show these DNS records to your client in your UI
|
|
143
|
+
const { dns_records, domain_id } = await platform.domains.create({
|
|
144
|
+
domain: 'pizzapalace.com'
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// After client verifies DNS:
|
|
148
|
+
// ✓ Domain status becomes "verified"
|
|
149
|
+
// ✓ Workspace is AUTO-CREATED for this domain
|
|
150
|
+
// ✓ You can now send emails from @pizzapalace.com
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Organization & Industries
|
|
154
|
+
|
|
155
|
+
Set your industry during onboarding to get pre-built templates and workflows.
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import { SendMailOS, INDUSTRIES } from '@sendmailos/sdk';
|
|
159
|
+
|
|
160
|
+
const client = new SendMailOS('sk_live_...');
|
|
161
|
+
|
|
162
|
+
// Get current organization
|
|
163
|
+
const org = await client.organization.get();
|
|
164
|
+
|
|
165
|
+
// Set industries (multi-select)
|
|
166
|
+
await client.organization.setIndustries(['ecommerce', 'saas']);
|
|
167
|
+
|
|
168
|
+
// Convert to agency account (enables workspaces)
|
|
169
|
+
await client.organization.convertToAgency();
|
|
170
|
+
|
|
171
|
+
// Available industries (50+)
|
|
172
|
+
console.log(INDUSTRIES);
|
|
173
|
+
// { hotels: 'Hotels & Hospitality', restaurants: 'Restaurants & Food Service', ... }
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Supported Industries
|
|
177
|
+
|
|
178
|
+
Hotels, Restaurants, Gyms, Travel Agencies, Real Estate, Schools, E-commerce, Dentists, Car Dealerships, Events, Beauty Salons, Law Firms, Non-Profits, SaaS, Recruitment, Insurance, Online Courses, Municipalities, Personal Trainers, Influencers, Doctors/Clinics, Nightclubs, Coworking, Wedding Planners, Art Galleries, Car Rentals, Podcasters, Consultants, Bakeries, Veterinarians, Airbnb Hosts, Accountants, Developers, Musicians, Spas, Bookstores, Cleaning Services, Churches, Graphic Designers, Coffee Shops, Florists, Political Campaigns, Libraries, Taxis/Limos, Home Inspectors, Photographers, Universities, Fashion, Nutritionists, Startups
|
|
179
|
+
|
|
180
|
+
## Account Types
|
|
181
|
+
|
|
182
|
+
### Single Brand (Business)
|
|
183
|
+
|
|
184
|
+
For companies sending emails from their own domain. Simple setup, no workspaces needed.
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const client = new SendMailOS('sk_live_your_api_key');
|
|
188
|
+
|
|
189
|
+
await client.emails.send({
|
|
190
|
+
to: 'customer@example.com',
|
|
191
|
+
fromEmail: 'hello@yourcompany.com',
|
|
192
|
+
subject: 'Welcome!',
|
|
193
|
+
html: '<h1>Hello!</h1>'
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Multi-Brand / SaaS Platform
|
|
198
|
+
|
|
199
|
+
For agencies or SaaS platforms managing multiple clients. Each client gets their own workspace with isolated data.
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// Your platform's master API key
|
|
203
|
+
const platform = new SendMailOS('sk_live_platform_key');
|
|
204
|
+
|
|
205
|
+
// 1. Client signs up → Register their domain
|
|
206
|
+
const { dns_records } = await platform.domains.create({
|
|
207
|
+
domain: 'pizzapalace.com'
|
|
208
|
+
});
|
|
209
|
+
// Show dns_records to client in your UI
|
|
210
|
+
|
|
211
|
+
// 2. Domain verified → Workspace auto-created!
|
|
212
|
+
// (No manual workspace creation needed)
|
|
213
|
+
|
|
214
|
+
// 3. Send emails → Workspace auto-detected from fromEmail
|
|
215
|
+
await platform.emails.send({
|
|
216
|
+
to: 'customer@example.com',
|
|
217
|
+
fromEmail: 'orders@pizzapalace.com', // ← Workspace detected automatically!
|
|
218
|
+
fromName: 'Pizza Palace',
|
|
219
|
+
subject: 'Your order is ready!',
|
|
220
|
+
html: '<h1>Order Ready!</h1>'
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// 4. Add subscribers → Use domain param
|
|
224
|
+
await platform.subscribers.create({
|
|
225
|
+
email: 'customer@example.com',
|
|
226
|
+
domain: 'pizzapalace.com' // Required for multi-brand
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// 5. List subscribers for a specific client
|
|
230
|
+
const { subscribers } = await platform.subscribers.list({
|
|
231
|
+
domain: 'pizzapalace.com'
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// 6. Send campaign → Workspace auto-detected
|
|
235
|
+
await platform.campaigns.send({
|
|
236
|
+
subject: 'New Menu Items!',
|
|
237
|
+
fromName: 'Pizza Palace',
|
|
238
|
+
fromEmail: 'promo@pizzapalace.com', // ← Auto-detected
|
|
239
|
+
html: '<h1>Check out our new menu!</h1>'
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### How Workspace Detection Works
|
|
244
|
+
|
|
245
|
+
| Action | How workspace is identified |
|
|
246
|
+
|--------|----------------------------|
|
|
247
|
+
| Register domain | Creates domain record (pending) |
|
|
248
|
+
| Domain verified | **Workspace auto-created** |
|
|
249
|
+
| Send email | Auto-detect from `fromEmail` domain |
|
|
250
|
+
| Send campaign | Auto-detect from `fromEmail` domain |
|
|
251
|
+
| Add subscriber | From `domain` parameter |
|
|
252
|
+
| List subscribers | From `domain` parameter |
|
|
253
|
+
|
|
254
|
+
**One verified domain = One workspace.** Simple.
|
|
255
|
+
|
|
256
|
+
## Agency Workspaces (Advanced)
|
|
257
|
+
|
|
258
|
+
For more control, you can manually manage workspaces:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Convert to agency account first
|
|
262
|
+
await client.organization.convertToAgency();
|
|
263
|
+
|
|
264
|
+
// Create client workspaces manually
|
|
265
|
+
const pizzaPlace = await client.workspaces.create({
|
|
266
|
+
name: 'Pizza Palace',
|
|
267
|
+
industry: 'restaurants',
|
|
268
|
+
import_templates: true // Auto-import restaurant templates
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// List all clients
|
|
272
|
+
const { workspaces } = await client.workspaces.list();
|
|
273
|
+
for (const ws of workspaces) {
|
|
274
|
+
console.log(`${ws.name}: ${ws.stats?.subscribers} subscribers`);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Get detailed stats
|
|
278
|
+
const details = await client.workspaces.get(pizzaPlace.id);
|
|
279
|
+
console.log(details.stats);
|
|
280
|
+
// { total_subscribers: 1200, active_subscribers: 1150, total_campaigns: 24, ... }
|
|
281
|
+
|
|
282
|
+
// Invite client to view reports
|
|
283
|
+
await client.workspaces.inviteClient(pizzaPlace.id, 'owner@pizzapalace.com');
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Workflows
|
|
287
|
+
|
|
288
|
+
Automate email sequences with workflows. Create them via API, build the steps in your UI, then trigger them programmatically.
|
|
289
|
+
|
|
290
|
+
### Workflow Lifecycle
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
1. Create workflow (draft)
|
|
294
|
+
2. Add nodes & edges (build the flow)
|
|
295
|
+
3. Activate workflow (start accepting triggers)
|
|
296
|
+
4. Trigger for subscribers (via API or events)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Create & Manage Workflows
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
// Create a workflow for a client (Multi-Brand)
|
|
303
|
+
const { data } = await platform.workflows.create({
|
|
304
|
+
name: 'Welcome Sequence',
|
|
305
|
+
domain: 'pizzapalace.com', // Auto-detect workspace
|
|
306
|
+
trigger: { type: 'api' } // Triggered via API
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const workflowId = data.workflow.id;
|
|
310
|
+
|
|
311
|
+
// List workflows
|
|
312
|
+
const { data: list } = await platform.workflows.list({ domain: 'pizzapalace.com' });
|
|
313
|
+
|
|
314
|
+
// Get workflow with nodes/edges
|
|
315
|
+
const { data: workflow } = await platform.workflows.get(workflowId);
|
|
316
|
+
|
|
317
|
+
// Delete workflow
|
|
318
|
+
await platform.workflows.delete(workflowId);
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Build Workflow Steps
|
|
322
|
+
|
|
323
|
+
Update a workflow with nodes (steps) and edges (connections):
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
await platform.workflows.update(workflowId, {
|
|
327
|
+
nodes: [
|
|
328
|
+
{
|
|
329
|
+
id: 'trigger-1',
|
|
330
|
+
type: 'trigger',
|
|
331
|
+
data: { triggerType: 'api' }
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
id: 'email-1',
|
|
335
|
+
type: 'email',
|
|
336
|
+
data: {
|
|
337
|
+
subject: 'Welcome to {{restaurantName}}!',
|
|
338
|
+
templateId: 'tmpl_welcome'
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
id: 'delay-1',
|
|
343
|
+
type: 'delay',
|
|
344
|
+
data: { duration: 3, unit: 'days' }
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
id: 'email-2',
|
|
348
|
+
type: 'email',
|
|
349
|
+
data: {
|
|
350
|
+
subject: 'Your first order discount',
|
|
351
|
+
templateId: 'tmpl_promo'
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
],
|
|
355
|
+
edges: [
|
|
356
|
+
{ id: 'e1', source: 'trigger-1', target: 'email-1' },
|
|
357
|
+
{ id: 'e2', source: 'email-1', target: 'delay-1' },
|
|
358
|
+
{ id: 'e3', source: 'delay-1', target: 'email-2' }
|
|
359
|
+
]
|
|
360
|
+
});
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Node Types
|
|
364
|
+
|
|
365
|
+
| Type | Description | Data Fields |
|
|
366
|
+
|------|-------------|-------------|
|
|
367
|
+
| `trigger` | Entry point | `triggerType` |
|
|
368
|
+
| `email` | Send email | `subject`, `templateId`, `fromName`, `fromEmail` |
|
|
369
|
+
| `delay` | Wait period | `duration`, `unit` (minutes/hours/days) |
|
|
370
|
+
| `condition` | Branch logic | `field`, `operator`, `value` |
|
|
371
|
+
| `tag` | Add/remove tags | `action` (add/remove), `tags` |
|
|
372
|
+
| `http` | Call webhook | `url`, `method`, `headers`, `body` |
|
|
373
|
+
| `wait_for_event` | Wait for event | `eventName`, `timeout` |
|
|
374
|
+
| `unsubscribe` | Unsubscribe user | - |
|
|
375
|
+
| `exit` | End workflow | - |
|
|
376
|
+
|
|
377
|
+
### Activate & Pause
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
// Activate workflow (start accepting triggers)
|
|
381
|
+
await platform.workflows.activate(workflowId);
|
|
382
|
+
|
|
383
|
+
// Pause workflow (stop new triggers, existing runs continue)
|
|
384
|
+
await platform.workflows.pause(workflowId);
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Trigger Workflows
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
// When a customer signs up at the restaurant
|
|
391
|
+
await platform.workflows.trigger(workflowId, {
|
|
392
|
+
email: 'customer@example.com',
|
|
393
|
+
data: {
|
|
394
|
+
firstName: 'John',
|
|
395
|
+
restaurantName: 'Pizza Palace',
|
|
396
|
+
signupSource: 'website'
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Wait for Events
|
|
402
|
+
|
|
403
|
+
Workflows can pause and wait for specific events:
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
// Workflow has a "wait_for_event: purchase_completed" node
|
|
407
|
+
// When customer makes a purchase, send the event:
|
|
408
|
+
await platform.workflows.sendEvent({
|
|
409
|
+
event: 'purchase_completed',
|
|
410
|
+
email: 'customer@example.com',
|
|
411
|
+
data: { orderTotal: 45.99 }
|
|
412
|
+
});
|
|
413
|
+
// The workflow resumes from where it was waiting
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Example: Restaurant Welcome Flow
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
// 1. Create workflow
|
|
420
|
+
const { data } = await platform.workflows.create({
|
|
421
|
+
name: 'New Customer Welcome',
|
|
422
|
+
domain: 'pizzapalace.com'
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// 2. Build the flow
|
|
426
|
+
await platform.workflows.update(data.workflow.id, {
|
|
427
|
+
nodes: [
|
|
428
|
+
{ id: '1', type: 'trigger', data: { triggerType: 'api' } },
|
|
429
|
+
{ id: '2', type: 'email', data: { subject: 'Welcome!', templateId: 'tmpl_welcome' } },
|
|
430
|
+
{ id: '3', type: 'delay', data: { duration: 2, unit: 'days' } },
|
|
431
|
+
{ id: '4', type: 'condition', data: { field: 'has_ordered', operator: 'eq', value: true } },
|
|
432
|
+
{ id: '5', type: 'email', data: { subject: 'Thanks for ordering!', templateId: 'tmpl_thanks' } },
|
|
433
|
+
{ id: '6', type: 'email', data: { subject: '10% off your first order', templateId: 'tmpl_promo' } }
|
|
434
|
+
],
|
|
435
|
+
edges: [
|
|
436
|
+
{ id: 'e1', source: '1', target: '2' },
|
|
437
|
+
{ id: 'e2', source: '2', target: '3' },
|
|
438
|
+
{ id: 'e3', source: '3', target: '4' },
|
|
439
|
+
{ id: 'e4', source: '4', target: '5', sourceHandle: 'yes' },
|
|
440
|
+
{ id: 'e5', source: '4', target: '6', sourceHandle: 'no' }
|
|
441
|
+
]
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// 3. Activate
|
|
445
|
+
await platform.workflows.activate(data.workflow.id);
|
|
446
|
+
|
|
447
|
+
// 4. Trigger when new customer signs up
|
|
448
|
+
await platform.workflows.trigger(data.workflow.id, {
|
|
449
|
+
email: 'newcustomer@gmail.com',
|
|
450
|
+
data: { firstName: 'Jane', restaurantName: 'Pizza Palace' }
|
|
451
|
+
});
|
|
103
452
|
```
|
|
104
453
|
|
|
105
454
|
## Pixel Tracking
|