@marlinjai/mail-contract 0.15.2 → 0.17.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.mjs CHANGED
@@ -2962,6 +2962,10 @@ var AUDIT_ACTIONS = [
2962
2962
  "provider.events_secret_set",
2963
2963
  "provider.bounces_halted",
2964
2964
  "provider.anomaly_cleared",
2965
+ "sending_domain.created",
2966
+ "sending_domain.updated",
2967
+ "sending_domain.checked",
2968
+ "sending_domain.deleted",
2965
2969
  "topic.created",
2966
2970
  "topic.updated",
2967
2971
  "topic.deleted",
@@ -3018,6 +3022,7 @@ var AUDIT_ACTIONS = [
3018
3022
  "billing.checkout_started",
3019
3023
  "billing.subscription_changed",
3020
3024
  "billing.exemption_changed",
3025
+ "billing.extra_sending_domains_changed",
3021
3026
  // A1: automations
3022
3027
  "automation.created",
3023
3028
  "automation.updated",
@@ -3793,7 +3798,7 @@ var ProviderRejections = z13.object({
3793
3798
  });
3794
3799
  var ProviderEvents = z13.object({
3795
3800
  status: z13.enum(["active", "needs_secret"]),
3796
- source: z13.enum(["automatic", "manual"]).nullable(),
3801
+ source: z13.enum(["automatic", "manual", "managed"]).nullable(),
3797
3802
  url: z13.string().url(),
3798
3803
  error: z13.string().nullable(),
3799
3804
  /**
@@ -3880,36 +3885,86 @@ var ProviderVerifyResult = z13.object({
3880
3885
  error: z13.string().nullable()
3881
3886
  });
3882
3887
 
3883
- // src/contacts.ts
3888
+ // src/sending-domains.ts
3884
3889
  import { z as z14 } from "zod";
3885
- var Topic = z14.object({
3890
+ var SENDING_DOMAIN_STATUSES = ["pending_dns", "verifying", "verified", "failed", "temporary_failure"];
3891
+ var SendingDomainStatus = z14.enum(SENDING_DOMAIN_STATUSES);
3892
+ var SENDING_DOMAIN_DNS_MODES = ["manual", "managed"];
3893
+ var SendingDomainDnsMode = z14.enum(SENDING_DOMAIN_DNS_MODES);
3894
+ var SENDING_DOMAIN_REGION = "eu-west-1";
3895
+ var SendingDomainName = z14.string().trim().toLowerCase().max(253).regex(
3896
+ /^(?=.{1,253}$)(?!-)[a-z0-9-]{1,63}(?<!-)(\.(?!-)[a-z0-9-]{1,63}(?<!-))*\.[a-z]{2,63}$/,
3897
+ "must be a domain such as example.com, without https:// or an @"
3898
+ );
3899
+ var SendingDomainRecord = z14.object({
3900
+ record: z14.string().max(40),
3901
+ name: z14.string().max(253),
3902
+ type: z14.string().max(10),
3903
+ value: z14.string().max(4096),
3904
+ ttl: z14.string().max(20),
3905
+ status: z14.string().max(40),
3906
+ priority: z14.number().int().min(0).max(65535).optional()
3907
+ });
3908
+ var SendingDomain = z14.object({
3909
+ id: Id,
3910
+ domain: z14.string(),
3911
+ from_name: z14.string(),
3912
+ from_email: Email,
3913
+ reply_to: Email.nullable(),
3914
+ status: SendingDomainStatus,
3915
+ dns_mode: SendingDomainDnsMode,
3916
+ records: z14.array(SendingDomainRecord),
3917
+ provider_id: Id.nullable(),
3918
+ checked_at: Timestamp.nullable(),
3919
+ verified_at: Timestamp.nullable(),
3920
+ last_error: z14.string().nullable(),
3921
+ created_at: Timestamp,
3922
+ updated_at: Timestamp
3923
+ });
3924
+ var SenderFields = {
3925
+ from_name: z14.string().trim().min(1).max(120),
3926
+ from_email: Email,
3927
+ reply_to: Email.nullable().optional()
3928
+ };
3929
+ function senderOnDomain(input, ctx) {
3930
+ const at = input.from_email.lastIndexOf("@");
3931
+ if (at < 0 || input.from_email.slice(at + 1).toLowerCase() !== input.domain) {
3932
+ ctx.addIssue({ code: z14.ZodIssueCode.custom, path: ["from_email"], message: `must be an address on ${input.domain}` });
3933
+ }
3934
+ }
3935
+ var SendingDomainCreate = z14.object({ domain: SendingDomainName, ...SenderFields }).superRefine(senderOnDomain);
3936
+ var SendingDomainUpdate = z14.object({ from_name: SenderFields.from_name.optional(), from_email: Email.optional(), reply_to: Email.nullable().optional() }).refine((v) => Object.keys(v).length > 0, "nothing to change");
3937
+
3938
+ // src/contacts.ts
3939
+ import { z as z15 } from "zod";
3940
+ var Topic = z15.object({
3886
3941
  id: Id,
3887
3942
  slug: Slug,
3888
- name: z14.string().min(1).max(120),
3943
+ name: z15.string().min(1).max(120),
3889
3944
  /** Shown on the hosted preference page. */
3890
- description: z14.string().max(1e3).nullable(),
3945
+ description: z15.string().max(1e3).nullable(),
3891
3946
  /** Translations of `name` and `description` per locale, for the hosted page. */
3892
- translations: z14.record(
3893
- z14.object({ name: z14.string().min(1).max(120), description: z14.string().max(1e3).nullable() })
3947
+ translations: z15.record(
3948
+ z15.object({ name: z15.string().min(1).max(120), description: z15.string().max(1e3).nullable() })
3894
3949
  ),
3895
3950
  created_at: Timestamp,
3896
3951
  updated_at: Timestamp
3897
3952
  });
3898
- var TopicCreate = z14.object({
3953
+ var TopicCreate = z15.object({
3899
3954
  slug: Slug,
3900
- name: z14.string().min(1).max(120),
3901
- description: z14.string().max(1e3).optional(),
3955
+ name: z15.string().min(1).max(120),
3956
+ description: z15.string().max(1e3).optional(),
3902
3957
  translations: Topic.shape.translations.optional()
3903
3958
  });
3904
3959
  var TopicUpdate = TopicCreate.omit({ slug: true }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
3905
- var Contact = z14.object({
3960
+ var Contact = z15.object({
3906
3961
  id: Id,
3907
- external_id: z14.string().min(1).max(255).nullable(),
3962
+ external_id: z15.string().min(1).max(255).nullable(),
3908
3963
  /** Stored lowercased, unique per workspace. */
3909
3964
  email: Email,
3910
- first_name: z14.string().max(200).nullable(),
3911
- last_name: z14.string().max(200).nullable(),
3912
- locale: z14.string().min(2).max(35).nullable(),
3965
+ first_name: z15.string().max(200).nullable(),
3966
+ last_name: z15.string().max(200).nullable(),
3967
+ locale: z15.string().min(2).max(35).nullable(),
3913
3968
  /**
3914
3969
  * The person's own time zone, an IANA name such as `Europe/Berlin` (A1).
3915
3970
  * Every wall clock an automation waits for is read in it, falling back to the
@@ -3917,65 +3972,65 @@ var Contact = z14.object({
3917
3972
  */
3918
3973
  timezone: TimezoneName.nullable(),
3919
3974
  properties: Properties,
3920
- topics: z14.array(Slug),
3975
+ topics: z15.array(Slug),
3921
3976
  /** The slugs of the contact's tags (S4). */
3922
- tags: z14.array(Slug),
3977
+ tags: z15.array(Slug),
3923
3978
  created_at: Timestamp,
3924
3979
  updated_at: Timestamp
3925
3980
  });
3926
- var ContactUpsert = z14.object({
3927
- external_id: z14.string().min(1).max(255).optional(),
3981
+ var ContactUpsert = z15.object({
3982
+ external_id: z15.string().min(1).max(255).optional(),
3928
3983
  email: Email.optional(),
3929
- first_name: z14.string().max(200).nullable().optional(),
3930
- last_name: z14.string().max(200).nullable().optional(),
3931
- locale: z14.string().min(2).max(35).nullable().optional(),
3984
+ first_name: z15.string().max(200).nullable().optional(),
3985
+ last_name: z15.string().max(200).nullable().optional(),
3986
+ locale: z15.string().min(2).max(35).nullable().optional(),
3932
3987
  timezone: TimezoneName.nullable().optional(),
3933
3988
  properties: Properties.optional(),
3934
- topics: z14.array(Slug).max(100).optional()
3989
+ topics: z15.array(Slug).max(100).optional()
3935
3990
  }).refine((v) => v.external_id !== void 0 || v.email !== void 0, {
3936
3991
  message: "external_id or email is required",
3937
3992
  path: ["email"]
3938
3993
  });
3939
- var ContactUpsertResult = z14.object({
3994
+ var ContactUpsertResult = z15.object({
3940
3995
  contact: Contact,
3941
- created: z14.boolean()
3996
+ created: z15.boolean()
3942
3997
  });
3943
3998
  var ContactListQuery = PageQuery.extend({
3944
- email: z14.string().min(1).max(254).optional(),
3945
- external_id: z14.string().min(1).max(255).optional(),
3999
+ email: z15.string().min(1).max(254).optional(),
4000
+ external_id: z15.string().min(1).max(255).optional(),
3946
4001
  topic: Slug.optional()
3947
4002
  });
3948
- var ContactErased = z14.object({
3949
- ok: z14.literal(true),
3950
- erased_messages: z14.number().int().min(0),
3951
- erased_recipients: z14.number().int().min(0),
3952
- suppressions_kept: z14.number().int().min(0)
4003
+ var ContactErased = z15.object({
4004
+ ok: z15.literal(true),
4005
+ erased_messages: z15.number().int().min(0),
4006
+ erased_recipients: z15.number().int().min(0),
4007
+ suppressions_kept: z15.number().int().min(0)
3953
4008
  });
3954
4009
  var SUPPRESSION_REASONS = ["unsubscribed", "bounced", "complained", "manual"];
3955
- var SuppressionReason = z14.enum(SUPPRESSION_REASONS);
3956
- var Suppression = z14.object({
4010
+ var SuppressionReason = z15.enum(SUPPRESSION_REASONS);
4011
+ var Suppression = z15.object({
3957
4012
  id: Id,
3958
4013
  email: Email,
3959
4014
  reason: SuppressionReason,
3960
4015
  topic: Slug.nullable(),
3961
4016
  source_message_id: Id.nullable(),
3962
- note: z14.string().max(1e3).nullable(),
4017
+ note: z15.string().max(1e3).nullable(),
3963
4018
  created_at: Timestamp
3964
4019
  });
3965
- var SuppressionCreate = z14.object({
4020
+ var SuppressionCreate = z15.object({
3966
4021
  email: Email,
3967
- reason: z14.enum(["manual", "unsubscribed"]),
4022
+ reason: z15.enum(["manual", "unsubscribed"]),
3968
4023
  topic: Slug.nullable().optional(),
3969
- note: z14.string().max(1e3).optional()
4024
+ note: z15.string().max(1e3).optional()
3970
4025
  });
3971
4026
  var SuppressionListQuery = PageQuery.extend({
3972
- email: z14.string().min(1).max(254).optional(),
4027
+ email: z15.string().min(1).max(254).optional(),
3973
4028
  reason: SuppressionReason.optional(),
3974
4029
  topic: Slug.optional()
3975
4030
  });
3976
4031
 
3977
4032
  // src/webhooks.ts
3978
- import { z as z15 } from "zod";
4033
+ import { z as z16 } from "zod";
3979
4034
  var WEBHOOK_EVENT_TYPES = [
3980
4035
  "message.sent",
3981
4036
  "message.failed",
@@ -4019,23 +4074,23 @@ var WEBHOOK_EVENT_TYPES = [
4019
4074
  "template.updated",
4020
4075
  "template.deleted"
4021
4076
  ];
4022
- var WebhookEventType = z15.enum(WEBHOOK_EVENT_TYPES);
4023
- var MessageEventBase = z15.object({
4077
+ var WebhookEventType = z16.enum(WEBHOOK_EVENT_TYPES);
4078
+ var MessageEventBase = z16.object({
4024
4079
  message_id: Id,
4025
4080
  mailing_id: Id.nullable(),
4026
4081
  mailing_metadata: MailingMetadata.nullable(),
4027
4082
  recipient_id: Id.nullable(),
4028
4083
  contact_id: Id.nullable(),
4029
- external_id: z15.string().nullable(),
4084
+ external_id: z16.string().nullable(),
4030
4085
  email: Email,
4031
- subject: z15.string(),
4086
+ subject: z16.string(),
4032
4087
  topic: Slug.nullable(),
4033
- provider_message_id: z15.string().nullable(),
4034
- is_test: z15.boolean()
4088
+ provider_message_id: z16.string().nullable(),
4089
+ is_test: z16.boolean()
4035
4090
  });
4036
4091
  var MessageSentData = MessageEventBase.extend({
4037
4092
  /** The final HTML as sent, so the client can archive it beside its own records. */
4038
- html: z15.string(),
4093
+ html: z16.string(),
4039
4094
  sent_at: Timestamp,
4040
4095
  /**
4041
4096
  * The choice each insertion made (see `Message.insertions`); absent or null
@@ -4046,20 +4101,20 @@ var MessageSentData = MessageEventBase.extend({
4046
4101
  insertions: InsertionChoices.nullish()
4047
4102
  });
4048
4103
  var MessageFailedData = MessageEventBase.extend({
4049
- error: z15.string(),
4104
+ error: z16.string(),
4050
4105
  /** False when the provider rejected permanently; the recipient will not be retried. */
4051
- retryable: z15.boolean(),
4106
+ retryable: z16.boolean(),
4052
4107
  failed_at: Timestamp
4053
4108
  });
4054
4109
  var UNSUBSCRIBE_SOURCES = ["hosted_page", "one_click", "api", "dashboard", "signup_form"];
4055
- var ContactUnsubscribedData = z15.object({
4110
+ var ContactUnsubscribedData = z16.object({
4056
4111
  contact_id: Id.nullable(),
4057
- external_id: z15.string().nullable(),
4112
+ external_id: z16.string().nullable(),
4058
4113
  email: Email,
4059
4114
  /** The topic unsubscribed from; null means every topic. */
4060
4115
  topic: Slug.nullable(),
4061
4116
  mailing_id: Id.nullable(),
4062
- source: z15.enum(UNSUBSCRIBE_SOURCES),
4117
+ source: z16.enum(UNSUBSCRIBE_SOURCES),
4063
4118
  unsubscribed_at: Timestamp
4064
4119
  });
4065
4120
  var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: true }).extend({
@@ -4068,142 +4123,142 @@ var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: tr
4068
4123
  * breaker undid a `bounced` block it judged false (a `contact.bounced` for the
4069
4124
  * same address and mailing went out before); `topic` is null.
4070
4125
  */
4071
- source: z15.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
4126
+ source: z16.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
4072
4127
  resubscribed_at: Timestamp
4073
4128
  });
4074
- var ContactBouncedData = z15.object({
4129
+ var ContactBouncedData = z16.object({
4075
4130
  contact_id: Id.nullable(),
4076
- external_id: z15.string().nullable(),
4131
+ external_id: z16.string().nullable(),
4077
4132
  email: Email,
4078
4133
  /** `bounced` for a hard bounce, `complained` for a spam complaint. */
4079
- reason: z15.enum(["bounced", "complained"]),
4134
+ reason: z16.enum(["bounced", "complained"]),
4080
4135
  message_id: Id.nullable(),
4081
- diagnostic: z15.string().nullable(),
4136
+ diagnostic: z16.string().nullable(),
4082
4137
  bounced_at: Timestamp
4083
4138
  });
4084
- var MailingFinishedData = z15.object({
4139
+ var MailingFinishedData = z16.object({
4085
4140
  mailing_id: Id,
4086
4141
  mailing_metadata: MailingMetadata,
4087
- status: z15.enum(["sent", "partially_failed", "cancelled"]),
4142
+ status: z16.enum(["sent", "partially_failed", "cancelled"]),
4088
4143
  counts: MailingCounts,
4089
4144
  finished_at: Timestamp
4090
4145
  });
4091
- var ContactSubscribedData = z15.object({
4146
+ var ContactSubscribedData = z16.object({
4092
4147
  contact_id: Id,
4093
- external_id: z15.string().nullable(),
4148
+ external_id: z16.string().nullable(),
4094
4149
  email: Email,
4095
- topics: z15.array(Slug),
4096
- source: z15.enum(["signup_form", "api", "dashboard", "automation"]),
4150
+ topics: z16.array(Slug),
4151
+ source: z16.enum(["signup_form", "api", "dashboard", "automation"]),
4097
4152
  signup_form_id: Id.nullable(),
4098
- signup_form_version: z15.number().int().min(1).nullable(),
4153
+ signup_form_version: z16.number().int().min(1).nullable(),
4099
4154
  subscribed_at: Timestamp
4100
4155
  });
4101
- var ImportFinishedData = z15.object({
4156
+ var ImportFinishedData = z16.object({
4102
4157
  import_id: Id,
4103
- status: z15.enum(["completed", "cancelled", "failed"]),
4158
+ status: z16.enum(["completed", "cancelled", "failed"]),
4104
4159
  result: ImportReport.nullable(),
4105
- error: z15.string().nullable(),
4160
+ error: z16.string().nullable(),
4106
4161
  finished_at: Timestamp
4107
4162
  });
4108
- var MailingScheduledData = z15.object({
4163
+ var MailingScheduledData = z16.object({
4109
4164
  mailing_id: Id,
4110
4165
  mailing_metadata: MailingMetadata,
4111
4166
  scheduled_at: Timestamp.nullable()
4112
4167
  });
4113
- var MailingStartedData = z15.object({
4168
+ var MailingStartedData = z16.object({
4114
4169
  mailing_id: Id,
4115
4170
  mailing_metadata: MailingMetadata,
4116
- trigger: z15.enum(["send", "schedule"]),
4117
- recipients: z15.number().int().min(0),
4171
+ trigger: z16.enum(["send", "schedule"]),
4172
+ recipients: z16.number().int().min(0),
4118
4173
  started_at: Timestamp
4119
4174
  });
4120
- var MailingScheduleFailedData = z15.object({
4175
+ var MailingScheduleFailedData = z16.object({
4121
4176
  mailing_id: Id,
4122
4177
  mailing_metadata: MailingMetadata,
4123
- code: z15.string(),
4124
- message: z15.string(),
4178
+ code: z16.string(),
4179
+ message: z16.string(),
4125
4180
  failed_at: Timestamp
4126
4181
  });
4127
- var MailingAbWinnerSelectedData = z15.object({
4182
+ var MailingAbWinnerSelectedData = z16.object({
4128
4183
  mailing_id: Id,
4129
4184
  mailing_metadata: MailingMetadata,
4130
- winner: z15.string(),
4131
- decided_by: z15.enum(["metric", "manual"]),
4132
- variants: z15.array(VariantAnalytics),
4185
+ winner: z16.string(),
4186
+ decided_by: z16.enum(["metric", "manual"]),
4187
+ variants: z16.array(VariantAnalytics),
4133
4188
  decided_at: Timestamp
4134
4189
  });
4135
- var ContactTaggedData = z15.object({
4190
+ var ContactTaggedData = z16.object({
4136
4191
  contact_id: Id,
4137
- external_id: z15.string().nullable(),
4192
+ external_id: z16.string().nullable(),
4138
4193
  email: Email,
4139
4194
  /** Only the tags the contact did not already have. */
4140
- tags: z15.array(Slug).min(1),
4141
- source: z15.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4195
+ tags: z16.array(Slug).min(1),
4196
+ source: z16.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4142
4197
  tagged_at: Timestamp
4143
4198
  });
4144
- var ContactUpdatedData = z15.object({
4199
+ var ContactUpdatedData = z16.object({
4145
4200
  contact_id: Id,
4146
- external_id: z15.string().nullable(),
4201
+ external_id: z16.string().nullable(),
4147
4202
  email: Email,
4148
- changed: z15.array(z15.string()).min(1),
4203
+ changed: z16.array(z16.string()).min(1),
4149
4204
  properties: Properties,
4150
- source: z15.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4205
+ source: z16.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4151
4206
  updated_at: Timestamp
4152
4207
  });
4153
- var AutomationRunEventBase = z15.object({
4208
+ var AutomationRunEventBase = z16.object({
4154
4209
  automation_id: Id,
4155
- automation_name: z15.string(),
4210
+ automation_name: z16.string(),
4156
4211
  run_id: Id,
4157
- version: z15.number().int().min(1),
4212
+ version: z16.number().int().min(1),
4158
4213
  contact_id: Id,
4159
- external_id: z15.string().nullable(),
4214
+ external_id: z16.string().nullable(),
4160
4215
  email: Email
4161
4216
  });
4162
4217
  var AutomationRunStartedData = AutomationRunEventBase.extend({
4163
4218
  /** What let them in: a trigger kind, or `manual` for an explicit enrolment. */
4164
- trigger_kind: z15.string(),
4219
+ trigger_kind: z16.string(),
4165
4220
  entered_at: Timestamp
4166
4221
  });
4167
4222
  var AutomationRunCompletedData = AutomationRunEventBase.extend({
4168
- last_step_id: z15.string().nullable(),
4223
+ last_step_id: z16.string().nullable(),
4169
4224
  completed_at: Timestamp
4170
4225
  });
4171
4226
  var AutomationRunExitedData = AutomationRunEventBase.extend({
4172
4227
  reason: AutomationEndReason,
4173
- step_id: z15.string().nullable(),
4228
+ step_id: z16.string().nullable(),
4174
4229
  exited_at: Timestamp
4175
4230
  });
4176
4231
  var AutomationRunFailedData = AutomationRunEventBase.extend({
4177
- reason: z15.string(),
4178
- step_id: z15.string().nullable(),
4232
+ reason: z16.string(),
4233
+ step_id: z16.string().nullable(),
4179
4234
  failed_at: Timestamp
4180
4235
  });
4181
4236
  var AutomationWebhookData = AutomationRunEventBase.extend({
4182
- step_id: z15.string(),
4237
+ step_id: z16.string(),
4183
4238
  /** The step's own label, when it was given one, so a receiver can branch on a name. */
4184
- step_label: z15.string().nullable(),
4239
+ step_label: z16.string().nullable(),
4185
4240
  /** Whatever the step carries, verbatim. Null when it carries nothing. */
4186
4241
  payload: JsonValue.nullable(),
4187
4242
  fired_at: Timestamp
4188
4243
  });
4189
- var TemplateEventBase = z15.object({
4244
+ var TemplateEventBase = z16.object({
4190
4245
  template_id: Id,
4191
- name: z15.string().min(1).max(200),
4192
- version: z15.number().int().min(1),
4193
- source: z15.enum(["api", "dashboard", "mjml_import"])
4246
+ name: z16.string().min(1).max(200),
4247
+ version: z16.number().int().min(1),
4248
+ source: z16.enum(["api", "dashboard", "mjml_import"])
4194
4249
  });
4195
4250
  var TemplateCreatedData = TemplateEventBase.extend({ created_at: Timestamp });
4196
- var TemplateUpdatedData = TemplateEventBase.extend({ archived: z15.boolean(), updated_at: Timestamp });
4251
+ var TemplateUpdatedData = TemplateEventBase.extend({ archived: z16.boolean(), updated_at: Timestamp });
4197
4252
  var TemplateDeletedData = TemplateEventBase.extend({ deleted_at: Timestamp });
4198
- var envelope = (type, data) => z15.object({
4253
+ var envelope = (type, data) => z16.object({
4199
4254
  /** Unique per event: a receiver deduplicates on it (deliveries may repeat). */
4200
4255
  id: Id,
4201
- type: z15.literal(type),
4256
+ type: z16.literal(type),
4202
4257
  created_at: Timestamp,
4203
4258
  workspace_id: Id,
4204
4259
  data
4205
4260
  });
4206
- var WebhookEvent = z15.discriminatedUnion("type", [
4261
+ var WebhookEvent = z16.discriminatedUnion("type", [
4207
4262
  envelope("message.sent", MessageSentData),
4208
4263
  envelope("message.failed", MessageFailedData),
4209
4264
  envelope("contact.unsubscribed", ContactUnsubscribedData),
@@ -4227,16 +4282,16 @@ var WebhookEvent = z15.discriminatedUnion("type", [
4227
4282
  envelope("template.updated", TemplateUpdatedData),
4228
4283
  envelope("template.deleted", TemplateDeletedData)
4229
4284
  ]);
4230
- var WebhookEndpoint = z15.object({
4285
+ var WebhookEndpoint = z16.object({
4231
4286
  id: Id,
4232
- url: z15.string().url(),
4233
- description: z15.string().max(500).nullable(),
4234
- events: z15.array(WebhookEventType).min(1),
4235
- enabled: z15.boolean(),
4287
+ url: z16.string().url(),
4288
+ description: z16.string().max(500).nullable(),
4289
+ events: z16.array(WebhookEventType).min(1),
4290
+ enabled: z16.boolean(),
4236
4291
  created_at: Timestamp,
4237
4292
  updated_at: Timestamp
4238
4293
  });
4239
- var WebhookUrl = z15.string().url().refine((u) => {
4294
+ var WebhookUrl = z16.string().url().refine((u) => {
4240
4295
  try {
4241
4296
  const url = new URL(u);
4242
4297
  if (url.protocol === "https:") return true;
@@ -4245,35 +4300,35 @@ var WebhookUrl = z15.string().url().refine((u) => {
4245
4300
  return false;
4246
4301
  }
4247
4302
  }, "must be https (http only for localhost)");
4248
- var WebhookEndpointCreate = z15.object({
4303
+ var WebhookEndpointCreate = z16.object({
4249
4304
  url: WebhookUrl,
4250
- description: z15.string().max(500).optional(),
4251
- events: z15.array(WebhookEventType).min(1),
4252
- enabled: z15.boolean().optional()
4305
+ description: z16.string().max(500).optional(),
4306
+ events: z16.array(WebhookEventType).min(1),
4307
+ enabled: z16.boolean().optional()
4253
4308
  });
4254
- var WebhookEndpointUpdate = z15.object({
4309
+ var WebhookEndpointUpdate = z16.object({
4255
4310
  url: WebhookUrl,
4256
- description: z15.string().max(500).nullable(),
4257
- events: z15.array(WebhookEventType).min(1),
4258
- enabled: z15.boolean()
4311
+ description: z16.string().max(500).nullable(),
4312
+ events: z16.array(WebhookEventType).min(1),
4313
+ enabled: z16.boolean()
4259
4314
  }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
4260
- var WebhookEndpointWithSecret = z15.object({
4315
+ var WebhookEndpointWithSecret = z16.object({
4261
4316
  endpoint: WebhookEndpoint,
4262
- secret: z15.string().min(32)
4317
+ secret: z16.string().min(32)
4263
4318
  });
4264
4319
  var WEBHOOK_DELIVERY_STATUSES = ["pending", "succeeded", "failed"];
4265
- var WebhookDeliveryStatus = z15.enum(WEBHOOK_DELIVERY_STATUSES);
4320
+ var WebhookDeliveryStatus = z16.enum(WEBHOOK_DELIVERY_STATUSES);
4266
4321
  var WEBHOOK_MAX_ATTEMPTS = 8;
4267
4322
  var WEBHOOK_RETRY_DELAYS_SECONDS = [30, 120, 600, 1800, 3600, 7200, 21600];
4268
- var WebhookDelivery = z15.object({
4323
+ var WebhookDelivery = z16.object({
4269
4324
  id: Id,
4270
4325
  endpoint_id: Id,
4271
4326
  event_id: Id,
4272
4327
  event_type: WebhookEventType,
4273
4328
  status: WebhookDeliveryStatus,
4274
- attempts: z15.number().int().min(0),
4275
- last_status_code: z15.number().int().min(100).max(599).nullable(),
4276
- last_error: z15.string().nullable(),
4329
+ attempts: z16.number().int().min(0),
4330
+ last_status_code: z16.number().int().min(100).max(599).nullable(),
4331
+ last_error: z16.string().nullable(),
4277
4332
  next_attempt_at: Timestamp.nullable(),
4278
4333
  delivered_at: Timestamp.nullable(),
4279
4334
  created_at: Timestamp
@@ -4282,7 +4337,7 @@ var WebhookDeliveryListQuery = PageQuery.extend({
4282
4337
  status: WebhookDeliveryStatus.optional(),
4283
4338
  event_type: WebhookEventType.optional()
4284
4339
  });
4285
- var WebhookDeliveryParams = z15.object({ id: Id, delivery_id: Id });
4340
+ var WebhookDeliveryParams = z16.object({ id: Id, delivery_id: Id });
4286
4341
 
4287
4342
  // src/webhook-signing.ts
4288
4343
  var WEBHOOK_SIGNATURE_HEADER = "x-mail-signature";
@@ -4349,79 +4404,94 @@ async function verifyWebhook(input) {
4349
4404
  }
4350
4405
 
4351
4406
  // src/billing.ts
4352
- import { z as z16 } from "zod";
4407
+ import { z as z17 } from "zod";
4353
4408
  var PLAN_IDS = ["free", "starter", "growth", "design_partner"];
4354
- var PlanId = z16.enum(PLAN_IDS);
4355
- var PlanLimits = z16.object({
4356
- monthly_messages: z16.number().int().min(0).nullable(),
4357
- contacts: z16.number().int().min(0).nullable(),
4358
- members: z16.number().int().min(1).nullable(),
4359
- providers: z16.number().int().min(1).nullable(),
4360
- webhook_endpoints: z16.number().int().min(0).nullable(),
4409
+ var PlanId = z17.enum(PLAN_IDS);
4410
+ var PlanLimits = z17.object({
4411
+ monthly_messages: z17.number().int().min(0).nullable(),
4412
+ contacts: z17.number().int().min(0).nullable(),
4413
+ members: z17.number().int().min(1).nullable(),
4414
+ providers: z17.number().int().min(1).nullable(),
4415
+ webhook_endpoints: z17.number().int().min(0).nullable(),
4361
4416
  /** Automations that may be live (active or paused) at once (A1). */
4362
- active_automations: z16.number().int().min(0).nullable(),
4417
+ active_automations: z17.number().int().min(0).nullable(),
4363
4418
  /** Steps one automation may hold. Null is the flow's own cap, not unlimited. */
4364
- automation_steps: z16.number().int().min(1).nullable()
4419
+ automation_steps: z17.number().int().min(1).nullable(),
4420
+ /** Own domains Lumitra Mail sends from (managed sending domains); 0 when the plan has none. */
4421
+ sending_domains: z17.number().int().min(0).nullable()
4365
4422
  });
4366
- var PlanFeatures = z16.object({
4423
+ var PlanFeatures = z17.object({
4367
4424
  /** A/B tests of subject and content on a mailing (S4). */
4368
- ab_testing: z16.boolean(),
4425
+ ab_testing: z17.boolean(),
4369
4426
  /** Open and click tracking, still off until a workspace turns it on (`settings.tracking_enabled`). */
4370
- tracking: z16.boolean(),
4371
- /** Sending and hosting pages on the workspace's own domain (a later phase). */
4372
- custom_domains: z16.boolean(),
4427
+ tracking: z17.boolean(),
4373
4428
  /** Automations: flows a person walks through step by step (A1). */
4374
- automations: z16.boolean()
4429
+ automations: z17.boolean()
4375
4430
  });
4376
- var PLAN_FEATURES = ["ab_testing", "tracking", "custom_domains", "automations"];
4377
- var Plan = z16.object({
4431
+ var PLAN_FEATURES = ["ab_testing", "tracking", "automations"];
4432
+ var Plan = z17.object({
4378
4433
  id: PlanId,
4379
- name: z16.string().min(1),
4434
+ name: z17.string().min(1),
4380
4435
  /** Price in the smallest currency unit per month; null for plans not sold. */
4381
- monthly_price_cents: z16.number().int().min(0).nullable(),
4382
- currency: z16.string().length(3),
4436
+ monthly_price_cents: z17.number().int().min(0).nullable(),
4437
+ currency: z17.string().length(3),
4383
4438
  limits: PlanLimits,
4384
4439
  features: PlanFeatures
4385
4440
  });
4386
- var CatalogPlan = Plan.extend({ sellable: z16.boolean() });
4387
- var Subscription = z16.object({
4441
+ var CatalogPlan = Plan.extend({ sellable: z17.boolean() });
4442
+ var Subscription = z17.object({
4388
4443
  workspace_id: Id,
4389
4444
  plan: PlanId,
4390
- status: z16.enum(["active", "trialing", "past_due", "cancelled"]),
4445
+ status: z17.enum(["active", "trialing", "past_due", "cancelled"]),
4391
4446
  current_period_start: Timestamp,
4392
4447
  current_period_end: Timestamp,
4393
- cancel_at_period_end: z16.boolean(),
4448
+ cancel_at_period_end: z17.boolean(),
4394
4449
  /**
4395
4450
  * A design partner outside billing (plan `design_partner`, no limits, no
4396
4451
  * checkout). Set only by an operator, never through the API.
4397
4452
  */
4398
- billing_exempt: z16.boolean()
4453
+ billing_exempt: z17.boolean(),
4454
+ /**
4455
+ * Own sending domains bought on top of the plan's included ones (the
4456
+ * add-on), each a monthly charge on the same subscription. 0 without the
4457
+ * add-on; the usage limit `sending_domains` is the plan's plus these.
4458
+ */
4459
+ extra_sending_domains: z17.number().int().min(0)
4460
+ });
4461
+ var BillingAddons = z17.object({
4462
+ sending_domain: z17.object({
4463
+ monthly_price_cents: z17.number().int().min(0),
4464
+ currency: z17.string().length(3),
4465
+ sellable: z17.boolean()
4466
+ })
4399
4467
  });
4400
- var USAGE_METRICS = ["messages", "contacts", "members", "providers", "webhook_endpoints", "active_automations"];
4401
- var UsageMetric = z16.enum(USAGE_METRICS);
4468
+ var MAX_EXTRA_SENDING_DOMAINS = 100;
4469
+ var ExtraSendingDomainsUpdate = z17.object({ quantity: z17.number().int().min(0).max(MAX_EXTRA_SENDING_DOMAINS) });
4470
+ var USAGE_METRICS = ["messages", "contacts", "members", "providers", "webhook_endpoints", "active_automations", "sending_domains"];
4471
+ var UsageMetric = z17.enum(USAGE_METRICS);
4402
4472
  var USAGE_WARNING_RATIO = 0.8;
4403
- var UsageWarning = z16.object({
4473
+ var UsageWarning = z17.object({
4404
4474
  metric: UsageMetric,
4405
- used: z16.number().int().min(0),
4406
- limit: z16.number().int().min(0),
4475
+ used: z17.number().int().min(0),
4476
+ limit: z17.number().int().min(0),
4407
4477
  /** `approaching`: at or above USAGE_WARNING_RATIO of the limit; `reached`: at or above the limit. */
4408
- level: z16.enum(["approaching", "reached"])
4478
+ level: z17.enum(["approaching", "reached"])
4409
4479
  });
4410
- var Usage = z16.object({
4480
+ var Usage = z17.object({
4411
4481
  plan: PlanId,
4412
4482
  period_start: Timestamp,
4413
4483
  period_end: Timestamp,
4414
- metrics: z16.record(UsageMetric, z16.object({ used: z16.number().int().min(0), limit: z16.number().int().min(0).nullable() })),
4415
- warnings: z16.array(UsageWarning)
4484
+ metrics: z17.record(UsageMetric, z17.object({ used: z17.number().int().min(0), limit: z17.number().int().min(0).nullable() })),
4485
+ warnings: z17.array(UsageWarning)
4416
4486
  });
4417
- var CheckoutRequest = z16.object({
4418
- plan: z16.enum(["starter", "growth"]),
4419
- success_url: z16.string().url(),
4420
- cancel_url: z16.string().url()
4487
+ var CheckoutRequest = z17.object({
4488
+ plan: z17.enum(["starter", "growth"]),
4489
+ success_url: z17.string().url(),
4490
+ cancel_url: z17.string().url()
4421
4491
  });
4422
- var CheckoutSession = z16.object({ url: z16.string().url() });
4423
- var PortalRequest = z16.object({ return_url: z16.string().url() });
4424
- var PortalSession = z16.object({ url: z16.string().url() });
4492
+ var CheckoutSession = z17.object({ url: z17.string().url() });
4493
+ var PortalRequest = z17.object({ return_url: z17.string().url() });
4494
+ var PortalSession = z17.object({ url: z17.string().url() });
4425
4495
  var USAGE_WARNING_HEADER = "x-mail-usage-warning";
4426
4496
  function formatUsageWarningHeader(warnings) {
4427
4497
  if (warnings.length === 0) return null;
@@ -4441,7 +4511,7 @@ function parseUsageWarningHeader(value) {
4441
4511
  }
4442
4512
 
4443
4513
  // src/routes.ts
4444
- import { z as z17 } from "zod";
4514
+ import { z as z18 } from "zod";
4445
4515
  var list = (item) => page(item);
4446
4516
  var foundationRoutes = {
4447
4517
  "workspaces.create": {
@@ -4687,7 +4757,7 @@ var templateRoutes = {
4687
4757
  path: "/v1/templates/:id/export",
4688
4758
  params: IdParams,
4689
4759
  query: TemplateExportQuery,
4690
- response: z17.string(),
4760
+ response: z18.string(),
4691
4761
  responseType: "text",
4692
4762
  status: 200,
4693
4763
  access: "read",
@@ -4868,6 +4938,62 @@ var sendingRoutes = {
4868
4938
  access: "read",
4869
4939
  phase: "S2"
4870
4940
  },
4941
+ // Managed sending domains (docs/plans/2026-10-18-managed-sending-domains.md).
4942
+ "sendingDomains.list": {
4943
+ method: "GET",
4944
+ path: "/v1/sending-domains",
4945
+ query: PageQuery,
4946
+ response: list(SendingDomain),
4947
+ status: 200,
4948
+ access: "read",
4949
+ phase: "S2"
4950
+ },
4951
+ "sendingDomains.create": {
4952
+ method: "POST",
4953
+ path: "/v1/sending-domains",
4954
+ body: SendingDomainCreate,
4955
+ response: SendingDomain,
4956
+ status: 201,
4957
+ access: "admin",
4958
+ phase: "S2"
4959
+ },
4960
+ "sendingDomains.get": {
4961
+ method: "GET",
4962
+ path: "/v1/sending-domains/:id",
4963
+ params: IdParams,
4964
+ response: SendingDomain,
4965
+ status: 200,
4966
+ access: "read",
4967
+ phase: "S2"
4968
+ },
4969
+ "sendingDomains.update": {
4970
+ method: "PATCH",
4971
+ path: "/v1/sending-domains/:id",
4972
+ params: IdParams,
4973
+ body: SendingDomainUpdate,
4974
+ response: SendingDomain,
4975
+ status: 200,
4976
+ access: "admin",
4977
+ phase: "S2"
4978
+ },
4979
+ "sendingDomains.check": {
4980
+ method: "POST",
4981
+ path: "/v1/sending-domains/:id/check",
4982
+ params: IdParams,
4983
+ response: SendingDomain,
4984
+ status: 200,
4985
+ access: "admin",
4986
+ phase: "S2"
4987
+ },
4988
+ "sendingDomains.delete": {
4989
+ method: "DELETE",
4990
+ path: "/v1/sending-domains/:id",
4991
+ params: IdParams,
4992
+ response: Ok,
4993
+ status: 200,
4994
+ access: "admin",
4995
+ phase: "S2"
4996
+ },
4871
4997
  "topics.list": {
4872
4998
  method: "GET",
4873
4999
  path: "/v1/topics",
@@ -5011,7 +5137,7 @@ var sendingRoutes = {
5011
5137
  path: "/v1/mailings/:id/export",
5012
5138
  params: IdParams,
5013
5139
  query: MailingExportQuery,
5014
- response: z17.string(),
5140
+ response: z18.string(),
5015
5141
  responseType: "text",
5016
5142
  status: 200,
5017
5143
  access: "read",
@@ -5278,7 +5404,7 @@ var platformRoutes = {
5278
5404
  "contactProperties.list": {
5279
5405
  method: "GET",
5280
5406
  path: "/v1/contact-properties",
5281
- response: z17.object({ data: z17.array(ContactPropertyDefinition) }),
5407
+ response: z18.object({ data: z18.array(ContactPropertyDefinition) }),
5282
5408
  status: 200,
5283
5409
  access: "read",
5284
5410
  phase: "S4"
@@ -5577,7 +5703,7 @@ var billingRoutes = {
5577
5703
  "billing.plans": {
5578
5704
  method: "GET",
5579
5705
  path: "/v1/billing/plans",
5580
- response: z17.object({ data: z17.array(CatalogPlan) }),
5706
+ response: z18.object({ data: z18.array(CatalogPlan), addons: BillingAddons }),
5581
5707
  status: 200,
5582
5708
  access: "read",
5583
5709
  phase: "S5"
@@ -5608,6 +5734,15 @@ var billingRoutes = {
5608
5734
  status: 200,
5609
5735
  access: "admin",
5610
5736
  phase: "S5"
5737
+ },
5738
+ "billing.setExtraSendingDomains": {
5739
+ method: "PUT",
5740
+ path: "/v1/billing/extra-sending-domains",
5741
+ body: ExtraSendingDomainsUpdate,
5742
+ response: Subscription,
5743
+ status: 200,
5744
+ access: "admin",
5745
+ phase: "S5"
5611
5746
  }
5612
5747
  };
5613
5748
  var inviteRoutes = {
@@ -5719,7 +5854,7 @@ var automationRoutes = {
5719
5854
  method: "POST",
5720
5855
  path: "/v1/automations/:id/pause",
5721
5856
  params: IdParams,
5722
- body: z17.object({}).strict(),
5857
+ body: z18.object({}).strict(),
5723
5858
  response: Automation,
5724
5859
  status: 200,
5725
5860
  access: "write",
@@ -5729,7 +5864,7 @@ var automationRoutes = {
5729
5864
  method: "POST",
5730
5865
  path: "/v1/automations/:id/resume",
5731
5866
  params: IdParams,
5732
- body: z17.object({}).strict(),
5867
+ body: z18.object({}).strict(),
5733
5868
  response: Automation,
5734
5869
  status: 200,
5735
5870
  access: "write",
@@ -5739,7 +5874,7 @@ var automationRoutes = {
5739
5874
  method: "POST",
5740
5875
  path: "/v1/automations/:id/archive",
5741
5876
  params: IdParams,
5742
- body: z17.object({}).strict(),
5877
+ body: z18.object({}).strict(),
5743
5878
  response: Automation,
5744
5879
  status: 200,
5745
5880
  access: "write",
@@ -5857,7 +5992,7 @@ var routes = {
5857
5992
  ...automationRoutes
5858
5993
  };
5859
5994
  var TRUSTED_APP_OPERATIONS = {
5860
- booking: ["workspaces.list", "workspace.update", "providers.list", "apiKeys.create", "apiKeys.revoke"]
5995
+ booking: ["workspaces.list", "workspace.update", "providers.list", "sendingDomains.list", "apiKeys.create", "apiKeys.revoke"]
5861
5996
  };
5862
5997
  function trustedAppMayCall(app, id) {
5863
5998
  return TRUSTED_APP_OPERATIONS[app].includes(id);
@@ -5981,6 +6116,7 @@ export {
5981
6116
  AutomationWithFlow,
5982
6117
  BEARER_PREFIX,
5983
6118
  BILLING_NOT_CONFIGURED_REASON,
6119
+ BillingAddons,
5984
6120
  BoundedAutomationFilter,
5985
6121
  BoundedSegmentFilter,
5986
6122
  COMPANY_GRANT_ROLES,
@@ -6037,6 +6173,7 @@ export {
6037
6173
  EventListQuery,
6038
6174
  EventName,
6039
6175
  ExportFormat,
6176
+ ExtraSendingDomainsUpdate,
6040
6177
  FILTER_FIELD_OPERATORS,
6041
6178
  FILTER_OPERATORS,
6042
6179
  FilterCondition,
@@ -6103,6 +6240,7 @@ export {
6103
6240
  MAX_DOCUMENT_BYTES,
6104
6241
  MAX_ENGAGEMENT_DAYS,
6105
6242
  MAX_EXPORT_WARNINGS_HEADER_LENGTH,
6243
+ MAX_EXTRA_SENDING_DOMAINS,
6106
6244
  MAX_FILTER_DEPTH,
6107
6245
  MAX_IMPORTED_REMOTE_IMAGES,
6108
6246
  MAX_IMPORT_BYTES,
@@ -6244,6 +6382,9 @@ export {
6244
6382
  ResolveProblem,
6245
6383
  ResolvedRecipient,
6246
6384
  ResolvedValue,
6385
+ SENDING_DOMAIN_DNS_MODES,
6386
+ SENDING_DOMAIN_REGION,
6387
+ SENDING_DOMAIN_STATUSES,
6247
6388
  SERVICE_FILLED_MERGE_FIELDS,
6248
6389
  SIGNUP_FORM_FIELDS,
6249
6390
  SKIP_REASONS,
@@ -6259,6 +6400,13 @@ export {
6259
6400
  SegmentFilter,
6260
6401
  SegmentPreview,
6261
6402
  SegmentPreviewRequest,
6403
+ SendingDomain,
6404
+ SendingDomainCreate,
6405
+ SendingDomainDnsMode,
6406
+ SendingDomainName,
6407
+ SendingDomainRecord,
6408
+ SendingDomainStatus,
6409
+ SendingDomainUpdate,
6262
6410
  SignupForm,
6263
6411
  SignupFormCreate,
6264
6412
  SignupFormEmbed,