@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 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