groundmail 0.0.0-stage → 0.14.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.
@@ -0,0 +1,950 @@
1
+ type ApiErrorCode = 'validation_error' | 'unauthorized' | 'forbidden' | 'not_found' | 'conflict' | 'plan_limit' | 'domain_limit' | 'idempotency_conflict' | 'rate_limited' | 'upstream_error' | 'not_configured' | 'internal_error';
2
+ type SendEmailParams = {
3
+ from: string | {
4
+ email: string;
5
+ name?: string;
6
+ };
7
+ to: string | string[];
8
+ /** Required unless `template` supplies the subject. */
9
+ subject?: string;
10
+ html?: string;
11
+ htmlBody?: string;
12
+ html_body?: string;
13
+ text?: string;
14
+ textBody?: string;
15
+ text_body?: string;
16
+ plain_body?: string;
17
+ /**
18
+ * React Email element (third-party MIT project — see https://react.email).
19
+ * Compiled to HTML via optional peer `@react-email/render` in your app before
20
+ * the request is sent. Mutually exclusive with `html` / `text` / `template`.
21
+ */
22
+ react?: unknown;
23
+ /** Send using a published template (id or alias). Mutually exclusive with html/text/react. */
24
+ template?: {
25
+ id: string;
26
+ variables?: Record<string, string | number | boolean>;
27
+ };
28
+ replyTo?: string | string[];
29
+ reply_to?: string | string[];
30
+ cc?: string | string[];
31
+ bcc?: string | string[];
32
+ tags?: Array<{
33
+ name: string;
34
+ value: string;
35
+ }> | Record<string, string>;
36
+ headers?: Record<string, string>;
37
+ tag?: string;
38
+ attachments?: Array<{
39
+ name?: string;
40
+ filename?: string;
41
+ content_type?: string;
42
+ contentType?: string;
43
+ data?: string;
44
+ content?: string;
45
+ content_id?: string;
46
+ contentId?: string;
47
+ }>;
48
+ scheduledAt?: string | Date;
49
+ scheduled_at?: string | Date;
50
+ /** Optional Idempotency-Key (24h TTL). */
51
+ idempotencyKey?: string;
52
+ /** Opt in to managed unsubscribe for this send. */
53
+ unsubscribe?: boolean;
54
+ /** Optional category override for preference management. */
55
+ category?: 'transactional' | 'product' | 'newsletter';
56
+ };
57
+ type SendEmailResult = {
58
+ id: string;
59
+ status: string;
60
+ };
61
+ type BatchSendEmailResult = {
62
+ data: Array<{
63
+ index: number;
64
+ id?: string;
65
+ status?: string;
66
+ error?: {
67
+ message: string;
68
+ code?: string;
69
+ details?: unknown;
70
+ status_code?: number;
71
+ };
72
+ }>;
73
+ };
74
+ type UpdateEmailParams = {
75
+ scheduledAt?: string | Date;
76
+ scheduled_at?: string | Date;
77
+ cancel?: boolean;
78
+ };
79
+ type EmailListItem = {
80
+ id: string;
81
+ from: string;
82
+ to: string[];
83
+ cc: string[];
84
+ bcc: string[];
85
+ reply_to: string[];
86
+ subject: string;
87
+ status: string;
88
+ last_event: string | null;
89
+ bounce_reason: string | null;
90
+ tags: unknown;
91
+ scheduled_at: string | null;
92
+ cancelled_at: string | null;
93
+ created_at: string;
94
+ sent_at: string | null;
95
+ delivered_at: string | null;
96
+ bounced_at: string | null;
97
+ };
98
+ type ReceivedEmailAttachmentMeta = {
99
+ filename: string;
100
+ content_type: string;
101
+ size: number;
102
+ content_id?: string | null;
103
+ };
104
+ type ReceivedEmailAttachment = ReceivedEmailAttachmentMeta & {
105
+ data?: string;
106
+ };
107
+ type ReceivedEmail = {
108
+ id: string;
109
+ domain_id: string;
110
+ domain_name: string;
111
+ status: 'received' | string;
112
+ rcpt_to: string;
113
+ mail_from: string | null;
114
+ from: string;
115
+ to: string[];
116
+ cc: string[];
117
+ subject: string;
118
+ spam_status: string | null;
119
+ bounced: boolean;
120
+ received_with_ssl: boolean | null;
121
+ message_id: string | null;
122
+ in_reply_to: string | null;
123
+ references: string[];
124
+ attachment_count: number;
125
+ attachments: ReceivedEmailAttachment[];
126
+ text_body: string | null;
127
+ html_body: string | null;
128
+ auto_submitted: string | null;
129
+ received_at: string;
130
+ created_at: string;
131
+ };
132
+ type ListReceivedEmailsParams = {
133
+ limit?: number;
134
+ cursor?: string;
135
+ domain?: string;
136
+ };
137
+ type ListReceivedEmailsResult = {
138
+ received_emails: ReceivedEmail[];
139
+ has_more: boolean;
140
+ next_cursor: string | null;
141
+ };
142
+ type ListEmailsParams = {
143
+ limit?: number;
144
+ cursor?: string;
145
+ };
146
+ type ListEmailsResult = {
147
+ emails: EmailListItem[];
148
+ has_more: boolean;
149
+ next_cursor: string | null;
150
+ };
151
+ type DeliverabilityWindow = '7d' | '30d';
152
+ type DeliverabilityBucket = {
153
+ total_emails: number;
154
+ attempted: number;
155
+ sent: number;
156
+ delivered: number;
157
+ bounced: number;
158
+ complained: number;
159
+ failed: number;
160
+ suppressed: number;
161
+ scheduled: number;
162
+ opened: number;
163
+ clicked: number;
164
+ bounce_rate: number;
165
+ complaint_rate: number;
166
+ delivery_rate: number;
167
+ open_rate: number;
168
+ click_rate: number;
169
+ };
170
+ type DeliverabilityMailServerRelay = {
171
+ window_days: number;
172
+ total_messages: number;
173
+ sent: number;
174
+ bounced: number;
175
+ failed: number;
176
+ delayed: number;
177
+ };
178
+ type DeliverabilityDomainInsight = DeliverabilityBucket & {
179
+ domain: string;
180
+ mail_server_relay?: DeliverabilityMailServerRelay;
181
+ };
182
+ type DeliverabilityInsightsResult = {
183
+ window: DeliverabilityWindow;
184
+ window_start: string;
185
+ generated_at: string;
186
+ summary: DeliverabilityBucket;
187
+ by_domain: DeliverabilityDomainInsight[];
188
+ top_bounce_reasons: Array<{
189
+ reason: string;
190
+ count: number;
191
+ }>;
192
+ notes: string[];
193
+ };
194
+ type ApiKeyScope = 'full' | 'sending';
195
+ type ApiKey = {
196
+ id: string;
197
+ name: string;
198
+ scope: ApiKeyScope;
199
+ prefix: string;
200
+ created_at: string;
201
+ last_used_at: string | null;
202
+ };
203
+ type ListApiKeysParams = {
204
+ limit?: number;
205
+ cursor?: string;
206
+ };
207
+ type ListApiKeysResult = {
208
+ data: ApiKey[];
209
+ has_more: boolean;
210
+ next_cursor: string | null;
211
+ };
212
+ type CreateApiKeyParams = {
213
+ name?: string;
214
+ scope?: ApiKeyScope;
215
+ };
216
+ type CreateApiKeyResult = {
217
+ id: string;
218
+ name: string;
219
+ scope: ApiKeyScope;
220
+ prefix: string;
221
+ token: string;
222
+ created_at: string;
223
+ };
224
+ type SmtpCredential = {
225
+ id: string;
226
+ name: string;
227
+ password_prefix: string;
228
+ username: string;
229
+ host: string;
230
+ port: number;
231
+ last_used_at: string | null;
232
+ revoked_at: string | null;
233
+ created_at: string;
234
+ };
235
+ type ListSmtpCredentialsParams = {
236
+ limit?: number;
237
+ cursor?: string;
238
+ };
239
+ type ListSmtpCredentialsResult = {
240
+ data: SmtpCredential[];
241
+ has_more: boolean;
242
+ next_cursor: string | null;
243
+ };
244
+ type CreateSmtpCredentialParams = {
245
+ name?: string;
246
+ };
247
+ type CreateSmtpCredentialResult = SmtpCredential & {
248
+ password: string;
249
+ };
250
+ type WebhookEventType = 'email.received' | 'email.sent' | 'email.delivered' | 'email.delivery_delayed' | 'email.bounced' | 'email.complained' | 'email.opened' | 'email.clicked' | 'email.failed' | 'email.suppressed' | 'email.scheduled' | 'contact.unsubscribed' | 'automation.started' | 'automation.step_completed' | 'automation.completed' | 'automation.failed';
251
+ /** `contact.unsubscribed` webhook payload (`scope` distinguishes global vs category opt-out). */
252
+ type ContactWebhookEventPayload = {
253
+ type: 'contact.unsubscribed';
254
+ created_at: string;
255
+ data: {
256
+ email: string;
257
+ source: 'unsubscribe';
258
+ scope: 'all' | 'category';
259
+ category?: 'product' | 'newsletter' | null;
260
+ category_label?: string | null;
261
+ suppression_id?: string | null;
262
+ category_opt_out_id?: string | null;
263
+ email_id?: string | null;
264
+ };
265
+ };
266
+ /** `details` on `POST /emails` 422 when recipients opted out of a category. */
267
+ type CategoryUnsubscribedErrorDetails = {
268
+ category_unsubscribed: string[];
269
+ category: 'product' | 'newsletter' | string;
270
+ email_id: string;
271
+ };
272
+ /** `details` on `POST /emails` 422 when recipients are globally suppressed. */
273
+ type SuppressedErrorDetails = {
274
+ suppressed: string[];
275
+ email_id: string;
276
+ };
277
+ /** Event types accepted by `POST /emails/test`. */
278
+ type EmailWebhookEventType = 'email.received' | 'email.sent' | 'email.delivered' | 'email.delivery_delayed' | 'email.bounced' | 'email.complained' | 'email.opened' | 'email.clicked' | 'email.failed' | 'email.suppressed' | 'email.scheduled';
279
+ type TestEmailWebhookParams = {
280
+ event: EmailWebhookEventType;
281
+ email_id?: string;
282
+ webhook_id?: string;
283
+ /** When true, deliver synchronously and return per-endpoint results. */
284
+ sync?: boolean;
285
+ /** When true (default), enqueue delivery to account webhooks. */
286
+ deliver?: boolean;
287
+ };
288
+ type WebhookTestDelivery = {
289
+ endpoint_id: string;
290
+ url: string;
291
+ success: boolean;
292
+ status?: number;
293
+ error?: string;
294
+ };
295
+ type TestEmailWebhookResult = {
296
+ ok: boolean;
297
+ payload: unknown;
298
+ delivered: boolean;
299
+ deliveries: WebhookTestDelivery[];
300
+ };
301
+ type TriggerEventParams = {
302
+ name?: string;
303
+ type?: string;
304
+ user_id?: string;
305
+ userId?: string;
306
+ email?: string;
307
+ data?: Record<string, unknown>;
308
+ idempotencyKey?: string;
309
+ };
310
+ type EventRecord = {
311
+ id: string;
312
+ name: string;
313
+ user_id: string | null;
314
+ email: string | null;
315
+ data: Record<string, unknown>;
316
+ source: string;
317
+ created_at: string;
318
+ };
319
+ type TriggerEventResult = {
320
+ event: EventRecord;
321
+ matched_automations: number;
322
+ resumed_runs: number;
323
+ cancelled_runs: number;
324
+ };
325
+ type AutomationStatus = 'draft' | 'active' | 'paused';
326
+ type AutomationTrigger = {
327
+ type: 'event';
328
+ event: string;
329
+ cancel_on_events?: string[];
330
+ };
331
+ type AutomationStep = {
332
+ type: 'delay' | 'send_email' | 'send_sms' | 'condition' | 'wait_for_event';
333
+ [key: string]: unknown;
334
+ };
335
+ type TwilioIntegrationStatus = {
336
+ connected: boolean;
337
+ hint: string | null;
338
+ connectedAt: string | null;
339
+ defaultFrom: string | null;
340
+ messagingServiceSid: string | null;
341
+ };
342
+ type TwilioIntegrationResponse = {
343
+ twilio: TwilioIntegrationStatus;
344
+ };
345
+ type ConnectTwilioParams = {
346
+ accountSid: string;
347
+ authToken: string;
348
+ defaultFrom?: string;
349
+ messagingServiceSid?: string;
350
+ };
351
+ type Automation = {
352
+ id: string;
353
+ name: string;
354
+ status: AutomationStatus;
355
+ trigger: AutomationTrigger;
356
+ steps: AutomationStep[];
357
+ created_at: string;
358
+ updated_at: string;
359
+ };
360
+ type CreateAutomationParams = {
361
+ name: string;
362
+ trigger: AutomationTrigger;
363
+ steps: AutomationStep[];
364
+ };
365
+ type UpdateAutomationParams = {
366
+ name?: string;
367
+ trigger?: AutomationTrigger;
368
+ steps?: AutomationStep[];
369
+ };
370
+ type ListAutomationsResult = {
371
+ automations: Automation[];
372
+ };
373
+ type AutomationRunStatus = 'queued' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled';
374
+ type AutomationRunStepStatus = 'started' | 'waiting' | 'completed' | 'failed';
375
+ type AutomationRunStep = {
376
+ id: string;
377
+ step_index: number;
378
+ step_type: AutomationStep['type'] | string;
379
+ status: AutomationRunStepStatus | string;
380
+ output: unknown;
381
+ error: string | null;
382
+ started_at: string;
383
+ completed_at: string | null;
384
+ created_at: string;
385
+ updated_at: string;
386
+ };
387
+ type AutomationRun = {
388
+ id: string;
389
+ automation_id: string;
390
+ trigger_event_id: string | null;
391
+ status: AutomationRunStatus | string;
392
+ current_step: number;
393
+ waiting_for_event: string | null;
394
+ wait_timeout_at: string | null;
395
+ context: Record<string, unknown>;
396
+ last_error: string | null;
397
+ cancel_requested_at: string | null;
398
+ started_at: string | null;
399
+ completed_at: string | null;
400
+ created_at: string;
401
+ updated_at: string;
402
+ automation?: Automation;
403
+ trigger_event?: EventRecord;
404
+ steps?: AutomationRunStep[];
405
+ };
406
+ type AutomationRunResponse = {
407
+ run: AutomationRun;
408
+ };
409
+ type ListAutomationRunsParams = {
410
+ automation_id?: string;
411
+ };
412
+ type ListAutomationRunsResult = {
413
+ runs: AutomationRun[];
414
+ };
415
+ type WebhookEndpoint = {
416
+ id: string;
417
+ url: string;
418
+ events: string[];
419
+ enabled: boolean;
420
+ created_at: string;
421
+ updated_at: string;
422
+ };
423
+ type CreateWebhookParams = {
424
+ url: string;
425
+ events?: WebhookEventType[];
426
+ };
427
+ type UpdateWebhookParams = {
428
+ url?: string;
429
+ events?: WebhookEventType[];
430
+ enabled?: boolean;
431
+ };
432
+ type WebhookEndpointWithSecret = {
433
+ webhook: WebhookEndpoint;
434
+ secret: string;
435
+ };
436
+ type Suppression = {
437
+ id: string;
438
+ email: string;
439
+ reason: string | null;
440
+ source: string;
441
+ created_at: string;
442
+ updated_at: string;
443
+ };
444
+ type ListSuppressionsParams = {
445
+ limit?: number;
446
+ cursor?: string;
447
+ email?: string;
448
+ };
449
+ type ListSuppressionsResult = {
450
+ data: Suppression[];
451
+ has_more: boolean;
452
+ next_cursor: string | null;
453
+ };
454
+ type CreateSuppressionParams = {
455
+ email: string;
456
+ reason?: string;
457
+ };
458
+ type TemplateStatus = 'draft' | 'published';
459
+ type TemplateFormat = 'html' | 'blocks';
460
+ type TemplateLintWarning = {
461
+ code: 'svg_image' | 'relative_image_url' | 'data_uri_image' | 'missing_alt' | 'non_https_image' | 'empty_href' | 'raw_html_block' | 'low_contrast' | 'html_too_large';
462
+ message: string;
463
+ detail?: string;
464
+ };
465
+ type Template = {
466
+ id: string;
467
+ name: string;
468
+ alias: string | null;
469
+ status: TemplateStatus | string;
470
+ format: TemplateFormat | string;
471
+ subject: string;
472
+ preheader: string | null;
473
+ html: string | null;
474
+ text: string | null;
475
+ design: Record<string, unknown> | null;
476
+ variables: string[] | null;
477
+ unsubscribe_enabled: boolean;
478
+ category: 'transactional' | 'product' | 'newsletter' | string;
479
+ published_version_id: string | null;
480
+ published_at: string | null;
481
+ created_at: string;
482
+ updated_at: string;
483
+ warnings?: TemplateLintWarning[];
484
+ };
485
+ type TemplateVersion = {
486
+ id: string;
487
+ template_id: string;
488
+ version: number;
489
+ format: 'html' | 'blocks';
490
+ subject: string;
491
+ preheader: string | null;
492
+ design: Record<string, unknown> | null;
493
+ html: string | null;
494
+ text: string | null;
495
+ variables: string[] | null;
496
+ created_by_user_id: string | null;
497
+ label: string | null;
498
+ created_at: string;
499
+ };
500
+ type Asset = {
501
+ id: string;
502
+ key: string;
503
+ url: string;
504
+ content_type: string;
505
+ bytes: number;
506
+ width: number | null;
507
+ height: number | null;
508
+ created_at: string;
509
+ };
510
+ type ListTemplatesParams = {
511
+ limit?: number;
512
+ cursor?: string;
513
+ status?: TemplateStatus;
514
+ };
515
+ type ListTemplatesResult = {
516
+ data: Template[];
517
+ has_more: boolean;
518
+ next_cursor: string | null;
519
+ };
520
+ type CreateTemplateParams = {
521
+ name: string;
522
+ subject: string;
523
+ format?: TemplateFormat;
524
+ preheader?: string;
525
+ html?: string;
526
+ text?: string;
527
+ design?: Record<string, unknown>;
528
+ alias?: string;
529
+ variables?: string[];
530
+ unsubscribe_enabled?: boolean;
531
+ category?: 'transactional' | 'product' | 'newsletter';
532
+ };
533
+ type TemplateStarter = {
534
+ alias: string;
535
+ name: string;
536
+ description: string;
537
+ subject: string;
538
+ preheader?: string | null;
539
+ html: string;
540
+ text: string;
541
+ design?: Record<string, unknown> | null;
542
+ variables: string[];
543
+ unsubscribe_enabled: boolean;
544
+ };
545
+ type UpdateTemplateParams = {
546
+ name?: string;
547
+ subject?: string;
548
+ format?: TemplateFormat;
549
+ preheader?: string | null;
550
+ html?: string | null;
551
+ text?: string | null;
552
+ design?: Record<string, unknown> | null;
553
+ alias?: string | null;
554
+ variables?: string[] | null;
555
+ unsubscribe_enabled?: boolean;
556
+ category?: 'transactional' | 'product' | 'newsletter' | null;
557
+ };
558
+ type GroundmailOptions = {
559
+ baseUrl?: string;
560
+ fetch?: typeof fetch;
561
+ };
562
+ type DomainStatus = 'pending' | 'verified' | 'failed';
563
+ type DomainTlsMode = 'opportunistic' | 'enforced';
564
+ type DomainDmarcAnalysis = {
565
+ host: string;
566
+ configured: boolean;
567
+ record: string | null;
568
+ policy: string | null;
569
+ rua: string[];
570
+ guidance: string;
571
+ };
572
+ type DomainBimiAnalysis = {
573
+ host: string;
574
+ configured: boolean;
575
+ record: string | null;
576
+ location: string | null;
577
+ authority: string | null;
578
+ requires_dmarc_enforcement: boolean;
579
+ guidance: string;
580
+ };
581
+ type DomainDnsAnalysis = {
582
+ dmarc: DomainDmarcAnalysis;
583
+ bimi: DomainBimiAnalysis;
584
+ };
585
+ type DomainTrackingDns = {
586
+ required: boolean;
587
+ host: string | null;
588
+ target: string | null;
589
+ ok: boolean | null;
590
+ };
591
+ type Domain = {
592
+ id: string;
593
+ name: string;
594
+ status: DomainStatus | string;
595
+ created_at: string;
596
+ verified_at: string | null;
597
+ open_tracking: boolean;
598
+ click_tracking: boolean;
599
+ tls_mode: DomainTlsMode | string;
600
+ inbound_enabled: boolean;
601
+ inbound_status: 'disabled' | 'pending' | 'active' | 'error' | string;
602
+ inbound_error: string | null;
603
+ };
604
+ type DnsRecord = {
605
+ type: string;
606
+ host: string;
607
+ value: string;
608
+ purpose: string;
609
+ /** MX preference when `type` is `MX`. Mail hostname is in `value`. */
610
+ priority?: number;
611
+ };
612
+ type CreateDomainParams = {
613
+ name: string;
614
+ inbound_enabled?: boolean;
615
+ inboundEnabled?: boolean;
616
+ };
617
+ type ListDomainsParams = {
618
+ limit?: number;
619
+ cursor?: string;
620
+ inbound_enabled?: boolean;
621
+ inboundEnabled?: boolean;
622
+ };
623
+ type ListDomainsResult = {
624
+ domains: Domain[];
625
+ has_more: boolean;
626
+ next_cursor: string | null;
627
+ };
628
+ type CreateDomainResult = {
629
+ domain: Domain;
630
+ records: DnsRecord[];
631
+ inbound_records: DnsRecord[];
632
+ inbound_note: string;
633
+ mail_server_dns_synced?: boolean;
634
+ mail_server_dns_error?: string;
635
+ };
636
+ type DomainDetailResult = {
637
+ domain: Domain;
638
+ records: DnsRecord[];
639
+ analysis: DomainDnsAnalysis;
640
+ inbound_records: DnsRecord[];
641
+ inbound_note: string;
642
+ inbound_configured?: boolean;
643
+ inbound_pending?: boolean;
644
+ inbound_error?: string | null;
645
+ tracking_dns?: DomainTrackingDns;
646
+ tracking_error?: string | null;
647
+ tls_error?: string | null;
648
+ };
649
+ type MailServerSigningStatus = {
650
+ dkim_ok?: boolean;
651
+ return_path_ok?: boolean;
652
+ dkim_status?: string | null;
653
+ return_path_status?: string | null;
654
+ };
655
+ type VerifyDomainResult = {
656
+ domain: Domain;
657
+ records: DnsRecord[];
658
+ analysis?: DomainDnsAnalysis;
659
+ inbound_records?: DnsRecord[];
660
+ inbound_note?: string;
661
+ verified: boolean;
662
+ checks?: {
663
+ ownership: boolean;
664
+ spf: boolean;
665
+ dkim: boolean;
666
+ dmarc: boolean;
667
+ };
668
+ auto?: boolean;
669
+ inbound_configured?: boolean;
670
+ inbound_pending?: boolean;
671
+ inbound_error?: string | null;
672
+ signing_ready?: boolean;
673
+ mail_server_signing?: MailServerSigningStatus;
674
+ };
675
+ type UpdateDomainParams = {
676
+ open_tracking?: boolean;
677
+ openTracking?: boolean;
678
+ click_tracking?: boolean;
679
+ clickTracking?: boolean;
680
+ tls_mode?: DomainTlsMode;
681
+ tlsMode?: DomainTlsMode;
682
+ inbound_enabled?: boolean;
683
+ inboundEnabled?: boolean;
684
+ };
685
+ type DnsProviderName = 'cloudflare' | 'godaddy' | 'vercel';
686
+ type RemoteApplyDnsCredentials = {
687
+ /** Inline Cloudflare token instead of the stored dashboard integration. */
688
+ apiToken?: string;
689
+ zoneId?: string;
690
+ cloudflareApiToken?: string;
691
+ cloudflareZoneId?: string;
692
+ /** GoDaddy one-time credentials. */
693
+ apiKey?: string;
694
+ apiSecret?: string;
695
+ godaddyApiKey?: string;
696
+ godaddyApiSecret?: string;
697
+ vercelApiToken?: string;
698
+ vercelTeamId?: string;
699
+ };
700
+ type ApplyDnsParams = {
701
+ provider: DnsProviderName;
702
+ /** Domain id or name (fetched from Groundmail for DNS records). */
703
+ idOrName: string;
704
+ cloudflareApiToken?: string;
705
+ cloudflareZoneId?: string;
706
+ godaddyApiKey?: string;
707
+ godaddyApiSecret?: string;
708
+ vercelApiToken?: string;
709
+ vercelTeamId?: string;
710
+ };
711
+ type ApplyDnsRecordResult = {
712
+ purpose: string;
713
+ host: string;
714
+ action: 'created' | 'updated' | 'unchanged' | 'merged';
715
+ detail?: string;
716
+ };
717
+ type ApplyDnsResult = {
718
+ provider: DnsProviderName;
719
+ domain: string;
720
+ results: ApplyDnsRecordResult[];
721
+ };
722
+ type ApiErrorBody = {
723
+ error?: string | {
724
+ message?: string;
725
+ details?: unknown;
726
+ code?: string;
727
+ upgrade_url?: string;
728
+ };
729
+ };
730
+
731
+ declare class AutomationsResource {
732
+ private readonly client;
733
+ constructor(client: Groundmail);
734
+ list(): Promise<ListAutomationsResult>;
735
+ get(id: string): Promise<{
736
+ automation: Automation;
737
+ }>;
738
+ create(params: CreateAutomationParams): Promise<{
739
+ automation: Automation;
740
+ }>;
741
+ update(id: string, params: UpdateAutomationParams): Promise<{
742
+ automation: Automation;
743
+ }>;
744
+ remove(id: string): Promise<{
745
+ ok: boolean;
746
+ }>;
747
+ activate(id: string): Promise<{
748
+ automation: Automation;
749
+ }>;
750
+ pause(id: string): Promise<{
751
+ automation: Automation;
752
+ }>;
753
+ listRuns(params?: ListAutomationRunsParams): Promise<ListAutomationRunsResult>;
754
+ getRun(id: string): Promise<AutomationRunResponse>;
755
+ cancelRun(id: string): Promise<AutomationRunResponse>;
756
+ retryRun(id: string): Promise<AutomationRunResponse>;
757
+ }
758
+
759
+ declare class DomainsResource {
760
+ private readonly client;
761
+ constructor(client: Groundmail);
762
+ list(params?: ListDomainsParams): Promise<ListDomainsResult>;
763
+ get(idOrName: string): Promise<DomainDetailResult>;
764
+ create(params: CreateDomainParams): Promise<CreateDomainResult>;
765
+ verify(idOrName: string): Promise<VerifyDomainResult>;
766
+ update(idOrName: string, params: UpdateDomainParams): Promise<DomainDetailResult>;
767
+ delete(idOrName: string): Promise<{
768
+ ok: boolean;
769
+ }>;
770
+ /**
771
+ * Apply DNS using the public API. Cloudflare, Vercel, and GoDaddy can use stored dashboard
772
+ * credentials; GoDaddy also accepts one-time credentials on the request.
773
+ */
774
+ apply(idOrName: string, options?: {
775
+ provider?: 'cloudflare' | 'godaddy' | 'vercel';
776
+ credentials?: RemoteApplyDnsCredentials;
777
+ }): Promise<ApplyDnsResult>;
778
+ /**
779
+ * Fetch Groundmail DNS records, then write them at Cloudflare, Vercel, or GoDaddy
780
+ * using the caller's provider credentials (never sent to Groundmail).
781
+ */
782
+ applyDns(params: ApplyDnsParams): Promise<ApplyDnsResult>;
783
+ }
784
+
785
+ declare class EmailsResource {
786
+ private readonly client;
787
+ constructor(client: Groundmail);
788
+ list(params?: ListEmailsParams): Promise<ListEmailsResult>;
789
+ get(id: string): Promise<{
790
+ email: EmailListItem;
791
+ }>;
792
+ insights(window?: DeliverabilityWindow): Promise<DeliverabilityInsightsResult>;
793
+ send(params: SendEmailParams): Promise<SendEmailResult>;
794
+ batch(emails: SendEmailParams[]): Promise<BatchSendEmailResult>;
795
+ update(id: string, params: UpdateEmailParams): Promise<SendEmailResult>;
796
+ cancel(id: string): Promise<SendEmailResult>;
797
+ /** Create a new send from a previously stored email (new `msg_…` id). */
798
+ resend(id: string): Promise<SendEmailResult>;
799
+ /** Simulate a webhook event for CI / local testing (`POST /emails/test`). */
800
+ testWebhook(params: TestEmailWebhookParams): Promise<TestEmailWebhookResult>;
801
+ private serializeSendParams;
802
+ }
803
+
804
+ declare class EventsResource {
805
+ private readonly client;
806
+ constructor(client: Groundmail);
807
+ trigger(params: TriggerEventParams): Promise<TriggerEventResult>;
808
+ }
809
+
810
+ declare class IntegrationsResource {
811
+ private readonly client;
812
+ constructor(client: Groundmail);
813
+ getTwilio(): Promise<TwilioIntegrationResponse>;
814
+ connectTwilio(params: ConnectTwilioParams): Promise<TwilioIntegrationResponse>;
815
+ disconnectTwilio(): Promise<TwilioIntegrationResponse>;
816
+ }
817
+
818
+ declare class KeysResource {
819
+ private readonly client;
820
+ constructor(client: Groundmail);
821
+ list(params?: ListApiKeysParams): Promise<ListApiKeysResult>;
822
+ create(params?: CreateApiKeyParams): Promise<CreateApiKeyResult>;
823
+ remove(id: string): Promise<{
824
+ ok: boolean;
825
+ }>;
826
+ }
827
+
828
+ declare class SmtpCredentialsResource {
829
+ private readonly client;
830
+ constructor(client: Groundmail);
831
+ list(params?: ListSmtpCredentialsParams): Promise<ListSmtpCredentialsResult>;
832
+ create(params?: CreateSmtpCredentialParams): Promise<CreateSmtpCredentialResult>;
833
+ remove(id: string): Promise<{
834
+ ok: boolean;
835
+ }>;
836
+ }
837
+
838
+ declare class ReceivedEmailsResource {
839
+ private readonly client;
840
+ constructor(client: Groundmail);
841
+ list(params?: ListReceivedEmailsParams): Promise<ListReceivedEmailsResult>;
842
+ get(id: string): Promise<{
843
+ received_email: ReceivedEmail;
844
+ }>;
845
+ }
846
+
847
+ declare class SuppressionsResource {
848
+ private readonly client;
849
+ constructor(client: Groundmail);
850
+ list(params?: ListSuppressionsParams): Promise<ListSuppressionsResult>;
851
+ create(params: CreateSuppressionParams): Promise<{
852
+ suppression: Suppression;
853
+ }>;
854
+ /** Remove by suppression id or email address. */
855
+ remove(idOrEmail: string): Promise<{
856
+ ok: boolean;
857
+ }>;
858
+ }
859
+
860
+ declare class TemplatesResource {
861
+ private readonly client;
862
+ constructor(client: Groundmail);
863
+ list(params?: ListTemplatesParams): Promise<ListTemplatesResult>;
864
+ get(idOrAlias: string): Promise<{
865
+ template: Template;
866
+ }>;
867
+ create(params: CreateTemplateParams): Promise<{
868
+ template: Template;
869
+ }>;
870
+ update(idOrAlias: string, params: UpdateTemplateParams): Promise<{
871
+ template: Template;
872
+ }>;
873
+ remove(idOrAlias: string): Promise<{
874
+ ok: boolean;
875
+ }>;
876
+ publish(idOrAlias: string): Promise<{
877
+ template: Template;
878
+ }>;
879
+ duplicate(idOrAlias: string, params?: {
880
+ name?: string;
881
+ }): Promise<{
882
+ template: Template;
883
+ }>;
884
+ listStarters(): Promise<{
885
+ data: TemplateStarter[];
886
+ }>;
887
+ fromStarter(alias: string): Promise<{
888
+ template: Template;
889
+ }>;
890
+ listVersions(idOrAlias: string): Promise<{
891
+ data: TemplateVersion[];
892
+ published_version_id: string | null;
893
+ }>;
894
+ restoreVersion(idOrAlias: string, version: number): Promise<{
895
+ template: Template;
896
+ }>;
897
+ testSend(idOrAlias: string, params: {
898
+ to: string;
899
+ from: string;
900
+ variables?: Record<string, unknown>;
901
+ }): Promise<unknown>;
902
+ }
903
+
904
+ declare class WebhooksResource {
905
+ private readonly client;
906
+ constructor(client: Groundmail);
907
+ list(params?: {
908
+ limit?: number;
909
+ cursor?: string;
910
+ }): Promise<{
911
+ webhooks: WebhookEndpoint[];
912
+ has_more: boolean;
913
+ next_cursor: string | null;
914
+ }>;
915
+ get(id: string): Promise<{
916
+ webhook: WebhookEndpoint;
917
+ }>;
918
+ create(params: CreateWebhookParams): Promise<WebhookEndpointWithSecret>;
919
+ update(id: string, params: UpdateWebhookParams): Promise<{
920
+ webhook: WebhookEndpoint;
921
+ }>;
922
+ delete(id: string): Promise<{
923
+ ok: boolean;
924
+ }>;
925
+ /** Verify an incoming webhook signature (same as `verifyWebhookSignature`). */
926
+ verify(secret: string, payload: string, header: string | null | undefined, toleranceSec?: number): boolean;
927
+ }
928
+
929
+ declare const DEFAULT_API_BASE_URL = "https://api.groundmail.dev";
930
+ declare class Groundmail {
931
+ private readonly apiKey;
932
+ private readonly options;
933
+ readonly domains: DomainsResource;
934
+ readonly emails: EmailsResource;
935
+ readonly receivedEmails: ReceivedEmailsResource;
936
+ readonly events: EventsResource;
937
+ readonly automations: AutomationsResource;
938
+ readonly webhooks: WebhooksResource;
939
+ readonly integrations: IntegrationsResource;
940
+ readonly apiKeys: KeysResource;
941
+ readonly smtpCredentials: SmtpCredentialsResource;
942
+ readonly suppressions: SuppressionsResource;
943
+ readonly templates: TemplatesResource;
944
+ constructor(apiKey: string, options?: GroundmailOptions);
945
+ get baseUrl(): string;
946
+ get fetchImpl(): typeof fetch;
947
+ request<T>(path: string, init: RequestInit): Promise<T>;
948
+ }
949
+
950
+ export { type ListAutomationRunsParams as $, type ApiErrorBody as A, type BatchSendEmailResult as B, type CategoryUnsubscribedErrorDetails as C, type DnsRecord as D, DEFAULT_API_BASE_URL as E, type DeliverabilityBucket as F, Groundmail as G, type DeliverabilityDomainInsight as H, type DeliverabilityInsightsResult as I, type DeliverabilityMailServerRelay as J, type DeliverabilityWindow as K, type DnsProviderName as L, type Domain as M, type DomainBimiAnalysis as N, type DomainDetailResult as O, type DomainDmarcAnalysis as P, type DomainDnsAnalysis as Q, type DomainStatus as R, type SendEmailResult as S, type DomainTlsMode as T, type DomainTrackingDns as U, type EmailListItem as V, type EmailWebhookEventType as W, type EventRecord as X, type GroundmailOptions as Y, type ListApiKeysParams as Z, type ListApiKeysResult as _, type ApiErrorCode as a, type ListAutomationRunsResult as a0, type ListAutomationsResult as a1, type ListDomainsParams as a2, type ListDomainsResult as a3, type ListEmailsParams as a4, type ListEmailsResult as a5, type ListReceivedEmailsParams as a6, type ListReceivedEmailsResult as a7, type ListSuppressionsParams as a8, type ListSuppressionsResult as a9, type UpdateWebhookParams as aA, type VerifyDomainResult as aB, type WebhookEndpoint as aC, type WebhookEndpointWithSecret as aD, type WebhookEventType as aE, type ListTemplatesParams as aa, type ListTemplatesResult as ab, type MailServerSigningStatus as ac, type ReceivedEmail as ad, type ReceivedEmailAttachment as ae, type ReceivedEmailAttachmentMeta as af, type RemoteApplyDnsCredentials as ag, type SendEmailParams as ah, type SuppressedErrorDetails as ai, type Suppression as aj, type Template as ak, type TemplateFormat as al, type TemplateLintWarning as am, type TemplateStarter as an, type TemplateStatus as ao, type TemplateVersion as ap, type TestEmailWebhookParams as aq, type TestEmailWebhookResult as ar, type TriggerEventParams as as, type TriggerEventResult as at, type TwilioIntegrationResponse as au, type TwilioIntegrationStatus as av, type UpdateAutomationParams as aw, type UpdateDomainParams as ax, type UpdateEmailParams as ay, type UpdateTemplateParams as az, type ApiKey as b, type ApiKeyScope as c, type ApplyDnsParams as d, type ApplyDnsRecordResult as e, type ApplyDnsResult as f, type Asset as g, type Automation as h, type AutomationRun as i, type AutomationRunResponse as j, type AutomationRunStatus as k, type AutomationRunStep as l, type AutomationRunStepStatus as m, type AutomationStatus as n, type AutomationStep as o, type AutomationTrigger as p, type ConnectTwilioParams as q, type ContactWebhookEventPayload as r, type CreateApiKeyParams as s, type CreateApiKeyResult as t, type CreateAutomationParams as u, type CreateDomainParams as v, type CreateDomainResult as w, type CreateSuppressionParams as x, type CreateTemplateParams as y, type CreateWebhookParams as z };