zupost 0.2.0 → 0.6.0

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.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Options } from '@react-email/render';
2
2
  import { ReactNode } from 'react';
3
3
 
4
- type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
4
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
5
5
  /**
6
6
  * @internal
7
7
  * Internal HTTP client for the Zupost API. Not part of the public API surface.
@@ -12,6 +12,8 @@ declare class HttpClient {
12
12
  request<T = unknown>(path: string, method: HttpMethod, body?: unknown): Promise<T>;
13
13
  get<T = unknown>(path: string): Promise<T>;
14
14
  post<T = unknown>(path: string, body: unknown): Promise<T>;
15
+ patch<T = unknown>(path: string, body: unknown): Promise<T>;
16
+ delete<T = unknown>(path: string, body?: unknown): Promise<T>;
15
17
  }
16
18
 
17
19
  /**
@@ -219,6 +221,580 @@ declare class Campaigns {
219
221
  send(options: SendCampaignOptions): Promise<SendCampaignResponse>;
220
222
  }
221
223
 
224
+ type ContactEventType = 'CONTACT_CREATED' | 'CONTACT_UPDATED' | 'EMAIL_SENT' | 'EMAIL_DELIVERED' | 'EMAIL_OPENED' | 'EMAIL_CLICKED' | 'EMAIL_BOUNCED' | 'EMAIL_COMPLAINED' | 'EMAIL_FAILED' | 'SUBSCRIBED' | 'UNSUBSCRIBED' | 'MARKETING_CONSENT_GIVEN' | 'MARKETING_CONSENT_WITHDRAWN' | 'TRACKING_CONSENT_GIVEN' | 'TRACKING_CONSENT_WITHDRAWN' | 'REPLY_RECEIVED' | 'SEQUENCE_ENTERED' | 'SEQUENCE_EXITED' | 'SEQUENCE_STEP_COMPLETED' | 'TAG_ADDED' | 'TAG_REMOVED' | 'FORGOTTEN';
225
+ type EmailRecipientType = 'TO' | 'CC' | 'BCC';
226
+ interface ContactTag {
227
+ name: string;
228
+ createdAt: string;
229
+ }
230
+ interface Contact {
231
+ id: string;
232
+ email: string;
233
+ name: string | null;
234
+ firstSeenAt: string;
235
+ firstSeenSource: string;
236
+ metadata?: unknown;
237
+ marketingConsent: boolean;
238
+ marketingConsentAt?: string | null;
239
+ marketingConsentSource?: string | null;
240
+ trackingConsent: boolean;
241
+ trackingConsentAt?: string | null;
242
+ birthday?: string | null;
243
+ createdAt: string;
244
+ updatedAt: string;
245
+ tags: ContactTag[];
246
+ }
247
+ interface ContactEvent {
248
+ id: string;
249
+ type: ContactEventType;
250
+ payload?: unknown;
251
+ emailId?: string | null;
252
+ sequenceRunId?: string | null;
253
+ source: string;
254
+ createdAt: string;
255
+ }
256
+ interface CreateContactOptions {
257
+ email: string;
258
+ name?: string;
259
+ metadata?: Record<string, unknown>;
260
+ marketingConsent?: boolean;
261
+ marketingConsentSource?: string;
262
+ trackingConsent?: boolean;
263
+ tags?: string[];
264
+ }
265
+ interface UpdateContactOptions {
266
+ name?: string | null;
267
+ metadata?: Record<string, unknown> | null;
268
+ birthday?: string | null;
269
+ marketingConsent?: boolean;
270
+ marketingConsentSource?: string | null;
271
+ trackingConsent?: boolean;
272
+ }
273
+ interface ListContactsOptions {
274
+ skip?: number;
275
+ take?: number;
276
+ search?: string;
277
+ marketingConsent?: boolean;
278
+ tag?: string;
279
+ }
280
+ interface ListContactsResponse {
281
+ items: Contact[];
282
+ total: number;
283
+ skip: number;
284
+ take: number;
285
+ }
286
+ interface ListEventsOptions {
287
+ skip?: number;
288
+ take?: number;
289
+ type?: ContactEventType | ContactEventType[];
290
+ }
291
+ interface ListEventsResponse {
292
+ items: ContactEvent[];
293
+ total: number;
294
+ skip: number;
295
+ take: number;
296
+ }
297
+ interface ContactExport {
298
+ contact: Contact;
299
+ subscriptions: Array<{
300
+ id: string;
301
+ status: string;
302
+ source: string;
303
+ createdAt: string;
304
+ unsubscribedAt: string | null;
305
+ audiences: Array<{
306
+ id: string;
307
+ name: string;
308
+ }>;
309
+ }>;
310
+ tags: ContactTag[];
311
+ emails: Array<{
312
+ emailId: string;
313
+ subject: string | null;
314
+ from: string;
315
+ usageType: 'TRANSACTIONAL' | 'MARKETING';
316
+ latestStatus: string;
317
+ recipientType: EmailRecipientType;
318
+ sentAt: string;
319
+ }>;
320
+ timeline: ContactEvent[];
321
+ exportedAt: string;
322
+ }
323
+ interface ForgetContactResponse {
324
+ id: string;
325
+ forgottenAt: string;
326
+ }
327
+
328
+ /**
329
+ * Contacts API.
330
+ *
331
+ * A Contact is every email address Zupost has ever seen, with a chronological
332
+ * event timeline, consent state (marketing and tracking), tags and GDPR
333
+ * primitives (data export, right to be forgotten).
334
+ *
335
+ * Marketing emails require `marketingConsent: true` and an audience membership
336
+ * (Subscriber). Transactional emails do not require consent and can be sent
337
+ * to any contact or even an ad-hoc address.
338
+ */
339
+ declare class Contacts {
340
+ private readonly http;
341
+ constructor(http: HttpClient);
342
+ /**
343
+ * Create or upsert a contact by email. Idempotent on (project, email).
344
+ *
345
+ * @example
346
+ * ```typescript
347
+ * const contact = await zupost.contacts.create({
348
+ * email: 'user@example.com',
349
+ * name: 'Jane Doe',
350
+ * marketingConsent: true,
351
+ * marketingConsentSource: 'signup-form',
352
+ * tags: ['vip', 'beta'],
353
+ * });
354
+ * ```
355
+ */
356
+ create(options: CreateContactOptions): Promise<Contact>;
357
+ /**
358
+ * Get a contact by ID.
359
+ */
360
+ get(id: string): Promise<Contact>;
361
+ /**
362
+ * List contacts with optional search, consent and tag filters.
363
+ */
364
+ list(options?: ListContactsOptions): Promise<ListContactsResponse>;
365
+ /**
366
+ * Update a contact. Pass only the fields that should change.
367
+ *
368
+ * Toggling `marketingConsent` or `trackingConsent` automatically records
369
+ * a corresponding ContactEvent for the audit trail.
370
+ */
371
+ update(id: string, patch: UpdateContactOptions): Promise<Contact>;
372
+ /**
373
+ * GDPR right-to-be-forgotten. Anonymises the contact, sets `forgottenAt`
374
+ * and disables consent. Existing email events are anonymised in a
375
+ * follow-up cascade.
376
+ */
377
+ forget(id: string): Promise<ForgetContactResponse>;
378
+ /**
379
+ * Get the chronological event timeline for a contact.
380
+ */
381
+ events(id: string, options?: ListEventsOptions): Promise<ListEventsResponse>;
382
+ /**
383
+ * GDPR data access export. Returns the complete record for a contact
384
+ * including all emails, events, subscriptions and tags.
385
+ */
386
+ export(id: string): Promise<ContactExport>;
387
+ /**
388
+ * Add a tag to a contact (idempotent).
389
+ */
390
+ addTag(id: string, name: string): Promise<ContactTag>;
391
+ /**
392
+ * Remove a tag from a contact.
393
+ */
394
+ removeTag(id: string, name: string): Promise<{
395
+ ok: true;
396
+ }>;
397
+ }
398
+
399
+ type SequenceType = 'TRANSACTIONAL' | 'MARKETING';
400
+ type SequenceStatus = 'DRAFT' | 'ACTIVE' | 'PAUSED' | 'ARCHIVED';
401
+ type SequenceTriggerType = 'MANUAL' | 'API' | 'AUDIENCE_SUBSCRIBE' | 'AUDIENCE_UNSUBSCRIBE' | 'TAG_ADDED' | 'TAG_REMOVED' | 'WEBHOOK' | 'SCHEDULED';
402
+ type SequenceRunStatus = 'RUNNING' | 'COMPLETED' | 'FAILED' | 'CANCELLED';
403
+ type WaitDuration = {
404
+ minutes?: number;
405
+ hours?: number;
406
+ days?: number;
407
+ };
408
+ type BranchCondition = {
409
+ kind: 'has_tag';
410
+ tag: string;
411
+ } | {
412
+ kind: 'opened_email';
413
+ sinceStepKey: string;
414
+ } | {
415
+ kind: 'clicked_email';
416
+ sinceStepKey: string;
417
+ } | {
418
+ kind: 'always';
419
+ };
420
+ type SequenceStep = {
421
+ key: string;
422
+ type: 'send_email';
423
+ name?: string;
424
+ config: {
425
+ templateId?: string;
426
+ subject?: string;
427
+ html?: string;
428
+ variables?: Record<string, unknown>;
429
+ fromHandle?: string;
430
+ fromDomainId?: string;
431
+ };
432
+ next?: string | null;
433
+ } | {
434
+ key: string;
435
+ type: 'wait';
436
+ name?: string;
437
+ config: {
438
+ duration: WaitDuration;
439
+ };
440
+ next?: string | null;
441
+ } | {
442
+ key: string;
443
+ type: 'branch';
444
+ name?: string;
445
+ config: {
446
+ condition: BranchCondition;
447
+ };
448
+ thenNext: string | null;
449
+ elseNext: string | null;
450
+ } | {
451
+ key: string;
452
+ type: 'tag_add' | 'tag_remove';
453
+ name?: string;
454
+ config: {
455
+ tag: string;
456
+ };
457
+ next?: string | null;
458
+ } | {
459
+ key: string;
460
+ type: 'update_contact';
461
+ name?: string;
462
+ config: {
463
+ fields: Record<string, unknown>;
464
+ };
465
+ next?: string | null;
466
+ } | {
467
+ key: string;
468
+ type: 'webhook';
469
+ name?: string;
470
+ config: {
471
+ url: string;
472
+ method?: 'GET' | 'POST';
473
+ headers?: Record<string, string>;
474
+ body?: unknown;
475
+ };
476
+ next?: string | null;
477
+ } | {
478
+ key: string;
479
+ type: 'end';
480
+ name?: string;
481
+ };
482
+ type SequenceDefinition = {
483
+ entry: string;
484
+ steps: Record<string, SequenceStep>;
485
+ };
486
+ interface SequenceVersion {
487
+ id: string;
488
+ version: number;
489
+ definition: SequenceDefinition;
490
+ createdBy?: string | null;
491
+ createdAt: string;
492
+ activatedAt?: string | null;
493
+ }
494
+ interface Sequence {
495
+ id: string;
496
+ name: string;
497
+ description?: string | null;
498
+ type: SequenceType;
499
+ status: SequenceStatus;
500
+ triggerType: SequenceTriggerType;
501
+ triggerConfig?: unknown;
502
+ activeVersionId?: string | null;
503
+ activeVersion?: SequenceVersion | null;
504
+ createdAt: string;
505
+ updatedAt: string;
506
+ }
507
+ interface SequenceRun {
508
+ id: string;
509
+ sequenceId: string;
510
+ sequenceVersionId: string;
511
+ contactId?: string | null;
512
+ adHocRecipient?: string | null;
513
+ payload?: unknown;
514
+ status: SequenceRunStatus;
515
+ currentStepKey?: string | null;
516
+ nextStepAt?: string | null;
517
+ enteredAt: string;
518
+ completedAt?: string | null;
519
+ error?: string | null;
520
+ }
521
+ interface CreateSequenceOptions {
522
+ name: string;
523
+ description?: string;
524
+ type?: SequenceType;
525
+ triggerType?: SequenceTriggerType;
526
+ triggerConfig?: unknown;
527
+ definition?: SequenceDefinition;
528
+ }
529
+ interface ListSequencesOptions {
530
+ skip?: number;
531
+ take?: number;
532
+ type?: SequenceType;
533
+ status?: SequenceStatus;
534
+ search?: string;
535
+ }
536
+ interface ListSequencesResponse {
537
+ items: Sequence[];
538
+ total: number;
539
+ skip: number;
540
+ take: number;
541
+ }
542
+ interface SaveVersionOptions {
543
+ definition: SequenceDefinition;
544
+ activate?: boolean;
545
+ }
546
+ interface TriggerRunOptions {
547
+ contactId?: string;
548
+ email?: string;
549
+ payload?: unknown;
550
+ }
551
+ interface ListRunsOptions {
552
+ skip?: number;
553
+ take?: number;
554
+ status?: SequenceRunStatus;
555
+ contactId?: string;
556
+ }
557
+ interface ListRunsResponse {
558
+ items: SequenceRun[];
559
+ total: number;
560
+ skip: number;
561
+ take: number;
562
+ }
563
+
564
+ /**
565
+ * Sequences API.
566
+ *
567
+ * A Sequence is a multi-step email journey. There are two kinds:
568
+ *
569
+ * - MARKETING: requires marketing consent on the recipient and an
570
+ * unsubscribe link in every send. Triggers off audience subscribe,
571
+ * tags, etc.
572
+ * - TRANSACTIONAL: no consent required, no unsubscribe link. Triggers
573
+ * off API events, webhooks or schedules.
574
+ *
575
+ * Define a sequence in code with the `defineSequence` helper, then
576
+ * `client.sequences.saveVersion` to push it.
577
+ */
578
+ declare class Sequences {
579
+ private readonly http;
580
+ constructor(http: HttpClient);
581
+ readonly runs: {
582
+ list: (sequenceId: string, options?: ListRunsOptions) => Promise<ListRunsResponse>;
583
+ };
584
+ /**
585
+ * Create a new sequence (always starts in DRAFT). Pass `definition` to
586
+ * seed the first version, or omit it to create an empty placeholder you
587
+ * can later push versions into.
588
+ */
589
+ create(options: CreateSequenceOptions): Promise<Sequence>;
590
+ /**
591
+ * Get a sequence by ID.
592
+ */
593
+ get(id: string): Promise<Sequence>;
594
+ /**
595
+ * List sequences with filters.
596
+ */
597
+ list(options?: ListSequencesOptions): Promise<ListSequencesResponse>;
598
+ /**
599
+ * Delete a sequence and all its versions and runs.
600
+ */
601
+ delete(id: string): Promise<{
602
+ id: string;
603
+ }>;
604
+ /**
605
+ * Change the lifecycle status: DRAFT, ACTIVE, PAUSED, ARCHIVED.
606
+ */
607
+ setStatus(id: string, status: SequenceStatus): Promise<Sequence>;
608
+ /**
609
+ * Save a new immutable version of the sequence definition. If `activate`
610
+ * is true (default), the new version becomes the active one for future
611
+ * triggered runs. Existing in-flight runs keep their pinned version.
612
+ */
613
+ saveVersion(id: string, options: SaveVersionOptions): Promise<SequenceVersion>;
614
+ /**
615
+ * Trigger a sequence run for a contact or ad-hoc email. The sequence
616
+ * must be ACTIVE.
617
+ */
618
+ trigger(id: string, options: TriggerRunOptions): Promise<SequenceRun>;
619
+ }
620
+
621
+ /**
622
+ * Verification status shared by a domain and its individual DNS records.
623
+ */
624
+ type DomainVerificationStatus = 'NOT_STARTED' | 'PENDING' | 'SUCCESS' | 'FAILED' | 'TEMPORARY_FAILURE';
625
+ type DomainDnsRecordType = 'MX' | 'TXT' | 'CNAME';
626
+ /**
627
+ * A single DNS record you need to add at your DNS provider for the domain to
628
+ * verify (DKIM, SPF, the verification TXT record, optional DMARC, …).
629
+ */
630
+ interface DomainDnsRecord {
631
+ type: DomainDnsRecordType;
632
+ /** Record name/host, e.g. `mail` or `@`. */
633
+ name: string;
634
+ /** Record value, e.g. the SPF or DKIM string. */
635
+ value: string;
636
+ /** Recommended TTL, e.g. `Auto`. */
637
+ ttl: string;
638
+ /** Priority for MX records. */
639
+ priority?: string | null;
640
+ /** Verification status of this specific record. */
641
+ status?: DomainVerificationStatus | null;
642
+ /** Whether adding this record is recommended (e.g. DMARC). */
643
+ recommended?: boolean;
644
+ }
645
+ /**
646
+ * A sending domain with its DNS records and verification state.
647
+ */
648
+ interface Domain {
649
+ id: string;
650
+ /** The domain name, e.g. `example.com`. */
651
+ name: string;
652
+ projectId: string;
653
+ /** Primary sending region, e.g. `eu-central-1`. */
654
+ mainRegion: string;
655
+ /** All regions the domain is provisioned in. */
656
+ regions: string[];
657
+ clickTracking: boolean;
658
+ openTracking: boolean;
659
+ dkimTokens: string[];
660
+ dkimStatus?: DomainVerificationStatus | null;
661
+ /** Overall verification status of the domain. */
662
+ status?: DomainVerificationStatus | null;
663
+ spfStatus?: DomainVerificationStatus | null;
664
+ createdAt: string;
665
+ updatedAt: string;
666
+ dmarcAdded: boolean;
667
+ verificationInProcess: boolean;
668
+ errorMessage?: string | null;
669
+ subdomain?: string | null;
670
+ verificationError?: string | null;
671
+ lastCheckedTime?: string | null;
672
+ scheduledForDeletion: boolean;
673
+ /** DNS records to add at your DNS provider to verify the domain. */
674
+ dnsRecords: DomainDnsRecord[];
675
+ }
676
+ interface CreateDomainOptions {
677
+ /** The domain name to register, e.g. `example.com`. */
678
+ name: string;
679
+ /**
680
+ * Sending region for the domain. Defaults to `eu-central-1`.
681
+ */
682
+ region?: string;
683
+ }
684
+ interface DeleteDomainResponse {
685
+ success: boolean;
686
+ message: string;
687
+ }
688
+ interface VerifyDomainResponse {
689
+ message: string;
690
+ }
691
+
692
+ /**
693
+ * Domains API.
694
+ *
695
+ * A Domain is a sending domain you own (e.g. `example.com`). After creating it
696
+ * you add the returned `dnsRecords` (DKIM, SPF, verification TXT) at your DNS
697
+ * provider and then `verify` it. Only verified domains can send email and
698
+ * receive inbound mail.
699
+ */
700
+ declare class Domains {
701
+ private readonly http;
702
+ constructor(http: HttpClient);
703
+ /**
704
+ * Register a new sending domain. The response contains the `dnsRecords` you
705
+ * need to add at your DNS provider before calling {@link verify}.
706
+ *
707
+ * @example
708
+ * ```typescript
709
+ * const domain = await zupost.domains.create({ name: 'example.com' });
710
+ * for (const record of domain.dnsRecords) {
711
+ * console.log(record.type, record.name, record.value);
712
+ * }
713
+ * ```
714
+ */
715
+ create(options: CreateDomainOptions): Promise<Domain>;
716
+ /**
717
+ * Get a domain by ID, including its current verification status and DNS
718
+ * records.
719
+ */
720
+ get(id: string): Promise<Domain>;
721
+ /**
722
+ * List all domains in the project.
723
+ */
724
+ list(): Promise<Domain[]>;
725
+ /**
726
+ * Start the verification process for a domain. Add the DNS records returned
727
+ * by {@link create} or {@link get} first; Zupost then checks them and
728
+ * updates the domain's `status`.
729
+ */
730
+ verify(id: string): Promise<VerifyDomainResponse>;
731
+ /**
732
+ * Schedule a domain for deletion.
733
+ */
734
+ delete(id: string): Promise<DeleteDomainResponse>;
735
+ }
736
+
737
+ interface CreateInboundChannelOptions {
738
+ /** Human-readable name for the channel (1-100 characters). */
739
+ name: string;
740
+ /** ID of a verified domain that should receive inbound email. */
741
+ domainId: string;
742
+ /**
743
+ * HTTPS URL parsed inbound emails are delivered to. Must resolve to a
744
+ * public address.
745
+ */
746
+ webhookUrl: string;
747
+ /**
748
+ * Shared secret (32-512 characters) used to sign webhook deliveries so you
749
+ * can verify they originate from Zupost.
750
+ */
751
+ webhookSecret: string;
752
+ }
753
+ /**
754
+ * An inbound email channel: it routes mail received on a domain to your
755
+ * `webhookUrl`.
756
+ */
757
+ interface InboundChannel {
758
+ id: string;
759
+ name: string;
760
+ projectId: string;
761
+ domainId: string;
762
+ webhookUrl: string;
763
+ createdAt: string;
764
+ updatedAt: string;
765
+ }
766
+
767
+ /**
768
+ * Inbound API.
769
+ *
770
+ * Receive email sent to a verified domain by routing it through an inbound
771
+ * channel to your own HTTPS webhook. Deliveries are signed with the
772
+ * `webhookSecret` you provide so you can verify their authenticity.
773
+ */
774
+ declare class Inbound {
775
+ private readonly http;
776
+ constructor(http: HttpClient);
777
+ /**
778
+ * Inbound channels route mail received on a domain to a webhook.
779
+ */
780
+ readonly channels: {
781
+ /**
782
+ * Create an inbound channel for a verified domain.
783
+ *
784
+ * @example
785
+ * ```typescript
786
+ * const channel = await zupost.inbound.channels.create({
787
+ * name: 'Support inbox',
788
+ * domainId: 'dom_123',
789
+ * webhookUrl: 'https://example.com/zupost/inbound',
790
+ * webhookSecret: process.env.ZUPOST_INBOUND_SECRET!,
791
+ * });
792
+ * ```
793
+ */
794
+ create: (options: CreateInboundChannelOptions) => Promise<InboundChannel>;
795
+ };
796
+ }
797
+
222
798
  interface ZupostOptions {
223
799
  /**
224
800
  * Custom API URL. Defaults to 'https://api.zupost.com'.
@@ -235,6 +811,26 @@ declare class Zupost {
235
811
  * Campaigns API for sending email campaigns to audiences.
236
812
  */
237
813
  readonly campaigns: Campaigns;
814
+ /**
815
+ * Contacts API. A Contact is every email address Zupost has ever seen,
816
+ * with a chronological event timeline, consent state and GDPR primitives.
817
+ */
818
+ readonly contacts: Contacts;
819
+ /**
820
+ * Sequences API. A Sequence is a multi-step email journey (marketing or
821
+ * transactional) with branches, waits, tags and webhooks.
822
+ */
823
+ readonly sequences: Sequences;
824
+ /**
825
+ * Domains API. A Domain is a sending domain you own, with DNS records and
826
+ * verification state. Only verified domains can send and receive email.
827
+ */
828
+ readonly domains: Domains;
829
+ /**
830
+ * Inbound API. Receive email on a verified domain and have it delivered to
831
+ * your own webhook through an inbound channel.
832
+ */
833
+ readonly inbound: Inbound;
238
834
  constructor(apiKey: string, options?: ZupostOptions);
239
835
  }
240
836
 
@@ -259,4 +855,49 @@ declare class ZupostError extends Error {
259
855
  static fromResponse(response: Response): Promise<ZupostError>;
260
856
  }
261
857
 
262
- export { type SendCampaignOptions, type SendCampaignResponse, type SendEmailOptions, type SendEmailResponse, Zupost, ZupostError, type ZupostOptions };
858
+ /**
859
+ * Type-safe helper for defining a SequenceDefinition in code.
860
+ *
861
+ * Catches missing entry steps and unreachable next-pointers at compile time
862
+ * (via the explicit literal types) and at runtime (via the assertion below).
863
+ *
864
+ * @example
865
+ * ```typescript
866
+ * const onboarding = defineSequence({
867
+ * entry: 'welcome',
868
+ * steps: {
869
+ * welcome: {
870
+ * key: 'welcome',
871
+ * type: 'send_email',
872
+ * config: { templateId: 'welcome-mail' },
873
+ * next: 'wait_3d',
874
+ * },
875
+ * wait_3d: {
876
+ * key: 'wait_3d',
877
+ * type: 'wait',
878
+ * config: { duration: { days: 3 } },
879
+ * next: 'tips',
880
+ * },
881
+ * tips: {
882
+ * key: 'tips',
883
+ * type: 'send_email',
884
+ * config: { templateId: 'tips-mail' },
885
+ * next: 'end',
886
+ * },
887
+ * end: { key: 'end', type: 'end' },
888
+ * },
889
+ * });
890
+ *
891
+ * await zupost.sequences.create({
892
+ * name: 'Onboarding',
893
+ * type: 'MARKETING',
894
+ * definition: onboarding,
895
+ * });
896
+ * ```
897
+ */
898
+ declare function defineSequence<TSteps extends Record<string, SequenceStep>>(definition: {
899
+ entry: keyof TSteps & string;
900
+ steps: TSteps;
901
+ }): SequenceDefinition;
902
+
903
+ export { type BranchCondition, type Contact, type ContactEvent, type ContactEventType, type ContactExport, type ContactTag, type CreateContactOptions, type CreateDomainOptions, type CreateInboundChannelOptions, type CreateSequenceOptions, type DeleteDomainResponse, type Domain, type DomainDnsRecord, type DomainDnsRecordType, type DomainVerificationStatus, type EmailRecipientType, type ForgetContactResponse, type InboundChannel, type ListContactsOptions, type ListContactsResponse, type ListEventsOptions, type ListEventsResponse, type ListRunsOptions, type ListRunsResponse, type ListSequencesOptions, type ListSequencesResponse, type SaveVersionOptions, type SendCampaignOptions, type SendCampaignResponse, type SendEmailOptions, type SendEmailResponse, type Sequence, type SequenceDefinition, type SequenceRun, type SequenceRunStatus, type SequenceStatus, type SequenceStep, type SequenceTriggerType, type SequenceType, type SequenceVersion, type TriggerRunOptions, type UpdateContactOptions, type VerifyDomainResponse, type WaitDuration, Zupost, ZupostError, type ZupostOptions, defineSequence };