@sendmailos/sdk 1.2.0 → 1.2.2
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 +356 -14
- package/dist/index.d.mts +648 -7
- package/dist/index.d.ts +648 -7
- package/dist/index.js +452 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +452 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,11 +33,12 @@ 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
|
+
- **Email Automation**: Build workflows with triggers, delays, conditions, and actions
|
|
36
37
|
- **Industry Templates**: 50+ pre-built templates for different industries
|
|
37
38
|
- **Agency Workspaces**: Manage multiple clients from one account
|
|
38
39
|
- **Pixel Tracking**: Track website visitors and link to email campaigns
|
|
40
|
+
- **Webhooks**: Real-time event notifications with signature verification
|
|
39
41
|
- **React Components**: Pre-built components and hooks
|
|
40
|
-
- **Webhook Verification**: Secure signature verification utilities
|
|
41
42
|
- **Error Handling**: Custom error classes for different scenarios
|
|
42
43
|
|
|
43
44
|
## API Reference
|
|
@@ -45,7 +46,7 @@ await client.emails.send({
|
|
|
45
46
|
### Emails
|
|
46
47
|
|
|
47
48
|
```typescript
|
|
48
|
-
// Send transactional email
|
|
49
|
+
// Send transactional email (Single Brand)
|
|
49
50
|
await client.emails.send({
|
|
50
51
|
to: 'user@example.com',
|
|
51
52
|
subject: 'Hello!',
|
|
@@ -54,6 +55,16 @@ await client.emails.send({
|
|
|
54
55
|
fromEmail: 'hello@acme.com',
|
|
55
56
|
});
|
|
56
57
|
|
|
58
|
+
// Send email (Multi-Brand / SaaS Platform)
|
|
59
|
+
// Workspace auto-detected from fromEmail domain - no extra params needed!
|
|
60
|
+
await platform.emails.send({
|
|
61
|
+
to: 'customer@example.com',
|
|
62
|
+
subject: 'Your order is ready!',
|
|
63
|
+
html: '<h1>Order Ready!</h1>',
|
|
64
|
+
fromName: 'Pizza Palace',
|
|
65
|
+
fromEmail: 'orders@pizzapalace.com', // ← Workspace auto-detected
|
|
66
|
+
});
|
|
67
|
+
|
|
57
68
|
// Send with template
|
|
58
69
|
await client.emails.sendTemplate({
|
|
59
70
|
to: 'user@example.com',
|
|
@@ -65,24 +76,38 @@ await client.emails.sendTemplate({
|
|
|
65
76
|
### Subscribers
|
|
66
77
|
|
|
67
78
|
```typescript
|
|
68
|
-
// Create subscriber
|
|
79
|
+
// Create subscriber (Single Brand)
|
|
69
80
|
const { subscriber } = await client.subscribers.create({
|
|
70
81
|
email: 'user@example.com',
|
|
71
82
|
firstName: 'John',
|
|
72
83
|
tags: ['newsletter', 'premium']
|
|
73
84
|
});
|
|
74
85
|
|
|
86
|
+
// Create subscriber (Multi-Brand / SaaS Platform)
|
|
87
|
+
const { subscriber } = await platform.subscribers.create({
|
|
88
|
+
email: 'customer@example.com',
|
|
89
|
+
firstName: 'Jane',
|
|
90
|
+
domain: 'pizzapalace.com', // Required for multi-brand
|
|
91
|
+
tags: ['loyalty-member']
|
|
92
|
+
});
|
|
93
|
+
|
|
75
94
|
// List subscribers
|
|
76
95
|
const { subscribers, total } = await client.subscribers.list({
|
|
77
96
|
limit: 50,
|
|
78
97
|
offset: 0
|
|
79
98
|
});
|
|
99
|
+
|
|
100
|
+
// List subscribers for a specific client (Multi-Brand)
|
|
101
|
+
const { subscribers } = await platform.subscribers.list({
|
|
102
|
+
domain: 'pizzapalace.com',
|
|
103
|
+
limit: 50
|
|
104
|
+
});
|
|
80
105
|
```
|
|
81
106
|
|
|
82
107
|
### Campaigns
|
|
83
108
|
|
|
84
109
|
```typescript
|
|
85
|
-
// Send campaign
|
|
110
|
+
// Send campaign (Single Brand)
|
|
86
111
|
await client.campaigns.send({
|
|
87
112
|
name: 'Weekly Newsletter',
|
|
88
113
|
subject: 'What\'s new this week',
|
|
@@ -91,17 +116,39 @@ await client.campaigns.send({
|
|
|
91
116
|
html: '<h1>Hello {{first_name}}!</h1>',
|
|
92
117
|
tags: ['newsletter'] // Filter by subscriber tags
|
|
93
118
|
});
|
|
119
|
+
|
|
120
|
+
// Send campaign (Multi-Brand / SaaS Platform)
|
|
121
|
+
// Workspace auto-detected from fromEmail domain
|
|
122
|
+
await platform.campaigns.send({
|
|
123
|
+
name: 'Pizza Promo',
|
|
124
|
+
subject: 'New menu items!',
|
|
125
|
+
fromName: 'Pizza Palace',
|
|
126
|
+
fromEmail: 'promo@pizzapalace.com', // ← Workspace auto-detected
|
|
127
|
+
html: '<h1>Check out our new items!</h1>',
|
|
128
|
+
sourceDomains: ['pizzapalace.com'] // Only send to subscribers from this domain
|
|
129
|
+
});
|
|
94
130
|
```
|
|
95
131
|
|
|
96
132
|
### Domains
|
|
97
133
|
|
|
98
134
|
```typescript
|
|
99
|
-
// Add sending domain
|
|
135
|
+
// Add sending domain (Single Brand)
|
|
100
136
|
const { domain } = await client.domains.create({
|
|
101
137
|
domain: 'yourcompany.com'
|
|
102
138
|
});
|
|
103
139
|
|
|
104
140
|
console.log('DNS Records to add:', domain.dnsRecords);
|
|
141
|
+
|
|
142
|
+
// Add client domain (Multi-Brand / SaaS Platform)
|
|
143
|
+
// Show these DNS records to your client in your UI
|
|
144
|
+
const { dns_records, domain_id } = await platform.domains.create({
|
|
145
|
+
domain: 'pizzapalace.com'
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// After client verifies DNS:
|
|
149
|
+
// ✓ Domain status becomes "verified"
|
|
150
|
+
// ✓ Workspace is AUTO-CREATED for this domain
|
|
151
|
+
// ✓ You can now send emails from @pizzapalace.com
|
|
105
152
|
```
|
|
106
153
|
|
|
107
154
|
## Organization & Industries
|
|
@@ -131,27 +178,97 @@ console.log(INDUSTRIES);
|
|
|
131
178
|
|
|
132
179
|
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
|
|
133
180
|
|
|
134
|
-
##
|
|
181
|
+
## Account Types
|
|
182
|
+
|
|
183
|
+
### Single Brand (Business)
|
|
184
|
+
|
|
185
|
+
For companies sending emails from their own domain. Simple setup, no workspaces needed.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
const client = new SendMailOS('sk_live_your_api_key');
|
|
189
|
+
|
|
190
|
+
await client.emails.send({
|
|
191
|
+
to: 'customer@example.com',
|
|
192
|
+
fromEmail: 'hello@yourcompany.com',
|
|
193
|
+
subject: 'Welcome!',
|
|
194
|
+
html: '<h1>Hello!</h1>'
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Multi-Brand / SaaS Platform
|
|
135
199
|
|
|
136
|
-
|
|
200
|
+
For agencies or SaaS platforms managing multiple clients. Each client gets their own workspace with isolated data.
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// Your platform's master API key
|
|
204
|
+
const platform = new SendMailOS('sk_live_platform_key');
|
|
205
|
+
|
|
206
|
+
// 1. Client signs up → Register their domain
|
|
207
|
+
const { dns_records } = await platform.domains.create({
|
|
208
|
+
domain: 'pizzapalace.com'
|
|
209
|
+
});
|
|
210
|
+
// Show dns_records to client in your UI
|
|
211
|
+
|
|
212
|
+
// 2. Domain verified → Workspace auto-created!
|
|
213
|
+
// (No manual workspace creation needed)
|
|
214
|
+
|
|
215
|
+
// 3. Send emails → Workspace auto-detected from fromEmail
|
|
216
|
+
await platform.emails.send({
|
|
217
|
+
to: 'customer@example.com',
|
|
218
|
+
fromEmail: 'orders@pizzapalace.com', // ← Workspace detected automatically!
|
|
219
|
+
fromName: 'Pizza Palace',
|
|
220
|
+
subject: 'Your order is ready!',
|
|
221
|
+
html: '<h1>Order Ready!</h1>'
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// 4. Add subscribers → Use domain param
|
|
225
|
+
await platform.subscribers.create({
|
|
226
|
+
email: 'customer@example.com',
|
|
227
|
+
domain: 'pizzapalace.com' // Required for multi-brand
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// 5. List subscribers for a specific client
|
|
231
|
+
const { subscribers } = await platform.subscribers.list({
|
|
232
|
+
domain: 'pizzapalace.com'
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// 6. Send campaign → Workspace auto-detected
|
|
236
|
+
await platform.campaigns.send({
|
|
237
|
+
subject: 'New Menu Items!',
|
|
238
|
+
fromName: 'Pizza Palace',
|
|
239
|
+
fromEmail: 'promo@pizzapalace.com', // ← Auto-detected
|
|
240
|
+
html: '<h1>Check out our new menu!</h1>'
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### How Workspace Detection Works
|
|
245
|
+
|
|
246
|
+
| Action | How workspace is identified |
|
|
247
|
+
|--------|----------------------------|
|
|
248
|
+
| Register domain | Creates domain record (pending) |
|
|
249
|
+
| Domain verified | **Workspace auto-created** |
|
|
250
|
+
| Send email | Auto-detect from `fromEmail` domain |
|
|
251
|
+
| Send campaign | Auto-detect from `fromEmail` domain |
|
|
252
|
+
| Add subscriber | From `domain` parameter |
|
|
253
|
+
| List subscribers | From `domain` parameter |
|
|
254
|
+
|
|
255
|
+
**One verified domain = One workspace.** Simple.
|
|
256
|
+
|
|
257
|
+
## Agency Workspaces (Advanced)
|
|
258
|
+
|
|
259
|
+
For more control, you can manually manage workspaces:
|
|
137
260
|
|
|
138
261
|
```typescript
|
|
139
262
|
// Convert to agency account first
|
|
140
263
|
await client.organization.convertToAgency();
|
|
141
264
|
|
|
142
|
-
// Create client workspaces
|
|
265
|
+
// Create client workspaces manually
|
|
143
266
|
const pizzaPlace = await client.workspaces.create({
|
|
144
267
|
name: 'Pizza Palace',
|
|
145
268
|
industry: 'restaurants',
|
|
146
269
|
import_templates: true // Auto-import restaurant templates
|
|
147
270
|
});
|
|
148
271
|
|
|
149
|
-
const gym = await client.workspaces.create({
|
|
150
|
-
name: 'FitLife Gym',
|
|
151
|
-
industry: 'gyms',
|
|
152
|
-
import_templates: true
|
|
153
|
-
});
|
|
154
|
-
|
|
155
272
|
// List all clients
|
|
156
273
|
const { workspaces } = await client.workspaces.list();
|
|
157
274
|
for (const ws of workspaces) {
|
|
@@ -167,6 +284,231 @@ console.log(details.stats);
|
|
|
167
284
|
await client.workspaces.inviteClient(pizzaPlace.id, 'owner@pizzapalace.com');
|
|
168
285
|
```
|
|
169
286
|
|
|
287
|
+
## Workflows
|
|
288
|
+
|
|
289
|
+
Automate email sequences with workflows. Create them via API, build the steps in your UI, then trigger them programmatically.
|
|
290
|
+
|
|
291
|
+
### Workflow Lifecycle
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
1. Create workflow (draft)
|
|
295
|
+
2. Add nodes & edges (build the flow)
|
|
296
|
+
3. Activate workflow (start accepting triggers)
|
|
297
|
+
4. Trigger for subscribers (via API or events)
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Create & Manage Workflows
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
// Create a workflow for a client (Multi-Brand)
|
|
304
|
+
const { data } = await platform.workflows.create({
|
|
305
|
+
name: 'Welcome Sequence',
|
|
306
|
+
domain: 'pizzapalace.com', // Auto-detect workspace
|
|
307
|
+
trigger: { type: 'api' } // Triggered via API
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
const workflowId = data.workflow.id;
|
|
311
|
+
|
|
312
|
+
// List workflows
|
|
313
|
+
const { data: list } = await platform.workflows.list({ domain: 'pizzapalace.com' });
|
|
314
|
+
|
|
315
|
+
// Get workflow with nodes/edges
|
|
316
|
+
const { data: workflow } = await platform.workflows.get(workflowId);
|
|
317
|
+
|
|
318
|
+
// Delete workflow
|
|
319
|
+
await platform.workflows.delete(workflowId);
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Build Workflow Steps
|
|
323
|
+
|
|
324
|
+
Update a workflow with nodes (steps) and edges (connections):
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
await platform.workflows.update(workflowId, {
|
|
328
|
+
nodes: [
|
|
329
|
+
{
|
|
330
|
+
id: 'trigger-1',
|
|
331
|
+
type: 'trigger',
|
|
332
|
+
data: { triggerType: 'api' }
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
id: 'email-1',
|
|
336
|
+
type: 'email',
|
|
337
|
+
data: {
|
|
338
|
+
subject: 'Welcome to {{restaurantName}}!',
|
|
339
|
+
templateId: 'tmpl_welcome'
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
id: 'delay-1',
|
|
344
|
+
type: 'delay',
|
|
345
|
+
data: { duration: 3, unit: 'days' }
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
id: 'email-2',
|
|
349
|
+
type: 'email',
|
|
350
|
+
data: {
|
|
351
|
+
subject: 'Your first order discount',
|
|
352
|
+
templateId: 'tmpl_promo'
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
],
|
|
356
|
+
edges: [
|
|
357
|
+
{ id: 'e1', source: 'trigger-1', target: 'email-1' },
|
|
358
|
+
{ id: 'e2', source: 'email-1', target: 'delay-1' },
|
|
359
|
+
{ id: 'e3', source: 'delay-1', target: 'email-2' }
|
|
360
|
+
]
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Node Types
|
|
365
|
+
|
|
366
|
+
| Type | Description | Data Fields |
|
|
367
|
+
|------|-------------|-------------|
|
|
368
|
+
| `trigger` | Entry point | `triggerType` |
|
|
369
|
+
| `email` | Send email | `subject`, `templateId`, `fromName`, `fromEmail` |
|
|
370
|
+
| `delay` | Wait period | `duration`, `unit` (minutes/hours/days) |
|
|
371
|
+
| `condition` | Branch logic | `field`, `operator`, `value` |
|
|
372
|
+
| `tag` | Add/remove tags | `action` (add/remove), `tags` |
|
|
373
|
+
| `http` | Call webhook | `url`, `method`, `headers`, `body` |
|
|
374
|
+
| `wait_for_event` | Wait for event | `eventName`, `timeout` |
|
|
375
|
+
| `unsubscribe` | Unsubscribe user | - |
|
|
376
|
+
| `exit` | End workflow | - |
|
|
377
|
+
|
|
378
|
+
### Activate & Pause
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
// Activate workflow (start accepting triggers)
|
|
382
|
+
await platform.workflows.activate(workflowId);
|
|
383
|
+
|
|
384
|
+
// Pause workflow (stop new triggers, existing runs continue)
|
|
385
|
+
await platform.workflows.pause(workflowId);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Trigger Workflows
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// When a customer signs up at the restaurant
|
|
392
|
+
await platform.workflows.trigger(workflowId, {
|
|
393
|
+
email: 'customer@example.com',
|
|
394
|
+
data: {
|
|
395
|
+
firstName: 'John',
|
|
396
|
+
restaurantName: 'Pizza Palace',
|
|
397
|
+
signupSource: 'website'
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Wait for Events
|
|
403
|
+
|
|
404
|
+
Workflows can pause and wait for specific events:
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
// Workflow has a "wait_for_event: purchase_completed" node
|
|
408
|
+
// When customer makes a purchase, send the event:
|
|
409
|
+
await platform.workflows.sendEvent({
|
|
410
|
+
event: 'purchase_completed',
|
|
411
|
+
email: 'customer@example.com',
|
|
412
|
+
data: { orderTotal: 45.99 }
|
|
413
|
+
});
|
|
414
|
+
// The workflow resumes from where it was waiting
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Example: Restaurant Welcome Flow
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
// 1. Create workflow
|
|
421
|
+
const { data } = await platform.workflows.create({
|
|
422
|
+
name: 'New Customer Welcome',
|
|
423
|
+
domain: 'pizzapalace.com'
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// 2. Build the flow
|
|
427
|
+
await platform.workflows.update(data.workflow.id, {
|
|
428
|
+
nodes: [
|
|
429
|
+
{ id: '1', type: 'trigger', data: { triggerType: 'api' } },
|
|
430
|
+
{ id: '2', type: 'email', data: { subject: 'Welcome!', templateId: 'tmpl_welcome' } },
|
|
431
|
+
{ id: '3', type: 'delay', data: { duration: 2, unit: 'days' } },
|
|
432
|
+
{ id: '4', type: 'condition', data: { field: 'has_ordered', operator: 'eq', value: true } },
|
|
433
|
+
{ id: '5', type: 'email', data: { subject: 'Thanks for ordering!', templateId: 'tmpl_thanks' } },
|
|
434
|
+
{ id: '6', type: 'email', data: { subject: '10% off your first order', templateId: 'tmpl_promo' } }
|
|
435
|
+
],
|
|
436
|
+
edges: [
|
|
437
|
+
{ id: 'e1', source: '1', target: '2' },
|
|
438
|
+
{ id: 'e2', source: '2', target: '3' },
|
|
439
|
+
{ id: 'e3', source: '3', target: '4' },
|
|
440
|
+
{ id: 'e4', source: '4', target: '5', sourceHandle: 'yes' },
|
|
441
|
+
{ id: 'e5', source: '4', target: '6', sourceHandle: 'no' }
|
|
442
|
+
]
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
// 3. Activate
|
|
446
|
+
await platform.workflows.activate(data.workflow.id);
|
|
447
|
+
|
|
448
|
+
// 4. Trigger when new customer signs up
|
|
449
|
+
await platform.workflows.trigger(data.workflow.id, {
|
|
450
|
+
email: 'newcustomer@gmail.com',
|
|
451
|
+
data: { firstName: 'Jane', restaurantName: 'Pizza Palace' }
|
|
452
|
+
});
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Webhooks
|
|
456
|
+
|
|
457
|
+
Receive real-time notifications when events occur (emails sent, opened, clicked, bounced, etc.).
|
|
458
|
+
|
|
459
|
+
### Create & Manage Webhooks
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
// Create a webhook endpoint
|
|
463
|
+
const { webhook } = await client.webhooks.create({
|
|
464
|
+
url: 'https://yourserver.com/webhooks',
|
|
465
|
+
events: ['email.sent', 'email.delivered', 'email.opened', 'email.clicked', 'email.bounced'],
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
console.log('Webhook secret:', webhook.secret); // Use this to verify signatures
|
|
469
|
+
|
|
470
|
+
// List all webhooks
|
|
471
|
+
const { webhooks } = await client.webhooks.list();
|
|
472
|
+
|
|
473
|
+
// Get webhook with delivery history
|
|
474
|
+
const { webhook, recentDeliveries, stats } = await client.webhooks.get('webhook-id');
|
|
475
|
+
|
|
476
|
+
// Update webhook
|
|
477
|
+
await client.webhooks.update('webhook-id', {
|
|
478
|
+
events: ['email.sent', 'email.bounced', 'email.complained']
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// Test webhook endpoint
|
|
482
|
+
const result = await client.webhooks.test('webhook-id');
|
|
483
|
+
if (result.test.sent) {
|
|
484
|
+
console.log(`Test delivered in ${result.test.responseTimeMs}ms`);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Disable/Enable webhook
|
|
488
|
+
await client.webhooks.disable('webhook-id');
|
|
489
|
+
await client.webhooks.enable('webhook-id');
|
|
490
|
+
|
|
491
|
+
// Delete webhook
|
|
492
|
+
await client.webhooks.delete('webhook-id');
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Event Types
|
|
496
|
+
|
|
497
|
+
| Event | Description |
|
|
498
|
+
|-------|-------------|
|
|
499
|
+
| `email.sent` | Email was sent to the recipient |
|
|
500
|
+
| `email.delivered` | Email was delivered to recipient's server |
|
|
501
|
+
| `email.opened` | Recipient opened the email |
|
|
502
|
+
| `email.clicked` | Recipient clicked a link in the email |
|
|
503
|
+
| `email.bounced` | Email bounced (hard or soft) |
|
|
504
|
+
| `email.complained` | Recipient marked email as spam |
|
|
505
|
+
| `subscriber.created` | New subscriber was added |
|
|
506
|
+
| `subscriber.updated` | Subscriber was updated |
|
|
507
|
+
| `subscriber.unsubscribed` | Subscriber unsubscribed |
|
|
508
|
+
| `campaign.sent` | Campaign finished sending |
|
|
509
|
+
| `workflow.started` | Workflow execution started |
|
|
510
|
+
| `workflow.completed` | Workflow execution completed |
|
|
511
|
+
|
|
170
512
|
## Pixel Tracking
|
|
171
513
|
|
|
172
514
|
Track website visitors and connect their behavior to email campaigns.
|