@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/dist/index.mjs CHANGED
@@ -54,9 +54,10 @@ var EmailsResource = class {
54
54
  }
55
55
  /**
56
56
  * Send a transactional email
57
- *
57
+ *
58
58
  * @example
59
59
  * ```ts
60
+ * // Business account (single-tenant)
60
61
  * const result = await client.emails.send({
61
62
  * to: 'user@example.com',
62
63
  * fromName: 'Your Company',
@@ -64,6 +65,16 @@ var EmailsResource = class {
64
65
  * subject: 'Welcome!',
65
66
  * html: '<h1>Hello!</h1>'
66
67
  * });
68
+ *
69
+ * // Agency account (multi-tenant) - identify client by domain
70
+ * const result = await agencyClient.emails.send({
71
+ * to: 'customer@example.com',
72
+ * fromName: 'Pizza Palace',
73
+ * fromEmail: 'hello@pizzapalace.com',
74
+ * subject: 'Your order is ready!',
75
+ * html: '<h1>Order Ready!</h1>',
76
+ * domain: 'pizzapalace.com' // Required for agency accounts
77
+ * });
67
78
  * ```
68
79
  */
69
80
  async send(params) {
@@ -77,13 +88,15 @@ var EmailsResource = class {
77
88
  from_name: params.fromName,
78
89
  from_email: params.fromEmail,
79
90
  variables: params.variables,
80
- type: params.type || "transactional"
91
+ type: params.type || "transactional",
92
+ workspace_id: params.workspaceId,
93
+ domain: params.domain
81
94
  })
82
95
  });
83
96
  }
84
97
  /**
85
98
  * Send email using a template
86
- *
99
+ *
87
100
  * @example
88
101
  * ```ts
89
102
  * const result = await client.emails.sendTemplate({
@@ -101,7 +114,9 @@ var EmailsResource = class {
101
114
  fromName: params.fromName,
102
115
  fromEmail: params.fromEmail,
103
116
  variables: params.variables,
104
- type: "transactional"
117
+ type: "transactional",
118
+ workspaceId: params.workspaceId,
119
+ domain: params.domain
105
120
  });
106
121
  }
107
122
  };
@@ -113,14 +128,23 @@ var SubscribersResource = class {
113
128
  }
114
129
  /**
115
130
  * Create or update a subscriber (upsert)
116
- *
131
+ *
117
132
  * @example
118
133
  * ```ts
134
+ * // Business account
119
135
  * const { subscriber } = await client.subscribers.create({
120
136
  * email: 'user@example.com',
121
137
  * firstName: 'John',
122
138
  * tags: ['newsletter', 'premium']
123
139
  * });
140
+ *
141
+ * // Agency account - subscriber tracked to client domain
142
+ * const { subscriber } = await agencyClient.subscribers.create({
143
+ * email: 'customer@example.com',
144
+ * firstName: 'Jane',
145
+ * domain: 'pizzapalace.com', // Required for agency accounts
146
+ * tags: ['loyalty-member']
147
+ * });
124
148
  * ```
125
149
  */
126
150
  async create(params) {
@@ -131,7 +155,10 @@ var SubscribersResource = class {
131
155
  first_name: params.firstName,
132
156
  last_name: params.lastName,
133
157
  tags: params.tags,
134
- domain_id: params.domainId
158
+ domain_id: params.domainId,
159
+ workspace_id: params.workspaceId,
160
+ domain: params.domain
161
+ // Alternative to workspace_id
135
162
  })
136
163
  });
137
164
  }
@@ -150,6 +177,8 @@ var SubscribersResource = class {
150
177
  const searchParams = new URLSearchParams();
151
178
  if (params.limit) searchParams.set("limit", String(params.limit));
152
179
  if (params.offset) searchParams.set("offset", String(params.offset));
180
+ if (params.workspaceId) searchParams.set("workspace_id", params.workspaceId);
181
+ if (params.domain) searchParams.set("domain", params.domain);
153
182
  const query = searchParams.toString();
154
183
  const endpoint = query ? `/subscribers?${query}` : "/subscribers";
155
184
  return this.request(endpoint, {
@@ -221,9 +250,10 @@ var CampaignsResource = class {
221
250
  }
222
251
  /**
223
252
  * Send a campaign to subscribers
224
- *
253
+ *
225
254
  * @example
226
255
  * ```ts
256
+ * // Business account
227
257
  * const result = await client.campaigns.send({
228
258
  * name: 'January Newsletter',
229
259
  * subject: 'What\'s new this month',
@@ -232,6 +262,17 @@ var CampaignsResource = class {
232
262
  * html: '<h1>Hello {{first_name}}!</h1>',
233
263
  * tags: ['newsletter', 'active']
234
264
  * });
265
+ *
266
+ * // Agency account - send to specific client's subscribers
267
+ * const result = await agencyClient.campaigns.send({
268
+ * name: 'Pizza Promo',
269
+ * subject: 'New menu items!',
270
+ * fromName: 'Pizza Palace',
271
+ * fromEmail: 'promo@pizzapalace.com',
272
+ * html: '<h1>Check out our new menu!</h1>',
273
+ * domain: 'pizzapalace.com', // Filter to this client's subscribers
274
+ * sourceDomains: ['pizzapalace.com'] // Only subscribers who signed up on this domain
275
+ * });
235
276
  * ```
236
277
  */
237
278
  async send(params) {
@@ -245,7 +286,10 @@ var CampaignsResource = class {
245
286
  html: params.html,
246
287
  templateId: params.templateId,
247
288
  tags: params.tags,
248
- variables: params.variables
289
+ variables: params.variables,
290
+ workspace_id: params.workspaceId,
291
+ domain: params.domain,
292
+ sourceDomains: params.sourceDomains
249
293
  })
250
294
  });
251
295
  }
@@ -260,7 +304,10 @@ var CampaignsResource = class {
260
304
  fromEmail: params.fromEmail,
261
305
  templateId: params.templateId,
262
306
  tags: params.tags,
263
- variables: params.variables
307
+ variables: params.variables,
308
+ workspaceId: params.workspaceId,
309
+ domain: params.domain,
310
+ sourceDomains: params.sourceDomains
264
311
  });
265
312
  }
266
313
  };
@@ -325,10 +372,633 @@ var DomainsResource = class {
325
372
  }
326
373
  };
327
374
 
375
+ // src/resources/organization.ts
376
+ var OrganizationResource = class {
377
+ constructor(request) {
378
+ this.request = request;
379
+ }
380
+ /**
381
+ * Get current organization details
382
+ */
383
+ async get() {
384
+ const response = await this.request("/organization", {
385
+ method: "GET"
386
+ });
387
+ return response.organization;
388
+ }
389
+ /**
390
+ * Update organization settings
391
+ */
392
+ async update(updates) {
393
+ const response = await this.request("/organization", {
394
+ method: "PATCH",
395
+ body: JSON.stringify(updates)
396
+ });
397
+ return response.organization;
398
+ }
399
+ /**
400
+ * Set organization industries (during onboarding)
401
+ *
402
+ * @example
403
+ * ```ts
404
+ * await client.organization.setIndustries(['ecommerce', 'saas']);
405
+ * ```
406
+ */
407
+ async setIndustries(industries) {
408
+ return this.update({ industries });
409
+ }
410
+ /**
411
+ * Convert to agency account (enables workspaces)
412
+ *
413
+ * @example
414
+ * ```ts
415
+ * await client.organization.convertToAgency();
416
+ * // Now you can create client workspaces
417
+ * await client.workspaces.create({ name: 'Client A', industry: 'ecommerce' });
418
+ * ```
419
+ */
420
+ async convertToAgency() {
421
+ return this.update({ org_type: "agency" });
422
+ }
423
+ /**
424
+ * Complete onboarding
425
+ */
426
+ async completeOnboarding() {
427
+ return this.update({ onboarding_completed: true });
428
+ }
429
+ };
430
+ var INDUSTRIES = {
431
+ hotels: "Hotels & Hospitality",
432
+ restaurants: "Restaurants & Food Service",
433
+ gyms: "Gyms & Fitness",
434
+ travel_agencies: "Travel Agencies",
435
+ real_estate: "Real Estate",
436
+ schools: "Schools & Education",
437
+ ecommerce: "E-commerce",
438
+ dentists: "Dentists",
439
+ car_dealerships: "Car Dealerships",
440
+ events: "Events & Entertainment",
441
+ beauty_salons: "Beauty Salons",
442
+ law_firms: "Law Firms",
443
+ nonprofits: "Non-Profits",
444
+ saas: "SaaS & Software",
445
+ recruitment: "Recruitment & HR",
446
+ insurance: "Insurance",
447
+ online_courses: "Online Courses",
448
+ municipalities: "Government & Municipalities",
449
+ personal_trainers: "Personal Trainers",
450
+ influencers: "Influencers & Creators",
451
+ doctors_clinics: "Doctors & Clinics",
452
+ nightclubs: "Nightclubs & Bars",
453
+ coworking: "Coworking Spaces",
454
+ wedding_planners: "Wedding Planners",
455
+ art_galleries: "Art Galleries",
456
+ car_rentals: "Car Rentals",
457
+ podcasters: "Podcasters",
458
+ consultants: "Consultants",
459
+ bakeries: "Bakeries",
460
+ veterinarians: "Veterinarians",
461
+ airbnb_hosts: "Airbnb Hosts",
462
+ accountants: "Accountants",
463
+ developers: "Developers",
464
+ musicians: "Musicians & Bands",
465
+ spas: "Spas & Wellness",
466
+ bookstores: "Bookstores",
467
+ cleaning_services: "Cleaning Services",
468
+ churches: "Churches & Religious",
469
+ graphic_designers: "Graphic Designers",
470
+ coffee_shops: "Coffee Shops",
471
+ florists: "Florists",
472
+ political: "Political Campaigns",
473
+ libraries: "Libraries",
474
+ taxis_limos: "Taxis & Limos",
475
+ home_inspectors: "Home Inspectors",
476
+ photographers: "Photographers",
477
+ universities: "Universities",
478
+ fashion: "Fashion Brands",
479
+ nutritionists: "Nutritionists",
480
+ startups: "Startups",
481
+ other: "Other"
482
+ };
483
+
484
+ // src/resources/workspaces.ts
485
+ var WorkspacesResource = class {
486
+ constructor(request) {
487
+ this.request = request;
488
+ }
489
+ /**
490
+ * List all workspaces (clients)
491
+ * @note Only available for agency accounts
492
+ *
493
+ * @example
494
+ * ```ts
495
+ * const { workspaces } = await client.workspaces.list();
496
+ * for (const ws of workspaces) {
497
+ * console.log(`${ws.name}: ${ws.stats?.subscribers} subscribers`);
498
+ * }
499
+ * ```
500
+ */
501
+ async list() {
502
+ const response = await this.request("/workspaces", {
503
+ method: "GET"
504
+ });
505
+ return { workspaces: response.workspaces, total: response.total };
506
+ }
507
+ /**
508
+ * Create a new workspace (client)
509
+ * @note Only available for agency accounts
510
+ *
511
+ * @example
512
+ * ```ts
513
+ * const workspace = await client.workspaces.create({
514
+ * name: 'Pizza Palace',
515
+ * industry: 'restaurants',
516
+ * import_templates: true // Auto-import restaurant templates
517
+ * });
518
+ * ```
519
+ */
520
+ async create(workspace) {
521
+ const response = await this.request("/workspaces", {
522
+ method: "POST",
523
+ body: JSON.stringify(workspace)
524
+ });
525
+ return response.workspace;
526
+ }
527
+ /**
528
+ * Get a workspace by ID with detailed stats
529
+ *
530
+ * @example
531
+ * ```ts
532
+ * const workspace = await client.workspaces.get('ws_123');
533
+ * console.log('Active subscribers:', workspace.stats.active_subscribers);
534
+ * ```
535
+ */
536
+ async get(workspaceId) {
537
+ const response = await this.request(`/workspaces/${workspaceId}`, {
538
+ method: "GET"
539
+ });
540
+ return response.workspace;
541
+ }
542
+ /**
543
+ * Update a workspace
544
+ *
545
+ * @example
546
+ * ```ts
547
+ * await client.workspaces.update('ws_123', {
548
+ * name: 'Pizza Palace - Main Location',
549
+ * client_can_view_reports: true
550
+ * });
551
+ * ```
552
+ */
553
+ async update(workspaceId, updates) {
554
+ const response = await this.request(`/workspaces/${workspaceId}`, {
555
+ method: "PATCH",
556
+ body: JSON.stringify(updates)
557
+ });
558
+ return response.workspace;
559
+ }
560
+ /**
561
+ * Delete a workspace
562
+ * @warning This will delete all associated data (subscribers, campaigns, etc.)
563
+ *
564
+ * @example
565
+ * ```ts
566
+ * await client.workspaces.delete('ws_123');
567
+ * ```
568
+ */
569
+ async delete(workspaceId) {
570
+ const response = await this.request(`/workspaces/${workspaceId}`, {
571
+ method: "DELETE"
572
+ });
573
+ return { message: response.message };
574
+ }
575
+ /**
576
+ * Activate a workspace
577
+ */
578
+ async activate(workspaceId) {
579
+ return this.update(workspaceId, { is_active: true });
580
+ }
581
+ /**
582
+ * Deactivate a workspace
583
+ */
584
+ async deactivate(workspaceId) {
585
+ return this.update(workspaceId, { is_active: false });
586
+ }
587
+ /**
588
+ * Invite client to view reports
589
+ *
590
+ * @example
591
+ * ```ts
592
+ * await client.workspaces.inviteClient('ws_123', 'owner@pizzapalace.com');
593
+ * // Client receives email with portal access
594
+ * ```
595
+ */
596
+ async inviteClient(workspaceId, email) {
597
+ return this.update(workspaceId, {
598
+ client_email: email,
599
+ client_can_view_reports: true
600
+ });
601
+ }
602
+ /**
603
+ * Smart workspace provisioning - finds existing or creates new
604
+ *
605
+ * This is the recommended method for agency client onboarding.
606
+ * It will:
607
+ * 1. Search for existing workspace by website URL or client_email
608
+ * 2. Return existing workspace if found
609
+ * 3. Create new workspace with industry templates if not found
610
+ * 4. Optionally generate a workspace-scoped API key
611
+ *
612
+ * @note Only available for agency accounts
613
+ *
614
+ * @example
615
+ * ```ts
616
+ * // Auto-provision workspace for a new client
617
+ * const result = await client.workspaces.provision({
618
+ * name: 'Pizza Palace',
619
+ * website: 'https://pizzapalace.com',
620
+ * client_email: 'owner@pizzapalace.com',
621
+ * industry: 'restaurants',
622
+ * generate_api_key: true
623
+ * });
624
+ *
625
+ * if (result.is_new) {
626
+ * console.log('Created new workspace:', result.workspace.id);
627
+ * console.log('API Key:', result.api_key);
628
+ * } else {
629
+ * console.log('Found existing workspace:', result.workspace.id);
630
+ * }
631
+ * ```
632
+ *
633
+ * @example
634
+ * ```ts
635
+ * // Idempotent client setup - safe to call multiple times
636
+ * const { workspace, is_new } = await client.workspaces.provision({
637
+ * name: 'Client Name',
638
+ * website: 'https://client.com',
639
+ * industry: 'ecommerce'
640
+ * });
641
+ * // Always returns the same workspace for the same website
642
+ * ```
643
+ */
644
+ async provision(request) {
645
+ const response = await this.request("/workspaces/provision", {
646
+ method: "POST",
647
+ body: JSON.stringify(request)
648
+ });
649
+ return {
650
+ workspace: response.workspace,
651
+ is_new: response.is_new,
652
+ api_key: response.api_key,
653
+ message: response.message
654
+ };
655
+ }
656
+ /**
657
+ * Alias for provision() - find or create workspace
658
+ * @see provision
659
+ */
660
+ async findOrCreate(request) {
661
+ return this.provision(request);
662
+ }
663
+ /**
664
+ * Complete client onboarding in ONE call (Agency only)
665
+ *
666
+ * This is the simplest way to onboard a new client:
667
+ * 1. Creates or finds workspace by domain
668
+ * 2. Registers domain for email verification
669
+ * 3. Generates workspace token
670
+ * 4. Returns DNS records + token
671
+ *
672
+ * After this, use the returned `token` for all API calls.
673
+ *
674
+ * @example
675
+ * ```ts
676
+ * // Your SaaS onboards a new restaurant
677
+ * const result = await agency.workspaces.onboard({
678
+ * domain: 'pizzapalace.com',
679
+ * industry: 'restaurants'
680
+ * });
681
+ *
682
+ * // Save this token - it's all you need
683
+ * saveToDatabase(restaurantId, result.token);
684
+ *
685
+ * // Show DNS records to restaurant owner
686
+ * console.log('Add these DNS records:', result.dns_records);
687
+ *
688
+ * // Later, use the token directly
689
+ * const restaurant = new SendMailOS(result.token);
690
+ * await restaurant.emails.send({ ... });
691
+ * ```
692
+ */
693
+ async onboard(request) {
694
+ const response = await this.request("/workspaces/onboard", {
695
+ method: "POST",
696
+ body: JSON.stringify(request)
697
+ });
698
+ return {
699
+ token: response.token,
700
+ workspace_id: response.workspace_id,
701
+ workspace_name: response.workspace_name,
702
+ domain: response.domain,
703
+ domain_status: response.domain_status,
704
+ dns_records: response.dns_records,
705
+ is_new: response.is_new,
706
+ message: response.message
707
+ };
708
+ }
709
+ };
710
+
711
+ // src/resources/workflows.ts
712
+ var WorkflowsResource = class {
713
+ constructor(request) {
714
+ this.request = request;
715
+ }
716
+ /**
717
+ * Create a new workflow
718
+ *
719
+ * @example
720
+ * ```ts
721
+ * // Create workflow for a specific client (multi-brand)
722
+ * const result = await platform.workflows.create({
723
+ * name: 'Welcome Sequence',
724
+ * domain: 'pizzapalace.com',
725
+ * trigger: { type: 'subscriber_created' }
726
+ * });
727
+ *
728
+ * // Create workflow (single brand)
729
+ * const result = await client.workflows.create({
730
+ * name: 'Onboarding Flow',
731
+ * trigger: { type: 'api' }
732
+ * });
733
+ * ```
734
+ */
735
+ async create(params) {
736
+ return this.request("/workflows", {
737
+ method: "POST",
738
+ body: JSON.stringify(params)
739
+ });
740
+ }
741
+ /**
742
+ * List all workflows
743
+ *
744
+ * @example
745
+ * ```ts
746
+ * // List all workflows
747
+ * const { workflows } = await client.workflows.list();
748
+ *
749
+ * // List workflows for a specific client (multi-brand)
750
+ * const { workflows } = await platform.workflows.list({ domain: 'pizzapalace.com' });
751
+ * ```
752
+ */
753
+ async list(params = {}) {
754
+ const searchParams = new URLSearchParams();
755
+ if (params.domain) searchParams.set("domain", params.domain);
756
+ if (params.workspace_id) searchParams.set("workspace_id", params.workspace_id);
757
+ const query = searchParams.toString();
758
+ const endpoint = query ? `/workflows?${query}` : "/workflows";
759
+ return this.request(endpoint, {
760
+ method: "GET"
761
+ });
762
+ }
763
+ /**
764
+ * Get a workflow by ID (includes nodes and edges)
765
+ *
766
+ * @example
767
+ * ```ts
768
+ * const { workflow } = await client.workflows.get('workflow-uuid');
769
+ * console.log(workflow.nodes); // The workflow steps
770
+ * console.log(workflow.edges); // Connections between steps
771
+ * ```
772
+ */
773
+ async get(workflowId) {
774
+ return this.request(`/workflows/${workflowId}`, {
775
+ method: "GET"
776
+ });
777
+ }
778
+ /**
779
+ * Update a workflow (name, nodes, edges, trigger)
780
+ *
781
+ * @example
782
+ * ```ts
783
+ * // Update workflow name
784
+ * await client.workflows.update('workflow-uuid', { name: 'New Name' });
785
+ *
786
+ * // Update workflow steps
787
+ * await client.workflows.update('workflow-uuid', {
788
+ * nodes: [
789
+ * { id: '1', type: 'trigger', data: { triggerType: 'api' } },
790
+ * { id: '2', type: 'email', data: { templateId: 'tmpl_xxx', subject: 'Welcome!' } },
791
+ * { id: '3', type: 'delay', data: { duration: 3, unit: 'days' } }
792
+ * ],
793
+ * edges: [
794
+ * { id: 'e1', source: '1', target: '2' },
795
+ * { id: 'e2', source: '2', target: '3' }
796
+ * ]
797
+ * });
798
+ * ```
799
+ */
800
+ async update(workflowId, params) {
801
+ return this.request(`/workflows/${workflowId}`, {
802
+ method: "PUT",
803
+ body: JSON.stringify(params)
804
+ });
805
+ }
806
+ /**
807
+ * Delete a workflow
808
+ */
809
+ async delete(workflowId) {
810
+ return this.request(`/workflows/${workflowId}`, {
811
+ method: "DELETE"
812
+ });
813
+ }
814
+ /**
815
+ * Activate a workflow (start accepting triggers)
816
+ *
817
+ * @example
818
+ * ```ts
819
+ * await client.workflows.activate('workflow-uuid');
820
+ * // Workflow is now active and will process triggers
821
+ * ```
822
+ */
823
+ async activate(workflowId) {
824
+ return this.request(`/workflows/${workflowId}/activate`, {
825
+ method: "POST"
826
+ });
827
+ }
828
+ /**
829
+ * Pause a workflow (stop accepting new triggers)
830
+ *
831
+ * @example
832
+ * ```ts
833
+ * await client.workflows.pause('workflow-uuid');
834
+ * // Workflow is paused - existing executions continue, but no new ones start
835
+ * ```
836
+ */
837
+ async pause(workflowId) {
838
+ return this.request(`/workflows/${workflowId}/pause`, {
839
+ method: "POST"
840
+ });
841
+ }
842
+ /**
843
+ * Trigger a workflow for a subscriber
844
+ *
845
+ * @example
846
+ * ```ts
847
+ * // Trigger when a customer signs up
848
+ * const result = await platform.workflows.trigger('workflow-uuid', {
849
+ * email: 'customer@example.com',
850
+ * data: {
851
+ * firstName: 'John',
852
+ * restaurantName: 'Pizza Palace',
853
+ * signupSource: 'website'
854
+ * }
855
+ * });
856
+ *
857
+ * console.log(result.execution_id); // Track this execution
858
+ * ```
859
+ */
860
+ async trigger(workflowId, params) {
861
+ return this.request(`/webhooks/${workflowId}`, {
862
+ method: "POST",
863
+ body: JSON.stringify(params)
864
+ });
865
+ }
866
+ /**
867
+ * Send a custom event to resume waiting workflows
868
+ *
869
+ * Use this when you have workflows waiting for specific events (e.g., "purchase_completed").
870
+ * All workflows waiting for this event for the given subscriber will resume.
871
+ *
872
+ * @example
873
+ * ```ts
874
+ * // When a customer completes a purchase
875
+ * await platform.workflows.sendEvent({
876
+ * event: 'purchase_completed',
877
+ * email: 'customer@example.com',
878
+ * data: { orderTotal: 45.99, orderId: 'ORD-123' }
879
+ * });
880
+ *
881
+ * // Any workflow with a "wait_for_event: purchase_completed" node will resume
882
+ * ```
883
+ */
884
+ async sendEvent(params) {
885
+ return this.request("/events", {
886
+ method: "POST",
887
+ body: JSON.stringify(params)
888
+ });
889
+ }
890
+ };
891
+
892
+ // src/resources/webhooks.ts
893
+ var WebhooksResource = class {
894
+ constructor(request) {
895
+ this.request = request;
896
+ }
897
+ /**
898
+ * Create a new webhook endpoint
899
+ *
900
+ * @example
901
+ * ```ts
902
+ * const webhook = await client.webhooks.create({
903
+ * url: 'https://yourserver.com/webhooks',
904
+ * events: ['email.sent', 'email.delivered', 'email.opened'],
905
+ * secret: 'your-secret-key' // Optional, auto-generated if not provided
906
+ * });
907
+ *
908
+ * console.log('Webhook secret:', webhook.secret);
909
+ * ```
910
+ */
911
+ async create(params) {
912
+ return this.request("/webhooks", {
913
+ method: "POST",
914
+ body: JSON.stringify(params)
915
+ });
916
+ }
917
+ /**
918
+ * List all webhooks
919
+ */
920
+ async list() {
921
+ return this.request("/webhooks", {
922
+ method: "GET"
923
+ });
924
+ }
925
+ /**
926
+ * Get a webhook by ID with recent delivery history
927
+ */
928
+ async get(webhookId) {
929
+ return this.request(`/webhooks/${webhookId}`, {
930
+ method: "GET"
931
+ });
932
+ }
933
+ /**
934
+ * Update a webhook
935
+ *
936
+ * @example
937
+ * ```ts
938
+ * // Update webhook URL
939
+ * await client.webhooks.update('webhook-id', {
940
+ * url: 'https://newserver.com/webhooks'
941
+ * });
942
+ *
943
+ * // Add new events
944
+ * await client.webhooks.update('webhook-id', {
945
+ * events: ['email.sent', 'email.delivered', 'email.bounced']
946
+ * });
947
+ *
948
+ * // Disable webhook
949
+ * await client.webhooks.update('webhook-id', { active: false });
950
+ * ```
951
+ */
952
+ async update(webhookId, params) {
953
+ return this.request(`/webhooks/${webhookId}`, {
954
+ method: "PATCH",
955
+ body: JSON.stringify(params)
956
+ });
957
+ }
958
+ /**
959
+ * Delete a webhook
960
+ */
961
+ async delete(webhookId) {
962
+ return this.request(`/webhooks/${webhookId}`, {
963
+ method: "DELETE"
964
+ });
965
+ }
966
+ /**
967
+ * Test a webhook by sending a test event
968
+ *
969
+ * @example
970
+ * ```ts
971
+ * const result = await client.webhooks.test('webhook-id');
972
+ * if (result.test.sent) {
973
+ * console.log(`Test delivered in ${result.test.responseTimeMs}ms`);
974
+ * } else {
975
+ * console.log('Test failed:', result.test.error);
976
+ * }
977
+ * ```
978
+ */
979
+ async test(webhookId) {
980
+ return this.request(`/webhooks/${webhookId}/test`, {
981
+ method: "POST"
982
+ });
983
+ }
984
+ /**
985
+ * Enable a webhook
986
+ */
987
+ async enable(webhookId) {
988
+ return this.update(webhookId, { active: true });
989
+ }
990
+ /**
991
+ * Disable a webhook
992
+ */
993
+ async disable(webhookId) {
994
+ return this.update(webhookId, { active: false });
995
+ }
996
+ };
997
+
328
998
  // src/client.ts
329
999
  var DEFAULT_BASE_URL = "https://api.sendmailos.com/api/v1";
330
1000
  var DEFAULT_TIMEOUT = 3e4;
331
- var SDK_VERSION = "1.0.0";
1001
+ var SDK_VERSION = "1.2.0";
332
1002
  var SendMailOS = class {
333
1003
  constructor(apiKey, options = {}) {
334
1004
  if (!apiKey) {
@@ -353,6 +1023,10 @@ var SendMailOS = class {
353
1023
  this.subscribers = new SubscribersResource(boundRequest);
354
1024
  this.campaigns = new CampaignsResource(boundRequest);
355
1025
  this.domains = new DomainsResource(boundRequest);
1026
+ this.organization = new OrganizationResource(boundRequest);
1027
+ this.workspaces = new WorkspacesResource(boundRequest);
1028
+ this.workflows = new WorkflowsResource(boundRequest);
1029
+ this.webhooks = new WebhooksResource(boundRequest);
356
1030
  }
357
1031
  /**
358
1032
  * Make an authenticated request to the API
@@ -896,6 +1570,6 @@ function constructWebhookEvent(payload, headers, secret) {
896
1570
  return JSON.parse(payload);
897
1571
  }
898
1572
 
899
- export { AuthenticationError, NotFoundError, Pixel, RateLimitError, SendMailOS, SendMailOSError, SendmailPixel, ValidationError, constructWebhookEvent, createGlobalPixel, SendMailOS as default, verifyWebhookSignature, verifyWebhookSignatureAsync };
1573
+ export { AuthenticationError, INDUSTRIES, NotFoundError, Pixel, RateLimitError, SendMailOS, SendMailOSError, SendmailPixel, ValidationError, constructWebhookEvent, createGlobalPixel, SendMailOS as default, verifyWebhookSignature, verifyWebhookSignatureAsync };
900
1574
  //# sourceMappingURL=index.mjs.map
901
1575
  //# sourceMappingURL=index.mjs.map