samva 0.8.0 → 0.10.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.
Files changed (53) hide show
  1. package/README.md +1 -1
  2. package/dist/client/sdk.gen.d.ts +1 -13
  3. package/dist/client/types.gen.d.ts +1357 -1484
  4. package/dist/{client-attribution-N5A784Zo.js → client-attribution-Bl4nTEsE.js} +2 -2
  5. package/dist/{client-ByJHYp7r.js → client-mI4S99Ts.js} +1848 -1965
  6. package/dist/effect/analytics.d.ts +6 -6
  7. package/dist/effect/analytics.js +1 -1
  8. package/dist/effect/api-keys.d.ts +11 -11
  9. package/dist/effect/api-keys.js +1 -1
  10. package/dist/effect/attachments.d.ts +4 -4
  11. package/dist/effect/attachments.js +1 -1
  12. package/dist/effect/brands.d.ts +6 -6
  13. package/dist/effect/brands.js +2 -2
  14. package/dist/effect/campaigns.d.ts +18 -18
  15. package/dist/effect/campaigns.js +1 -1
  16. package/dist/effect/client.js +1 -1
  17. package/dist/effect/contact-groups.d.ts +14 -14
  18. package/dist/effect/contact-groups.js +1 -1
  19. package/dist/effect/contacts.d.ts +19 -19
  20. package/dist/effect/contacts.js +1 -1
  21. package/dist/effect/conversations.d.ts +11 -11
  22. package/dist/effect/conversations.js +1 -1
  23. package/dist/effect/custom-fields.d.ts +6 -6
  24. package/dist/effect/custom-fields.js +1 -1
  25. package/dist/effect/email.d.ts +66 -66
  26. package/dist/effect/email.js +2 -2
  27. package/dist/effect/generated.d.ts +1287 -1634
  28. package/dist/effect/index.js +1 -1
  29. package/dist/effect/internal/client.d.ts +2 -2
  30. package/dist/effect/internal/operation.d.ts +3 -3
  31. package/dist/effect/media.d.ts +5 -5
  32. package/dist/effect/media.js +1 -1
  33. package/dist/effect/messages.d.ts +10 -10
  34. package/dist/effect/messages.js +1 -1
  35. package/dist/effect/operations.d.ts +3 -3
  36. package/dist/effect/operations.js +1 -1
  37. package/dist/effect/organizations.d.ts +6 -6
  38. package/dist/effect/organizations.js +1 -1
  39. package/dist/effect/scheduled-messages.d.ts +7 -7
  40. package/dist/effect/scheduled-messages.js +1 -1
  41. package/dist/effect/templates.d.ts +36 -123
  42. package/dist/effect/templates.js +3 -5
  43. package/dist/effect/unsubscribe-groups.d.ts +13 -13
  44. package/dist/effect/unsubscribe-groups.js +1 -1
  45. package/dist/effect/webhooks.d.ts +12 -12
  46. package/dist/effect/webhooks.js +2 -2
  47. package/dist/index.js +1 -1
  48. package/dist/{operation-D2nEeKBD.js → operation-DQWJO4jY.js} +2 -6
  49. package/dist/promises/index.js +1 -1
  50. package/dist/promises/types.gen.d.ts +1 -1
  51. package/dist/{promises-DAv8ZtOX.js → promises-C7D4oaHn.js} +2 -45
  52. package/dist/service-map.d.ts +0 -5
  53. package/package.json +8 -8
@@ -1,199 +1,94 @@
1
1
  export type ClientOptions = {
2
2
  baseUrl: "https://api.samva.dev" | (string & {});
3
3
  };
4
- export type ConversationId = string;
5
- export type ContactId = string;
6
- /**
7
- * Requested per-send engagement tracking policy. Recipient opt-out takes precedence, then explicit fields, organization defaults, and product defaults.
8
- */
9
- export type EmailTrackingOverrideV1 = {
10
- /**
11
- * Override open tracking for this send. Omit to inherit the organization default. A recipient tracking opt-out always disables tracking.
12
- */
13
- opens?: boolean | undefined;
14
- /**
15
- * Override click tracking for this send. Omit to inherit the organization default. A recipient tracking opt-out always disables tracking.
16
- */
17
- clicks?: boolean | undefined;
4
+ export type GatewayTimeoutError = {
5
+ _tag: "GatewayTimeoutError";
6
+ message: string;
7
+ retryAfterSeconds: number;
18
8
  };
19
- export type MediaId = string;
20
- export type MessageContent = {
21
- text?: string | null | undefined;
22
- html?: string | null | undefined;
23
- markdown?: string | null | undefined;
24
- email?: {
25
- subject?: string | null | undefined;
26
- html?: string | null | undefined;
27
- text?: string | null | undefined;
28
- headers?: {
29
- [key: string]: string;
30
- } | null | undefined;
31
- tracking?: EmailTrackingOverrideV1 | undefined;
32
- attachments?: Array<{
33
- filename: string;
34
- content?: string | null | undefined;
35
- mediaId?: MediaId | null | undefined;
36
- contentType: string;
37
- size: number;
38
- }> | null | undefined;
39
- } | null | undefined;
40
- metadata?: {
41
- [key: string]: JsonValue;
42
- } | null | undefined;
9
+ export type UnauthorizedError = {
10
+ _tag: "UnauthorizedError";
11
+ message: string;
12
+ };
13
+ export type ForbiddenError = {
14
+ _tag: "ForbiddenError";
15
+ message: string;
16
+ };
17
+ export type InternalError = {
18
+ _tag: "InternalError";
19
+ message: string;
20
+ };
21
+ export type ResourceNotFoundError = {
22
+ _tag: "ResourceNotFoundError";
23
+ resource: string;
24
+ id: string;
43
25
  };
44
26
  export type ApiKeyId = string;
45
- export type SubmissionCredential = {
46
- kind: "api_key";
47
- apiKeyId: ApiKeyId | null;
48
- } | {
49
- kind: "oauth";
50
- clientId: string | null;
51
- } | {
52
- kind: "session";
27
+ export type BillingProviderError = {
28
+ _tag: "BillingProviderError";
29
+ message: string;
53
30
  };
54
- export type UserId = string;
55
- export type SubmissionClient = {
56
- surface: "typescript-promise" | "typescript-effect" | "cli" | "mcp";
57
- version: string;
31
+ export type SuccessResponse = {
32
+ success: boolean;
58
33
  };
59
- export type MessageSubmission = {
60
- origin: "direct" | "campaign" | "scheduled";
61
- transport: "http" | null;
62
- credential: SubmissionCredential | null;
63
- userId: UserId | null;
64
- client: SubmissionClient | null;
34
+ export type ValidationError = {
35
+ _tag: "ValidationError";
36
+ message: string;
37
+ fields?: {
38
+ [key: string]: Array<string>;
39
+ } | null | undefined;
65
40
  };
66
- export type MessageContact = {
41
+ export type ApiKeyWithSecret = {
67
42
  id: string;
68
43
  name: string;
69
- displayName: string | null;
70
- type: string;
71
- identities: Array<{
72
- channel: "email";
73
- identifier: string;
74
- verified: boolean;
75
- }>;
44
+ key: string;
45
+ start: string | null;
46
+ description?: string | null | undefined;
47
+ createdAt: string;
48
+ expiresAt: string | null;
49
+ lastUsedAt: string | null;
50
+ isActive: boolean;
51
+ access: ApiKeyAccess;
52
+ owner: ApiKeyOwner | null;
76
53
  };
77
- export type DeliveryErrorDetails = {
78
- code?: string | null | undefined;
79
- name?: string | null | undefined;
80
- message?: string | null | undefined;
81
- details?: {
82
- [key: string]: string | number | null;
83
- } | null | undefined;
84
- retryable?: boolean | null | undefined;
54
+ export type ApiKeyOwner = {
55
+ id: string;
56
+ name: string;
57
+ email: string;
85
58
  };
86
- export type JsonObject = {
87
- [key: string]: JsonValue;
59
+ export type ApiKeyAccess = {
60
+ mode: "full";
61
+ } | {
62
+ mode: "restricted";
63
+ resources: ApiKeyResourceAccess;
88
64
  };
89
- export type Message = {
65
+ export type ApiKeyResourceAccess = {
66
+ messages?: "read" | "write" | null | undefined;
67
+ email?: "read" | "write" | null | undefined;
68
+ domains?: "read" | "write" | null | undefined;
69
+ phoneNumbers?: "read" | "write" | null | undefined;
70
+ contacts?: "read" | "write" | null | undefined;
71
+ conversations?: "read" | "write" | null | undefined;
72
+ templates?: "read" | "write" | null | undefined;
73
+ competitors?: "read" | "write" | null | undefined;
74
+ webhooks?: "read" | "write" | null | undefined;
75
+ apiKeys?: "read" | "write" | null | undefined;
76
+ organization?: "read" | "write" | null | undefined;
77
+ billing?: "read" | "write" | null | undefined;
78
+ analytics?: "read" | "write" | null | undefined;
79
+ };
80
+ export type ApiKey = {
90
81
  id: string;
91
- organizationId: string;
92
- conversationId: string | null;
93
- parentMessageId: string | null;
94
- fromActorId: string;
95
- actorMetadata: {
96
- [key: string]: JsonValue;
97
- } | null;
98
- channel: "email";
99
- direction: "outbound" | "inbound";
100
- content: MessageContent;
101
- metadata: {
102
- [key: string]: JsonValue;
103
- } | null;
104
- status: "pending" | "scheduled" | "queued" | "processing" | "sent" | "delivered" | "read" | "failed" | "bounced" | "complained";
105
- scheduledAt: string | null;
106
- tags: Array<string>;
107
- categories: Array<string>;
108
- isTest: boolean;
109
- externalId: string | null;
110
- referenceId: string | null;
111
- submission: MessageSubmission | null;
82
+ name: string;
83
+ key?: string | null | undefined;
84
+ start: string | null;
85
+ description?: string | null | undefined;
112
86
  createdAt: string;
113
- updatedAt: string;
114
- fromContact: MessageContact | null;
115
- toContacts: Array<MessageContact>;
116
- recipients: Array<{
117
- id: string;
118
- messageId: string;
119
- actorId: string | null;
120
- contactId: string | null;
121
- identityId: string | null;
122
- kind: "to" | "cc" | "bcc";
123
- address: string;
124
- status: "pending" | "scheduled" | "queued" | "processing" | "sent" | "delivered" | "read" | "failed" | "bounced" | "complained";
125
- createdAt: string;
126
- updatedAt: string;
127
- contact: MessageContact | null;
128
- }>;
129
- deliveries: Array<{
130
- scheduling: {
131
- dueAt: string;
132
- expiresAt: string;
133
- waitReason: "rate" | "daily-quota" | "domain-health" | "sending-paused" | "upstream-unavailable" | "retry" | "campaign-paused" | "domain-warming" | "onboarding-review" | "content-review" | null;
134
- reviewExpectedAt: string | null;
135
- } | null;
136
- id: string;
137
- messageId: string;
138
- recipientId: string | null;
139
- channel: "email";
140
- status: "pending" | "scheduled" | "queued" | "processing" | "sent" | "delivered" | "read" | "failed" | "bounced" | "complained";
141
- attemptCount: number;
142
- maxAttempts: number;
143
- queuedAt: string | null;
144
- claimedAt: string | null;
145
- lastAttemptAt: string | null;
146
- nextRetryAt: string | null;
147
- sentAt: string | null;
148
- deliveredAt: string | null;
149
- readAt: string | null;
150
- failedAt: string | null;
151
- terminalAt: string | null;
152
- errorCode: string | null;
153
- errorMessage: string | null;
154
- errorDetails: DeliveryErrorDetails | null;
155
- cost: string;
156
- currency: string;
157
- idempotencyKey: string | null;
158
- createdAt: string;
159
- updatedAt: string;
160
- }>;
161
- emailDeliveryDetails: Array<{
162
- deliveryId: string;
163
- messageIdHeader: string;
164
- inReplyTo: string | null;
165
- references: Array<string> | null;
166
- subject: string;
167
- fromEmail: string;
168
- fromName: string | null;
169
- toEmails: Array<string>;
170
- toName: string | null;
171
- ccEmails: Array<string> | null;
172
- bccEmails: Array<string> | null;
173
- replyToEmails: Array<string> | null;
174
- hasAttachments: boolean;
175
- attachmentCount: number;
176
- listUnsubscribeUrl: string | null;
177
- listUnsubscribeEmail: string | null;
178
- threadPosition: number | null;
179
- newContent: string | null;
180
- quotedContent: string | null;
181
- hasQuotedContent: boolean;
182
- dkimVerdict: string | null;
183
- spfVerdict: string | null;
184
- dmarcVerdict: string | null;
185
- isAutoReply: boolean;
186
- autoReplyReason: "out-of-office" | "auto-response" | "delivery-status" | "read-receipt" | null;
187
- priority: string | null;
188
- parsingErrors: Array<string> | null;
189
- parsingDuration: number | null;
190
- receivedAt: string | null;
191
- processedAt: string | null;
192
- createdAt: string;
193
- updatedAt: string;
194
- }>;
195
- waitReason: "rate" | "daily-quota" | "domain-health" | "sending-paused" | "upstream-unavailable" | "retry" | "campaign-paused" | "domain-warming" | "onboarding-review" | "content-review" | null;
196
- reviewExpectedAt: string | null;
87
+ expiresAt: string | null;
88
+ lastUsedAt: string | null;
89
+ isActive: boolean;
90
+ access: ApiKeyAccess;
91
+ owner: ApiKeyOwner | null;
197
92
  };
198
93
  export type PaginationMeta = {
199
94
  page: number;
@@ -201,163 +96,29 @@ export type PaginationMeta = {
201
96
  total: number;
202
97
  totalPages: number;
203
98
  };
204
- export type InternalError = {
205
- _tag: "InternalError";
206
- message: string;
207
- };
208
- export type ForbiddenError = {
209
- _tag: "ForbiddenError";
210
- message: string;
211
- };
212
- export type UnauthorizedError = {
213
- _tag: "UnauthorizedError";
214
- message: string;
215
- };
216
- export type GatewayTimeoutError = {
217
- _tag: "GatewayTimeoutError";
218
- message: string;
219
- retryAfterSeconds: number;
220
- };
221
- export type MessageId = string;
222
- export type ResourceNotFoundError = {
223
- _tag: "ResourceNotFoundError";
224
- resource: string;
225
- id: string;
226
- };
227
- export type EmailAddress = {
228
- email: string;
229
- name: string | null;
230
- };
231
- export type AttachmentId = string;
232
- export type MessageMetadata = {
233
- [key: string]: JsonValue;
234
- } | null;
235
- export type EmailRecipient = {
236
- contactId: ContactId;
237
- } | {
238
- email: string;
239
- name?: string | null | undefined;
240
- displayName?: string | null | null | undefined;
241
- };
242
- export type EmailRecipients = Array<EmailRecipient>;
243
- export type EmailCcRecipients = Array<EmailRecipient> | null | null;
244
- export type EmailBccRecipients = Array<EmailRecipient> | null | null;
245
- export type EmailSender = {
246
- email: string;
247
- name?: string | null | undefined;
248
- } | null;
249
- export type EmailAttachment = {
250
- filename: string;
251
- content?: string | null | undefined;
252
- mediaId?: MediaId | null | undefined;
253
- contentType: string;
254
- size: number;
255
- };
256
- export type EmailAttachments = Array<EmailAttachment> | null;
257
- export type TemplatePublicationId = string;
258
- export type TemplateInputContractId = string;
259
- export type TemplateId = string;
260
- export type TemplateData = JsonObject | null;
261
- export type RenderLocale = string;
262
- export type RenderTimeZone = string;
263
- export type ReplyToAddresses = Array<string> | null | null;
264
- export type UnsubscribeId = string;
265
- export type EmailFooterOverride = {
266
- enabled?: boolean | null | undefined;
267
- };
268
- export type EmailContent = {
269
- subject?: string | null | undefined;
270
- html?: string | null | undefined;
271
- text?: string | null | undefined;
272
- attachments?: EmailAttachments | undefined;
273
- publicationId?: TemplatePublicationId | undefined;
274
- inputContractId?: TemplateInputContractId | undefined;
275
- templateId?: TemplateId | null | undefined;
276
- templateSlug?: string | null | undefined;
277
- templateData?: TemplateData | undefined;
278
- locale?: RenderLocale | undefined;
279
- timeZone?: RenderTimeZone | undefined;
280
- inReplyToMessageId?: MessageId | null | undefined;
281
- replyTo?: ReplyToAddresses | undefined;
282
- unsubscribeGroupId?: UnsubscribeId | null | undefined;
283
- tracking?: EmailTrackingOverrideV1 | undefined;
284
- footer?: EmailFooterOverride | undefined;
285
- };
286
- export type EmailSendMessagePayload = {
287
- conversationId?: ConversationId | null | null | undefined;
288
- metadata?: MessageMetadata | undefined;
289
- channel: "email";
290
- to: EmailRecipients;
291
- cc?: EmailCcRecipients | undefined;
292
- bcc?: EmailBccRecipients | undefined;
293
- from?: EmailSender | undefined;
294
- email: EmailContent;
295
- };
296
- export type SendMessagePayload = EmailSendMessagePayload;
297
- export type ConflictError = {
298
- _tag: "ConflictError";
299
- message: string;
300
- resource: string;
301
- id?: string | null | undefined;
302
- };
303
- export type RateLimitedError = {
304
- _tag: "RateLimitedError";
305
- retryAfterSeconds: number;
306
- };
307
99
  export type PaymentRequiredError = {
308
100
  _tag: "PaymentRequiredError";
309
101
  resource: string;
310
102
  currentUsage: number;
311
103
  limit: number;
312
104
  };
313
- export type BillingProviderError = {
314
- _tag: "BillingProviderError";
315
- message: string;
316
- };
317
- export type ExternalServiceError = {
318
- _tag: "ExternalServiceError";
319
- message: string;
320
- };
321
- export type ValidationError = {
322
- _tag: "ValidationError";
323
- message: string;
324
- fields?: {
325
- [key: string]: Array<string>;
326
- } | null | undefined;
327
- };
328
- export type OnboardingReviewRequiredError = {
329
- _tag: "OnboardingReviewRequiredError";
330
- code: "review_required" | "review_in_progress" | "information_required" | "review_rejected" | "identity_review_required" | "identity_review_rejected" | "identity_changed";
331
- decision: "undecided" | "approved" | "rejected";
332
- stage: "collecting" | "automated_review" | "manual_review" | "information_requested" | "complete";
333
- nextAction: "wait_for_review" | "provide_information" | "verify_sending_identity" | "reapply" | "contact_support";
334
- identityId?: string | null | undefined;
335
- };
336
- export type FlagDisabledError = {
337
- _tag: "FlagDisabledError";
338
- flag: string;
339
- };
340
- export type DeliveryUnavailableError = {
341
- _tag: "DeliveryUnavailableError";
105
+ export type ConflictError = {
106
+ _tag: "ConflictError";
342
107
  message: string;
343
- retryAfterSeconds: number;
108
+ resource: string;
109
+ id?: string | null | undefined;
344
110
  };
345
- export type ValidateEmailResponse = {
346
- valid: true;
347
- from: {
348
- email: string;
349
- name: string | null;
350
- };
351
- recipientCount: number;
352
- content: {
353
- source: "inline" | "template";
354
- subject: string;
355
- hasHtml: boolean;
356
- hasText: boolean;
111
+ export type OperationAccepted = {
112
+ operation: Operation;
113
+ links: {
114
+ self: string;
115
+ resource: OperationResourceLink;
357
116
  };
358
117
  };
359
- export type MessageEventId = string;
360
- export type OperationId = string;
118
+ export type OperationResourceLink = {
119
+ resource: OperationResource;
120
+ href: string;
121
+ };
361
122
  export type OperationResource = {
362
123
  type: string;
363
124
  id: string;
@@ -382,648 +143,438 @@ export type Operation = {
382
143
  startedAt: string | null;
383
144
  completedAt: string | null;
384
145
  };
385
- export type OperationResourceLink = {
386
- resource: OperationResource;
387
- href: string;
388
- };
389
- export type OperationAccepted = {
390
- operation: Operation;
391
- links: {
392
- self: string;
393
- resource: OperationResourceLink;
394
- };
395
- };
396
- export type EmailDispatchContent = {
397
- subject?: string | null | undefined;
398
- html?: string | null | undefined;
399
- text?: string | null | undefined;
400
- attachments?: EmailAttachments | undefined;
401
- publicationId?: TemplatePublicationId | undefined;
402
- inputContractId?: TemplateInputContractId | undefined;
403
- templateId?: TemplateId | null | undefined;
404
- templateSlug?: string | null | undefined;
405
- templateData?: TemplateData | undefined;
406
- locale?: RenderLocale | undefined;
407
- timeZone?: RenderTimeZone | undefined;
408
- inReplyToMessageId?: MessageId | null | undefined;
409
- replyTo?: ReplyToAddresses | undefined;
410
- unsubscribeGroupId?: UnsubscribeId | null | undefined;
411
- tracking?: EmailTrackingOverrideV1 | undefined;
412
- footer?: EmailFooterOverride | undefined;
413
- };
414
- export type EmailDispatchSendMessagePayload = {
415
- conversationId?: ConversationId | null | null | undefined;
416
- metadata?: MessageMetadata | undefined;
417
- channel: "email";
418
- to: EmailRecipients;
419
- cc?: EmailCcRecipients | undefined;
420
- bcc?: EmailBccRecipients | undefined;
421
- from?: EmailSender | undefined;
422
- email: EmailDispatchContent;
423
- };
424
- export type DispatchSendMessagePayload = EmailDispatchSendMessagePayload;
425
- export type IanaTimezone = string;
426
- export type ScheduledMessageId = string;
427
- export type ScheduledMessage = {
428
- id: ScheduledMessageId;
429
- status: "pending" | "dispatching" | "paused" | "dispatched" | "cancelled" | "failed";
430
- scheduledFor: string;
146
+ export type OperationId = string;
147
+ export type Organization = {
148
+ id: string;
149
+ billingAccountId: string;
150
+ name: string;
151
+ slug: string;
152
+ countryCode: string;
431
153
  timezone: string;
432
- send: SendMessagePayload;
433
- messageId: MessageId | null;
434
- idempotencyKey: string | null;
435
- referenceId: string | null;
436
- failureReason: string | null;
437
- attempts: number;
438
- createdBy: string | null;
439
- actorEmail: string;
440
- memberRole: string;
154
+ plan: string;
155
+ isActive: boolean;
441
156
  createdAt: string;
442
157
  updatedAt: string;
158
+ metadata: {
159
+ [key: string]: JsonValue;
160
+ } | null;
161
+ replyToDefault: Array<string> | null;
162
+ emailFooterEnabledDefault: boolean | null;
163
+ messagesUsed: number;
164
+ messagesUsedThisMonth: number;
165
+ emailUsed: number;
166
+ emailUsedThisMonth: number;
167
+ contactsUsed: number;
168
+ conversationsUsed: number;
169
+ teamMembersUsed: number;
170
+ messagesResetAt: string | null;
443
171
  };
444
- export type CampaignConversationRef = ConversationId | null | null;
445
- export type CampaignContentMetadata = {
446
- [key: string]: JsonValue;
447
- } | null;
448
- export type EmailCampaignContentInput = {
449
- channel: "email";
450
- email: EmailDispatchContent;
451
- conversationId?: CampaignConversationRef | undefined;
452
- metadata?: CampaignContentMetadata | undefined;
172
+ export type IanaTimezone = string;
173
+ export type WebhookEndpointId = string;
174
+ export type WebhookAttemptId = string;
175
+ export type WebhookDeliveryId = string;
176
+ export type WebhookStatsResponse = {
177
+ total: number;
178
+ pending: number;
179
+ delivered: number;
180
+ exhausted: number;
181
+ cancelled: number;
182
+ daily: Array<WebhookDailyDeliveries>;
453
183
  };
454
- export type CampaignContentInput = EmailCampaignContentInput;
455
- export type ContactGroupId = string;
456
- export type CampaignAudience = {
457
- includeTags?: Array<string> | null | undefined;
458
- excludeTags?: Array<string> | null | undefined;
459
- contactIds?: Array<ContactId> | null | undefined;
460
- groupIds?: Array<ContactGroupId> | null | undefined;
461
- };
462
- export type CampaignPolicy = {
463
- unsubscribeGroupId?: UnsubscribeId | null | undefined;
464
- pageSize?: number | null | undefined;
465
- };
466
- export type CampaignId = string;
467
- export type EmailCampaignContent = {
468
- channel: "email";
469
- email: EmailContent;
470
- conversationId?: CampaignConversationRef | undefined;
471
- metadata?: CampaignContentMetadata | undefined;
472
- };
473
- export type CampaignContent = EmailCampaignContent;
474
- export type CampaignDefinitionSummary = {
475
- state: "editable" | "frozen" | "archived";
476
- frozenAt: string | null;
184
+ export type WebhookDailyDeliveries = {
185
+ date: string;
186
+ pending: number;
187
+ delivered: number;
188
+ exhausted: number;
189
+ cancelled: number;
477
190
  };
478
- export type CampaignRunId = string;
479
- export type CampaignLatestRun = {
480
- id: CampaignRunId;
481
- status: "scheduled" | "resolving" | "dispatching" | "paused" | "completed" | "cancelled" | "failed";
482
- scheduledFor: string;
483
- completedAt: string | null;
484
- totalRecipients: number;
485
- dispatchedCount: number;
486
- failedCount: number;
487
- skippedCount: number;
488
- estimatedCompletionAt: string | null;
191
+ export type WebhookEventId = string;
192
+ export type TestWebhookPayload = {
193
+ data?: {
194
+ [key: string]: JsonValue;
195
+ } | null | undefined;
489
196
  };
490
- export type Campaign = {
491
- id: CampaignId;
197
+ export type WebhookEndpoint = {
198
+ id: WebhookEndpointId;
492
199
  name: string;
493
- channel: "email";
494
- content: CampaignContent;
495
- audience: CampaignAudience;
496
- policy: CampaignPolicy;
497
- definition: CampaignDefinitionSummary;
498
- latestRun: CampaignLatestRun | null;
499
- createdBy: string | null;
500
- actorEmail: string;
501
- memberRole: string;
200
+ url: string;
201
+ eventTypes: Array<"message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.bounced" | "message.complained" | "message.received" | "message.opened" | "message.clicked" | "contact.created" | "contact.updated" | "contact.deleted" | "contact.unsubscribed" | "contact.resubscribed" | "conversation.created" | "conversation.updated" | "conversation.archived" | "webhook.created" | "webhook.updated" | "webhook.deleted" | "webhook.test" | "domain.updated" | "domain.warming.updated">;
202
+ channels: Array<"email"> | null;
203
+ status: "active" | "disabled";
204
+ hasCustomHeaders: boolean;
205
+ failureStartedAt: string | null;
206
+ lastSucceededAt: string | null;
502
207
  createdAt: string;
503
208
  updatedAt: string;
504
209
  };
505
- /**
506
- * Daily email sends for the last 14 calendar days in the organization's own timezone, oldest first and zero-filled. Always fourteen entries; an entity that has never sent reports fourteen zeroes.
507
- */
508
- export type SendsSeries = Array<number>;
509
- export type CampaignListItem = {
510
- id: CampaignId;
210
+ export type UpdateWebhookPayload = {
211
+ name?: string | null | undefined;
212
+ url?: string | null | undefined;
213
+ eventTypes?: Array<"message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.bounced" | "message.complained" | "message.received" | "message.opened" | "message.clicked" | "contact.created" | "contact.updated" | "contact.deleted" | "contact.unsubscribed" | "contact.resubscribed" | "conversation.created" | "conversation.updated" | "conversation.archived" | "webhook.created" | "webhook.updated" | "webhook.deleted" | "webhook.test" | "domain.updated" | "domain.warming.updated"> | null | undefined;
214
+ channels?: Array<"email"> | null | null | undefined;
215
+ headers?: {
216
+ [key: string]: string;
217
+ } | null | undefined;
218
+ status?: "active" | "disabled" | null | undefined;
219
+ };
220
+ export type WebhookEndpointListItem = {
221
+ id: WebhookEndpointId;
511
222
  name: string;
512
- channel: "email";
513
- content: CampaignContent;
514
- audience: CampaignAudience;
515
- policy: CampaignPolicy;
516
- definition: CampaignDefinitionSummary;
517
- latestRun: CampaignLatestRun | null;
518
- createdBy: string | null;
519
- actorEmail: string;
520
- memberRole: string;
223
+ url: string;
224
+ eventTypes: Array<"message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.bounced" | "message.complained" | "message.received" | "message.opened" | "message.clicked" | "contact.created" | "contact.updated" | "contact.deleted" | "contact.unsubscribed" | "contact.resubscribed" | "conversation.created" | "conversation.updated" | "conversation.archived" | "webhook.created" | "webhook.updated" | "webhook.deleted" | "webhook.test" | "domain.updated" | "domain.warming.updated">;
225
+ channels: Array<"email"> | null;
226
+ status: "active" | "disabled";
227
+ hasCustomHeaders: boolean;
228
+ failureStartedAt: string | null;
229
+ lastSucceededAt: string | null;
521
230
  createdAt: string;
522
231
  updatedAt: string;
523
- series: SendsSeries;
232
+ deliveries: WebhookDeliveryCounts;
524
233
  };
525
- export type EmailDomainId = string;
526
- export type CampaignRun = {
527
- id: CampaignRunId;
528
- campaignId: CampaignId;
529
- status: "scheduled" | "resolving" | "dispatching" | "paused" | "completed" | "cancelled" | "failed";
530
- scheduledFor: string;
531
- idempotencyKey: string | null;
532
- startedAt: string | null;
533
- completedAt: string | null;
534
- contentSnapshot: CampaignContent;
535
- audienceSnapshot: CampaignAudience;
536
- policySnapshot: CampaignPolicy;
537
- totalRecipients: number;
538
- dispatchedCount: number;
539
- failedCount: number;
540
- skippedCount: number;
541
- estimatedCompletionAt: string | null;
542
- failureReason: string | null;
543
- holdReason: string | null;
544
- holdDomainId: EmailDomainId | null;
545
- lastContactId: string | null;
546
- createdBy: string | null;
547
- actorEmail: string;
548
- memberRole: string;
234
+ export type WebhookDeliveryCounts = {
235
+ total: number;
236
+ pending: number;
237
+ delivered: number;
238
+ exhausted: number;
239
+ cancelled: number;
240
+ };
241
+ export type CreateWebhookPayload = {
242
+ name: string;
243
+ url: string;
244
+ eventTypes: Array<"message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.bounced" | "message.complained" | "message.received" | "message.opened" | "message.clicked" | "contact.created" | "contact.updated" | "contact.deleted" | "contact.unsubscribed" | "contact.resubscribed" | "conversation.created" | "conversation.updated" | "conversation.archived" | "webhook.created" | "webhook.updated" | "webhook.deleted" | "webhook.test" | "domain.updated" | "domain.warming.updated">;
245
+ channels?: Array<"email"> | null | undefined;
246
+ headers?: {
247
+ [key: string]: string;
248
+ } | null | undefined;
249
+ status?: "active" | "disabled" | null | undefined;
250
+ };
251
+ export type Brand = {
252
+ id: BrandId;
253
+ /**
254
+ * The brand's handle, unique in the organization; `samva:brand/<slug>` names it.
255
+ */
256
+ slug: string;
257
+ name: string;
258
+ /**
259
+ * Whether bare `samva:brand` and domains without a brand resolve to this brand.
260
+ */
261
+ isDefault: boolean;
262
+ /**
263
+ * Brand theme CSS: `@theme` variables, one dark-mode `@theme` of colors, and `@font-face` rules with https WOFF2 sources.
264
+ */
265
+ css: string;
266
+ assets: BrandAssets;
267
+ footer: BrandFooter;
268
+ /**
269
+ * SHA-256 of the brand's css, assets and footer. A publication built against a different digest predates the brand's current content.
270
+ */
271
+ digest: string;
549
272
  createdAt: string;
550
273
  updatedAt: string;
551
274
  };
552
- export type BrandAddressRequiredError = {
553
- _tag: "BrandAddressRequiredError";
554
- message: string;
555
- brand: string | null;
275
+ export type BrandFooter = {
276
+ companyName?: string | null | undefined;
277
+ address?: BrandAddress | null | undefined;
278
+ socialLinks?: Array<BrandSocialLink> | null | undefined;
556
279
  };
557
- export type CampaignFooterRequiredError = {
558
- _tag: "CampaignFooterRequiredError";
559
- message: string;
280
+ export type BrandSocialLink = {
281
+ label: string;
282
+ url: string;
560
283
  };
561
- export type CampaignRunAction = {
562
- success: boolean;
563
- item: CampaignRun;
284
+ export type BrandAddress = {
285
+ street1: string;
286
+ street2?: string | null | undefined;
287
+ city: string;
288
+ region: string;
289
+ postalCode: string;
290
+ country: string;
564
291
  };
565
- export type CampaignRecipientId = string;
566
- export type IdentityClearanceStatus = {
567
- identityId: string;
568
- decision: "undecided" | "approved" | "rejected";
569
- generation: number;
570
- canSend: boolean;
571
- code: "review_required" | "review_in_progress" | "information_required" | "review_rejected" | "identity_review_required" | "identity_review_rejected" | "identity_changed" | null;
572
- nextAction: "wait_for_review" | "provide_information" | "verify_sending_identity" | "reapply" | "contact_support" | null;
573
- updatedAt: string;
292
+ export type BrandAssets = {
293
+ logoUrl?: string | null | undefined;
294
+ logoDarkUrl?: string | null | undefined;
295
+ iconUrl?: string | null | undefined;
574
296
  };
575
- export type OnboardingReviewStatus = {
576
- decision: "undecided" | "approved" | "rejected";
577
- trustTier: "screened" | "probation" | "established";
578
- stage: "collecting" | "automated_review" | "manual_review" | "information_requested" | "complete";
579
- generation: number;
580
- canSend: boolean;
581
- code: "review_required" | "review_in_progress" | "information_required" | "review_rejected" | "identity_review_required" | "identity_review_rejected" | "identity_changed" | null;
582
- nextAction: "wait_for_review" | "provide_information" | "verify_sending_identity" | "reapply" | "contact_support" | null;
583
- canReapply: boolean;
584
- informationRequest: {
585
- id: string;
586
- requestedFields: Array<string>;
587
- requestedAt: string;
588
- canRespond: boolean;
589
- } | null;
590
- identities: Array<IdentityClearanceStatus>;
591
- updatedAt: string | null;
297
+ export type BrandId = string;
298
+ export type UpdateBrand = {
299
+ newSlug?: string | null | undefined;
300
+ name?: string | null | undefined;
301
+ css?: string | null | undefined;
302
+ assets?: BrandAssets | null | undefined;
303
+ footer?: BrandFooter | null | undefined;
592
304
  };
593
- export type ReapplyOnboardingReviewInput = {
594
- expectedGeneration: number;
305
+ export type CreateBrand = {
306
+ slug: string;
307
+ name: string;
308
+ css?: string | null | undefined;
309
+ assets?: BrandAssets | null | undefined;
310
+ footer?: BrandFooter | null | undefined;
311
+ isDefault?: boolean | null | undefined;
595
312
  };
596
- export type RespondToOnboardingInformationRequestInput = {
597
- expectedGeneration: number;
598
- responseText: string;
599
- evidenceMediaIds: Array<MediaId>;
313
+ export type BrandList = {
314
+ items: Array<Brand>;
600
315
  };
601
- export type EmailTrackingDefaults = {
602
- opens: boolean;
603
- clicks: boolean;
316
+ export type UserId = string;
317
+ export type OrganizationId = string;
318
+ export type TemplateProjectId = string;
319
+ export type TemplateId = string;
320
+ export type TemplateInputContractId = string;
321
+ export type BrandRenderedFooter = {
322
+ withUnsubscribe: BrandFooterBlock;
323
+ withoutUnsubscribe: BrandFooterBlock;
604
324
  };
605
- export type TrackingRecipientEmail = string;
606
- export type EmailRecipientTrackingPreference = {
607
- email: TrackingRecipientEmail;
608
- optedOut: boolean;
609
- trackingOptedOutAt: string | null;
610
- createdAt: string | null;
611
- updatedAt: string | null;
612
- };
613
- export type EmailSenderId = string;
614
- /**
615
- * Bounce and complaint rates over the last 24 hours, as fractions between 0 and 1, with `windowSends`, the deliveries they were divided by, plus `sendingStatus`, which says whether the organization can currently send. The window matches the one the sending-pause rule reads. Below 200 sends that rule ignores the window entirely, so a rate over a smaller `windowSends` is a quotient rather than a reading. These are not a lifetime record; an identity with no traffic in the window reports zeroes.
616
- */
617
- export type DeliverabilityFacts = {
618
- bounceRate: number;
619
- complaintRate: number;
620
- windowSends: number;
621
- sendingStatus: "enabled" | "disabled" | "reinstated" | "unknown";
325
+ export type BrandFooterBlock = {
326
+ html: string;
327
+ text: string;
622
328
  };
623
- export type EmailDomainDetailed = {
624
- id: EmailDomainId;
625
- domain: string;
626
- phase: "dns-setup" | "provisioning" | "verifying" | "ready" | "degraded" | "failed";
627
- dkimSelector?: string | null | undefined;
628
- dkimPublicKey?: string | null | undefined;
629
- dnsRecords: Array<{
630
- type: "A" | "AAAA" | "CNAME" | "MX" | "NS" | "SOA" | "PTR" | "SRV" | "TXT" | "CAA";
631
- name: string;
632
- value: string;
633
- ttl?: string | null | undefined;
634
- description?: string | null | undefined;
635
- priority?: number | null | undefined;
636
- }>;
637
- verifiedAt: string | null;
329
+ export type TemplatePublicationId = string;
330
+ export type Template = {
331
+ id: TemplateId;
332
+ organizationId: OrganizationId;
333
+ projectId: TemplateProjectId;
334
+ entryPath: string;
335
+ name: string;
336
+ slug: string;
337
+ familyId: TemplateFamilyId | null;
338
+ channel: "email";
339
+ description: string | null;
340
+ category: string | null;
341
+ fromDefault?: TemplateFromDefault | null | null | undefined;
342
+ replyToDefault?: Array<string> | null | null | undefined;
343
+ trackingDefault?: {
344
+ opens?: boolean | null | undefined;
345
+ clicks?: boolean | null | undefined;
346
+ } | null | null | undefined;
347
+ email: {
348
+ subject: string;
349
+ preheader: string | null;
350
+ headers: {
351
+ [key: string]: string;
352
+ } | null;
353
+ } | null;
354
+ publicationId: TemplatePublicationId | null;
355
+ brand: TemplatePublicationBrand | null;
356
+ inputContractId: TemplateInputContractId | null;
357
+ inputSchema: {
358
+ [key: string]: JsonValue;
359
+ } | null;
360
+ usageCount: number;
361
+ lastUsedAt: string | null;
362
+ status: string;
363
+ isActive: boolean;
638
364
  isDefault: boolean;
639
- defaultSenderId: EmailSenderId | null;
640
- deliverability: DeliverabilityFacts;
365
+ publishedAt?: string | null | null | undefined;
366
+ publishedBy?: string | null | null | undefined;
641
367
  createdAt: string;
642
368
  updatedAt: string;
643
369
  };
644
- export type EmailChannelError = {
645
- _tag: "EmailChannelError";
646
- reason: "transport" | "rejected" | "rate_limited" | "auth";
647
- message: string;
648
- statusCode?: number | null | undefined;
649
- };
650
- export type EmailDomainProvisioningExecution = {
651
- status: "none" | "running" | "succeeded" | "failed";
652
- generation: number;
653
- revision: number;
654
- };
655
- export type EmailDkimRotation = {
656
- id: string;
657
- domainId: EmailDomainId;
658
- phase: "staged" | "cutover" | "complete";
659
- selector: string;
660
- record: {
661
- name: string;
662
- type: "TXT";
663
- value: string;
664
- ttl: string;
665
- };
666
- formerRecord: {
667
- name: string;
668
- type: "TXT";
669
- value: string;
670
- };
370
+ export type TemplatePublicationBrand = {
671
371
  /**
672
- * The earliest time the former DKIM record may be removed. Keep it published at least until then so mail signed with the former key still verifies.
372
+ * The brand the publication imports.
673
373
  */
674
- minimumRetainUntil: string | null;
675
- };
676
- export type EmailDomainVerification = {
677
- domainId: EmailDomainId;
678
- domain: string;
679
- phase: "dns-setup" | "provisioning" | "verifying" | "ready" | "degraded" | "failed";
680
- dns: {
681
- observed: boolean;
682
- total: number;
683
- satisfied: number;
684
- missing: number;
685
- mismatch: number;
686
- unknown: number;
687
- };
688
- requirements: Array<{
689
- key: string;
690
- record: {
691
- type: "A" | "AAAA" | "CNAME" | "MX" | "NS" | "SOA" | "PTR" | "SRV" | "TXT" | "CAA";
692
- name: string;
693
- value: string;
694
- ttl?: string | null | undefined;
695
- description?: string | null | undefined;
696
- priority?: number | null | undefined;
697
- };
698
- status: "satisfied" | "missing" | "mismatch" | "unknown";
699
- evidence: Array<{
700
- _tag: "PublicDns";
701
- resolver: string;
702
- status: "satisfied" | "missing" | "mismatch" | "unknown";
703
- values: Array<string>;
704
- detail: string | null;
705
- observedAt: string;
706
- } | {
707
- _tag: "Provider";
708
- provider: string;
709
- status: "satisfied" | "missing" | "mismatch" | "unknown";
710
- values: Array<string>;
711
- detail: string | null;
712
- observedAt: string;
713
- } | {
714
- _tag: "Host";
715
- source: string;
716
- status: "ok" | "pending" | "failed";
717
- label: string;
718
- detail: string | null;
719
- observedAt: string;
720
- }>;
721
- }>;
722
- provider: {
723
- identity: "pending" | "verified" | "failed" | "unknown";
724
- dkim?: "pending" | "verified" | "failed" | "unknown" | null | undefined;
725
- mailFrom?: "pending" | "verified" | "failed" | "unknown" | null | undefined;
726
- } | null;
727
- operationId: OperationId | null;
728
- checkedAt: string | null;
729
- nextCheckAt: string | null;
730
- failure: {
731
- code: string;
732
- message: string;
733
- failedAt: string;
734
- } | null;
735
- provisioning: EmailDomainProvisioningExecution;
736
- health: {
737
- actionOwner: "customer" | "samva" | "upstream" | "none";
738
- action: string;
739
- freshness: "current" | "stale" | "unknown";
740
- observedAt: string | null;
741
- staleAt: string | null;
742
- nextRetryAt: string | null;
743
- reason: "ready" | "dns-action-required" | "dns-unavailable" | "verification-pending" | "verification-failed" | "samva-repair" | "signing-custody-action-required" | "ownership-conflict" | "inactive" | "observation-stale" | "observation-unknown";
744
- };
374
+ slug: string;
745
375
  /**
746
- * Whether the domain, the organization, and its sending account are healthy enough to send, as last observed. Ready does not guarantee that a particular send is accepted.
376
+ * The brand's digest when the publication was built.
747
377
  */
748
- sending: {
749
- actionOwner: "customer" | "samva" | "upstream" | "none";
750
- action: string;
751
- freshness: "current" | "stale" | "unknown";
752
- observedAt: string | null;
753
- staleAt: string | null;
754
- nextRetryAt: string | null;
755
- status: "ready" | "blocked" | "unknown";
756
- reason: "domain-not-ready" | "domain-observation-stale" | "operator-paused" | "sending-paused" | "sending-status-unknown" | "ready";
757
- };
758
- dmarc: {
759
- status: "valid" | "missing" | "invalid" | "multiple" | "unknown";
760
- source: "direct" | "organizational" | "none";
761
- policyDomain: string | null;
762
- policy: "none" | "quarantine" | "reject" | null;
763
- subdomainPolicy: "none" | "quarantine" | "reject" | null;
764
- effectivePolicy: "none" | "quarantine" | "reject" | null;
765
- observedAt: string | null;
766
- staleAt: string | null;
767
- guidance: string;
768
- };
769
- rotation: EmailDkimRotation | null;
770
- };
771
- export type DomainConnectEligibility = {
772
- eligible: false;
773
- reason: "no-record" | "no-settings" | "no-sync" | "no-template" | "unavailable";
774
- } | {
775
- eligible: true;
776
- providerName?: string | null | undefined;
378
+ digest: string;
379
+ /**
380
+ * Whether the brand has changed since this publication was built. Publishing the same commit again picks up the change.
381
+ */
382
+ stale: boolean;
777
383
  };
778
- export type DomainConnectApplyUrlResult = {
779
- url: string;
384
+ export type TemplateFromDefault = {
385
+ email: string;
386
+ name?: string | null | undefined;
780
387
  };
781
- export type DomainConnectCompleteResult = {
782
- status: "applied" | "cancelled" | "failed" | "invalid";
388
+ export type TemplateFamilyId = string;
389
+ export type UpdateTemplatePayload = {
390
+ data: {
391
+ name?: string | null | undefined;
392
+ slug?: string | null | undefined;
393
+ entryPath?: string | null | undefined;
394
+ description?: string | null | null | undefined;
395
+ category?: "transactional" | "marketing" | "support" | "notification" | "verification" | "reminder" | "alert" | null | null | undefined;
396
+ fromDefault?: TemplateFromDefault | null | null | undefined;
397
+ replyToDefault?: Array<string> | null | null | undefined;
398
+ isActive?: boolean | null | undefined;
399
+ };
783
400
  };
784
- export type SuccessResult = {
785
- success: boolean;
786
- message: string;
401
+ export type AddTemplateEntryPayload = {
402
+ entryPath: string;
403
+ name: string;
404
+ slug: string;
405
+ description?: string | null | null | undefined;
406
+ category?: "transactional" | "marketing" | "support" | "notification" | "verification" | "reminder" | "alert" | null | null | undefined;
787
407
  };
788
- export type WebhookEndpointId = string;
789
- export type CustomTrackingDnsRecord = {
408
+ export type CreateTemplatePayload = {
790
409
  name: string;
791
- type: string;
792
- value: string;
410
+ projectName?: string | null | undefined;
411
+ slug?: string | null | undefined;
412
+ galleryTemplateId?: string | null | undefined;
413
+ useBrand?: boolean | null | undefined;
414
+ description?: string | null | null | undefined;
415
+ category?: "transactional" | "marketing" | "support" | "notification" | "verification" | "reminder" | "alert" | null | null | undefined;
416
+ isActive?: boolean | null | undefined;
417
+ idempotencyKey: string;
793
418
  };
794
- export type CustomTrackingStatus = {
795
- enabled: boolean;
796
- customTracking: {
797
- status: "pending" | "caa-blocked" | "active" | "teardown-scheduled" | "disabled";
798
- label: string;
799
- hostname: string;
800
- region: string;
801
- sslStatus: string | null;
802
- dnsRecords: {
803
- tracking: CustomTrackingDnsRecord | null;
804
- dcvDelegation: CustomTrackingDnsRecord | null;
805
- };
806
- caaBlocked: boolean;
807
- verificationErrors: Array<string>;
808
- teardownScheduledAt: string | null;
809
- } | null;
810
- };
811
- export type CustomTrackingDomainConnectCompleteResult = {
812
- status: "applied" | "cancelled" | "failed" | "stale" | "invalid";
813
- };
814
- export type SuppressionId = string;
815
- export type SuppressionEntry = {
816
- id: SuppressionId;
817
- email: string;
818
- type: "bounce" | "complaint" | "unsubscribe" | "manual";
819
- bounceType: string | null;
820
- bounceSubType: string | null;
821
- reason: string | null;
822
- messageId: MessageId | null;
823
- isActive: boolean;
824
- expiresAt: string | null;
419
+ export type TemplateFamily = {
420
+ id: TemplateFamilyId;
421
+ organizationId: OrganizationId;
422
+ name: string;
423
+ members: Array<{
424
+ id: TemplateId;
425
+ name: string;
426
+ slug: string;
427
+ channel: "email";
428
+ status: "draft" | "pending" | "approved" | "published" | "rejected" | "archived";
429
+ isActive: boolean;
430
+ createdAt: string;
431
+ updatedAt: string;
432
+ }>;
825
433
  createdAt: string;
434
+ updatedAt: string;
826
435
  };
827
- export type BlockedEmailId = string;
828
- export type BlockedEmailLogId = string;
829
- export type ForwardingConditions = {
830
- subjectContains?: Array<string> | null | undefined;
831
- fromContains?: Array<string> | null | undefined;
832
- hasAttachments?: boolean | null | undefined;
436
+ export type TemplateFamilyName = {
437
+ name: string;
833
438
  };
834
- export type EmailForwardingRuleId = string;
835
- export type DomainWarmingDomainRef = {
836
- id: EmailDomainId;
837
- domain: string;
439
+ export type AnalyticsQueryError = {
440
+ _tag: "AnalyticsQueryError";
441
+ message: string;
838
442
  };
839
- export type EmailDomainWarmingPlanId = string;
840
- export type DomainWarmingPlan = {
841
- id: EmailDomainWarmingPlanId;
842
- status: "active" | "paused" | "completed";
843
- identity: "new" | "migrating" | "returning";
844
- initialDailyRecipients: number;
845
- dailyGrowthPercent: number;
846
- targetDailyRecipients: number;
847
- holdReason: string | null;
848
- heldAt: string | null;
849
- pausedAt: string | null;
850
- completedAt: string | null;
851
- createdAt: string;
852
- updatedAt: string;
443
+ export type UnsubscribeId = string;
444
+ export type CustomFieldDefinitionId = string;
445
+ export type ContactId = string;
446
+ export type ContactGroupId = string;
447
+ export type ContactIdentity = {
448
+ channel: "email";
449
+ identifier: string;
450
+ verified: boolean;
853
451
  };
854
- export type EmailDomainWarmingBatchId = string;
855
- export type DomainWarmingBatch = {
856
- id: EmailDomainWarmingBatchId;
857
- sequence: number;
858
- state: "scheduled" | "open" | "closed" | "cancelled";
859
- startsAt: string;
860
- endsAt: string;
861
- allowanceRecipients: number;
862
- dailyGrowthPercent: number;
863
- targetDailyRecipients: number;
864
- reservedRecipients: number;
865
- acceptedRecipients: number;
866
- cancelledAt: string | null;
867
- createdAt: string;
452
+ export type ConversationId = string;
453
+ export type MessageId = string;
454
+ export type BulkUpdateResult = {
455
+ updated: number;
456
+ failed: number;
868
457
  };
869
- export type EmailDomainWarmingDecisionId = string;
870
- export type DomainWarmingDecision = {
871
- id: EmailDomainWarmingDecisionId;
872
- kind: "plan-created" | "policy-updated" | "window-opened" | "window-cancelled" | "paused" | "resumed" | "held" | "completed";
873
- batchId: EmailDomainWarmingBatchId | null;
874
- actor: string;
875
- note: string | null;
458
+ export type UnknownRecord = {
459
+ [key: string]: JsonValue;
460
+ };
461
+ export type Contact = {
462
+ id: ContactId;
463
+ organizationId: OrganizationId;
464
+ type: "human" | "system";
465
+ name: string;
466
+ displayName: string | null;
467
+ avatar: string | null;
468
+ identities: Array<ContactIdentity>;
469
+ humanProfile: HumanProfile | null;
470
+ capabilities: Array<string>;
471
+ tags: Array<string>;
472
+ accessLevel: "public" | "authenticated" | "vip" | "internal";
473
+ accessConfig: ContactAccessConfig | null;
474
+ preferences: ContactPreferences | null;
475
+ status: "active" | "paused" | "blocked" | "archived";
476
+ statusReason: string | null;
477
+ externalId: string | null;
478
+ metadata: JsonObject | null;
876
479
  createdAt: string;
480
+ updatedAt: string;
481
+ createdBy: ContactId | null;
482
+ lastModifiedBy: ContactId | null;
877
483
  };
878
- export type DomainWarmingWindowHour = {
879
- sent: number;
880
- bounced: number;
881
- complained: number;
484
+ export type JsonObject = {
485
+ [key: string]: JsonValue;
882
486
  };
883
- export type DomainWarmingEvidence = {
884
- observedAt: string;
885
- windowHours: number;
886
- minimumSends: number;
887
- sent: number;
888
- bounced: number;
889
- complained: number;
890
- hourly: Array<DomainWarmingWindowHour>;
891
- bounceThreshold: number;
892
- complaintThreshold: number;
893
- verdict: "insufficient-evidence" | "healthy" | "over-threshold";
894
- thresholdReason: string | null;
487
+ export type ContactPreferences = {
488
+ preferredChannels?: Array<"email"> | null | undefined;
489
+ language?: string | null | undefined;
490
+ timezone?: string | null | undefined;
491
+ notifications?: {
492
+ email?: boolean | null | undefined;
493
+ quiet_hours?: {
494
+ start: string;
495
+ end: string;
496
+ } | null | undefined;
497
+ } | null | undefined;
498
+ messageFormats?: {
499
+ preferMarkdown?: boolean | null | undefined;
500
+ preferPlainText?: boolean | null | undefined;
501
+ maxMessageLength?: number | null | undefined;
502
+ } | null | undefined;
895
503
  };
896
- export type DomainWarmingHolds = {
897
- workspacePausedAt: string | null;
898
- workspacePauseReason: string | null;
899
- sendingStatus: "enabled" | "disabled" | "reinstated" | "unknown";
504
+ export type ContactAccessConfig = {
505
+ paymentRequired?: {
506
+ amount: number;
507
+ currency: string;
508
+ validityHours?: number | null | undefined;
509
+ message?: string | null | undefined;
510
+ } | null | undefined;
511
+ rateLimit?: {
512
+ messagesPerHour?: number | null | undefined;
513
+ messagesPerDay?: number | null | undefined;
514
+ cooldownMinutes?: number | null | undefined;
515
+ } | null | undefined;
516
+ allowedContacts?: Array<ContactId> | null | undefined;
517
+ blockedContacts?: Array<ContactId> | null | undefined;
518
+ availability?: {
519
+ timezone: string;
520
+ schedule: Array<{
521
+ days: Array<number>;
522
+ startTime: string;
523
+ endTime: string;
524
+ }>;
525
+ outOfOfficeMessage?: string | null | undefined;
526
+ } | null | undefined;
900
527
  };
901
- export type DomainWarming = {
902
- domain: DomainWarmingDomainRef;
903
- plan: DomainWarmingPlan | null;
904
- batches: Array<DomainWarmingBatch>;
905
- decisions: Array<DomainWarmingDecision>;
906
- evidence: DomainWarmingEvidence;
907
- holds: DomainWarmingHolds;
528
+ export type HumanProfile = {
529
+ firstName?: string | null | undefined;
530
+ lastName?: string | null | undefined;
531
+ email?: string | null | undefined;
532
+ phone?: string | null | undefined;
533
+ company?: string | null | undefined;
534
+ jobTitle?: string | null | undefined;
535
+ location?: {
536
+ country: string;
537
+ state: string;
538
+ city: string;
539
+ timezone: string;
540
+ } | null | undefined;
541
+ customFields?: UnknownRecord | null | undefined;
542
+ source?: "api" | "import" | "manual" | "form" | null | undefined;
543
+ sourceDetails?: UnknownRecord | null | undefined;
908
544
  };
909
- export type CreateDomainWarmingPlanPayload = {
910
- identity: "new" | "migrating" | "returning";
911
- initialDailyRecipients: number;
912
- dailyGrowthPercent: number;
913
- targetDailyRecipients: number;
545
+ export type ContactListItem = {
546
+ id: ContactId;
547
+ organizationId: OrganizationId;
548
+ type: "human" | "system";
549
+ name: string;
550
+ displayName: string | null;
551
+ avatar: string | null;
552
+ identities: Array<ContactIdentity>;
553
+ humanProfile: HumanProfile | null;
554
+ capabilities: Array<string>;
555
+ tags: Array<string>;
556
+ accessLevel: "public" | "authenticated" | "vip" | "internal";
557
+ accessConfig: ContactAccessConfig | null;
558
+ preferences: ContactPreferences | null;
559
+ status: "active" | "paused" | "blocked" | "archived";
560
+ statusReason: string | null;
561
+ externalId: string | null;
562
+ metadata: JsonObject | null;
563
+ createdAt: string;
564
+ updatedAt: string;
565
+ createdBy: ContactId | null;
566
+ lastModifiedBy: ContactId | null;
567
+ engagement: ContactActivitySummary;
568
+ lists: Array<ContactListMembership>;
914
569
  };
915
- export type UpdateDomainWarmingPolicyPayload = {
916
- dailyGrowthPercent: number;
917
- targetDailyRecipients: number;
918
- note?: string | null | undefined;
570
+ export type ContactListMembership = {
571
+ id: ContactGroupId;
572
+ name: string;
573
+ color: "clay" | "sand" | "moss" | "sky" | "plum" | "rose" | null;
919
574
  };
920
- export type DomainWarmingNotePayload = {
921
- note?: string | null | undefined;
922
- };
923
- export type CreateMediaPayload = {
924
- filename: string;
925
- contentType: string;
926
- sizeBytes: number;
927
- purpose: "attachment" | "avatar" | "review_evidence";
928
- checksumSha256?: string | null | undefined;
929
- };
930
- export type OrganizationId = string;
931
- export type MediaUploadInstruction = {
932
- url: string;
933
- method: "PUT";
934
- headers: {
935
- [key: string]: string;
936
- };
937
- expiresAt: string;
938
- };
939
- export type CreatedMedia = {
940
- id: MediaId;
941
- organizationId: OrganizationId;
942
- status: "pending" | "uploading" | "processing" | "ready" | "failed" | "deleted";
943
- filename: string;
944
- contentType: string;
945
- sizeBytes: number;
946
- width: number | null;
947
- height: number | null;
948
- durationMs: number | null;
949
- purpose: "attachment" | "avatar" | "review_evidence";
950
- checksumSha256: string | null;
951
- expiresAt: string | null;
952
- createdAt: string;
953
- confirmedAt: string | null;
954
- upload: MediaUploadInstruction;
955
- };
956
- export type Media = {
957
- id: MediaId;
958
- organizationId: OrganizationId;
959
- status: "pending" | "uploading" | "processing" | "ready" | "failed" | "deleted";
960
- filename: string;
961
- contentType: string;
962
- sizeBytes: number;
963
- width: number | null;
964
- height: number | null;
965
- durationMs: number | null;
966
- purpose: "attachment" | "avatar" | "review_evidence";
967
- checksumSha256: string | null;
968
- expiresAt: string | null;
969
- createdAt: string;
970
- confirmedAt: string | null;
971
- };
972
- export type CompletedMedia = {
973
- media: Media;
974
- downloadUrl: string;
975
- };
976
- export type SuccessResponse = {
977
- success: boolean;
978
- };
979
- export type MediaDownloadUrl = {
980
- url: string;
981
- expiresAt: string;
982
- };
983
- export type UnknownRecord = {
984
- [key: string]: JsonValue;
985
- };
986
- export type ConversationMetadata = {
987
- source?: string | null | undefined;
988
- tags?: Array<string> | null | undefined;
989
- customFields?: UnknownRecord | null | undefined;
990
- };
991
- export type ActorId = string;
992
- export type ActorTracking = {
993
- allActorIds: Array<ActorId>;
994
- activeActorIds: Array<ActorId>;
995
- actorHistory: Array<{
996
- actorId: ActorId;
997
- actorType: "contact" | "system" | "sender" | "agent" | "user";
998
- joinedAt: string;
999
- leftAt?: string | null | undefined;
1000
- role: "initiator" | "responder" | "observer";
1001
- addedBy?: ActorId | null | undefined;
1002
- removedBy?: ActorId | null | undefined;
1003
- reason?: string | null | undefined;
1004
- }>;
1005
- primaryActorIds: Array<ActorId>;
1006
- };
1007
- export type ConversationMetrics = {
1008
- messageCount: number;
1009
- messagesFromHuman: number;
1010
- totalActors: number;
1011
- contactCount: number;
1012
- channelSwitches: number;
1013
- channelDistribution: {
1014
- [key: string]: number;
1015
- };
1016
- };
1017
- export type ConversationContext = {
1018
- customerData?: UnknownRecord | null | undefined;
1019
- previousConversations?: Array<string> | null | undefined;
1020
- sessionVariables?: UnknownRecord | null | undefined;
1021
- workflowState?: {
1022
- currentStep?: string | null | undefined;
1023
- completedSteps?: Array<string> | null | undefined;
1024
- pendingSteps?: Array<string> | null | undefined;
1025
- workflowData?: UnknownRecord | null | undefined;
1026
- } | null | undefined;
575
+ export type ContactActivitySummary = {
576
+ totalInteractions: number;
577
+ lastActiveAt: string | null;
1027
578
  };
1028
579
  export type Conversation = {
1029
580
  id: ConversationId;
@@ -1060,515 +611,964 @@ export type Conversation = {
1060
611
  updatedAt: string;
1061
612
  createdBy: ActorId | null;
1062
613
  };
1063
- export type ConversationParticipant = {
1064
- actorId: ActorId;
1065
- actorType: "contact" | "system" | "sender" | "agent" | "user";
1066
- contact: MessageContact;
1067
- };
1068
- export type ConversationDetail = {
1069
- id: ConversationId;
1070
- organizationId: OrganizationId;
1071
- title: string | null;
1072
- description: string | null;
1073
- externalId: string | null;
1074
- parentConversationId: ConversationId | null;
1075
- channels: Array<"email">;
1076
- primaryChannel: "email";
1077
- status: "active" | "waiting" | "resolved" | "escalated" | "archived";
1078
- statusReason: string | null;
1079
- priority: number;
1080
- urgency: "low" | "medium" | "high" | "critical";
1081
- complexity: "simple" | "moderate" | "complex";
1082
- metadata: ConversationMetadata | null;
1083
- actorTracking: ActorTracking;
1084
- metrics: ConversationMetrics;
1085
- context: ConversationContext | null;
1086
- tags: Array<string>;
1087
- categories: Array<string>;
1088
- isTest: boolean;
1089
- isInternal: boolean;
1090
- isPrivate: boolean;
1091
- startedAt: string;
1092
- lastActivityAt: string;
1093
- lastHumanActivityAt: string | null;
1094
- resolvedAt: string | null;
1095
- archivedAt: string | null;
1096
- resolvedBy: ActorId | null;
1097
- resolutionType: "automated" | "human_assisted" | "escalated" | "abandoned" | "timeout" | null;
1098
- resolutionNotes: string | null;
1099
- createdAt: string;
1100
- updatedAt: string;
1101
- createdBy: ActorId | null;
1102
- participants: Array<ConversationParticipant>;
1103
- };
1104
- export type ConversationContacts = {
1105
- contactIds: [ContactId, ContactId];
1106
- };
1107
- export type ContactIdentity = {
1108
- channel: "email";
1109
- identifier: string;
1110
- verified: boolean;
1111
- };
1112
- export type HumanProfile = {
1113
- firstName?: string | null | undefined;
1114
- lastName?: string | null | undefined;
1115
- email?: string | null | undefined;
1116
- phone?: string | null | undefined;
1117
- company?: string | null | undefined;
1118
- jobTitle?: string | null | undefined;
1119
- location?: {
1120
- country: string;
1121
- state: string;
1122
- city: string;
1123
- timezone: string;
614
+ export type ActorId = string;
615
+ export type ConversationContext = {
616
+ customerData?: UnknownRecord | null | undefined;
617
+ previousConversations?: Array<string> | null | undefined;
618
+ sessionVariables?: UnknownRecord | null | undefined;
619
+ workflowState?: {
620
+ currentStep?: string | null | undefined;
621
+ completedSteps?: Array<string> | null | undefined;
622
+ pendingSteps?: Array<string> | null | undefined;
623
+ workflowData?: UnknownRecord | null | undefined;
1124
624
  } | null | undefined;
1125
- customFields?: UnknownRecord | null | undefined;
1126
- source?: "api" | "import" | "manual" | "form" | null | undefined;
1127
- sourceDetails?: UnknownRecord | null | undefined;
1128
625
  };
1129
- export type ContactAccessConfig = {
1130
- paymentRequired?: {
1131
- amount: number;
1132
- currency: string;
1133
- validityHours?: number | null | undefined;
1134
- message?: string | null | undefined;
1135
- } | null | undefined;
1136
- rateLimit?: {
1137
- messagesPerHour?: number | null | undefined;
1138
- messagesPerDay?: number | null | undefined;
1139
- cooldownMinutes?: number | null | undefined;
1140
- } | null | undefined;
1141
- allowedContacts?: Array<ContactId> | null | undefined;
1142
- blockedContacts?: Array<ContactId> | null | undefined;
1143
- availability?: {
1144
- timezone: string;
1145
- schedule: Array<{
1146
- days: Array<number>;
1147
- startTime: string;
1148
- endTime: string;
1149
- }>;
1150
- outOfOfficeMessage?: string | null | undefined;
1151
- } | null | undefined;
626
+ export type ConversationMetrics = {
627
+ messageCount: number;
628
+ messagesFromHuman: number;
629
+ totalActors: number;
630
+ contactCount: number;
631
+ channelSwitches: number;
632
+ channelDistribution: {
633
+ [key: string]: number;
634
+ };
1152
635
  };
1153
- export type ContactPreferences = {
1154
- preferredChannels?: Array<"email"> | null | undefined;
1155
- language?: string | null | undefined;
1156
- timezone?: string | null | undefined;
1157
- notifications?: {
1158
- email?: boolean | null | undefined;
1159
- quiet_hours?: {
1160
- start: string;
1161
- end: string;
1162
- } | null | undefined;
1163
- } | null | undefined;
1164
- messageFormats?: {
1165
- preferMarkdown?: boolean | null | undefined;
1166
- preferPlainText?: boolean | null | undefined;
1167
- maxMessageLength?: number | null | undefined;
1168
- } | null | undefined;
636
+ export type ActorTracking = {
637
+ allActorIds: Array<ActorId>;
638
+ activeActorIds: Array<ActorId>;
639
+ actorHistory: Array<{
640
+ actorId: ActorId;
641
+ actorType: "contact" | "system" | "sender" | "agent" | "user";
642
+ joinedAt: string;
643
+ leftAt?: string | null | undefined;
644
+ role: "initiator" | "responder" | "observer";
645
+ addedBy?: ActorId | null | undefined;
646
+ removedBy?: ActorId | null | undefined;
647
+ reason?: string | null | undefined;
648
+ }>;
649
+ primaryActorIds: Array<ActorId>;
1169
650
  };
1170
- export type ContactActivitySummary = {
1171
- totalInteractions: number;
1172
- lastActiveAt: string | null;
651
+ export type ConversationMetadata = {
652
+ source?: string | null | undefined;
653
+ tags?: Array<string> | null | undefined;
654
+ customFields?: UnknownRecord | null | undefined;
1173
655
  };
1174
- export type ContactListMembership = {
1175
- id: ContactGroupId;
1176
- name: string;
1177
- color: "clay" | "sand" | "moss" | "sky" | "plum" | "rose" | null;
656
+ export type ConversationContacts = {
657
+ contactIds: [ContactId, ContactId];
1178
658
  };
1179
- export type ContactListItem = {
1180
- id: ContactId;
1181
- organizationId: OrganizationId;
1182
- type: "human" | "system";
1183
- name: string;
1184
- displayName: string | null;
1185
- avatar: string | null;
1186
- identities: Array<ContactIdentity>;
1187
- humanProfile: HumanProfile | null;
1188
- capabilities: Array<string>;
659
+ export type Message = {
660
+ id: string;
661
+ organizationId: string;
662
+ conversationId: string | null;
663
+ parentMessageId: string | null;
664
+ fromActorId: string;
665
+ actorMetadata: {
666
+ [key: string]: JsonValue;
667
+ } | null;
668
+ channel: "email";
669
+ direction: "outbound" | "inbound";
670
+ content: MessageContent;
671
+ metadata: {
672
+ [key: string]: JsonValue;
673
+ } | null;
674
+ status: "pending" | "scheduled" | "queued" | "processing" | "sent" | "delivered" | "read" | "failed" | "bounced" | "complained";
675
+ scheduledAt: string | null;
1189
676
  tags: Array<string>;
1190
- accessLevel: "public" | "authenticated" | "vip" | "internal";
1191
- accessConfig: ContactAccessConfig | null;
1192
- preferences: ContactPreferences | null;
1193
- status: "active" | "paused" | "blocked" | "archived";
1194
- statusReason: string | null;
677
+ categories: Array<string>;
678
+ isTest: boolean;
1195
679
  externalId: string | null;
1196
- metadata: JsonObject | null;
680
+ referenceId: string | null;
681
+ submission: MessageSubmission | null;
1197
682
  createdAt: string;
1198
683
  updatedAt: string;
1199
- createdBy: ContactId | null;
1200
- lastModifiedBy: ContactId | null;
1201
- engagement: ContactActivitySummary;
1202
- lists: Array<ContactListMembership>;
684
+ fromContact: MessageContact | null;
685
+ toContacts: Array<MessageContact>;
686
+ recipients: Array<{
687
+ id: string;
688
+ messageId: string;
689
+ actorId: string | null;
690
+ contactId: string | null;
691
+ identityId: string | null;
692
+ kind: "to" | "cc" | "bcc";
693
+ address: string;
694
+ status: "pending" | "scheduled" | "queued" | "processing" | "sent" | "delivered" | "read" | "failed" | "bounced" | "complained";
695
+ createdAt: string;
696
+ updatedAt: string;
697
+ contact: MessageContact | null;
698
+ }>;
699
+ deliveries: Array<{
700
+ scheduling: {
701
+ dueAt: string;
702
+ expiresAt: string;
703
+ waitReason: "rate" | "daily-quota" | "domain-health" | "sending-paused" | "upstream-unavailable" | "retry" | "campaign-paused" | "domain-warming" | "onboarding-review" | "content-review" | null;
704
+ reviewExpectedAt: string | null;
705
+ } | null;
706
+ id: string;
707
+ messageId: string;
708
+ recipientId: string | null;
709
+ channel: "email";
710
+ status: "pending" | "scheduled" | "queued" | "processing" | "sent" | "delivered" | "read" | "failed" | "bounced" | "complained";
711
+ attemptCount: number;
712
+ maxAttempts: number;
713
+ queuedAt: string | null;
714
+ claimedAt: string | null;
715
+ lastAttemptAt: string | null;
716
+ nextRetryAt: string | null;
717
+ sentAt: string | null;
718
+ deliveredAt: string | null;
719
+ readAt: string | null;
720
+ failedAt: string | null;
721
+ terminalAt: string | null;
722
+ errorCode: string | null;
723
+ errorMessage: string | null;
724
+ errorDetails: DeliveryErrorDetails | null;
725
+ cost: string;
726
+ currency: string;
727
+ idempotencyKey: string | null;
728
+ createdAt: string;
729
+ updatedAt: string;
730
+ }>;
731
+ emailDeliveryDetails: Array<{
732
+ deliveryId: string;
733
+ messageIdHeader: string;
734
+ inReplyTo: string | null;
735
+ references: Array<string> | null;
736
+ subject: string;
737
+ fromEmail: string;
738
+ fromName: string | null;
739
+ toEmails: Array<string>;
740
+ toName: string | null;
741
+ ccEmails: Array<string> | null;
742
+ bccEmails: Array<string> | null;
743
+ replyToEmails: Array<string> | null;
744
+ hasAttachments: boolean;
745
+ attachmentCount: number;
746
+ listUnsubscribeUrl: string | null;
747
+ listUnsubscribeEmail: string | null;
748
+ threadPosition: number | null;
749
+ newContent: string | null;
750
+ quotedContent: string | null;
751
+ hasQuotedContent: boolean;
752
+ dkimVerdict: string | null;
753
+ spfVerdict: string | null;
754
+ dmarcVerdict: string | null;
755
+ isAutoReply: boolean;
756
+ autoReplyReason: "out-of-office" | "auto-response" | "delivery-status" | "read-receipt" | null;
757
+ priority: string | null;
758
+ parsingErrors: Array<string> | null;
759
+ parsingDuration: number | null;
760
+ receivedAt: string | null;
761
+ processedAt: string | null;
762
+ createdAt: string;
763
+ updatedAt: string;
764
+ }>;
765
+ waitReason: "rate" | "daily-quota" | "domain-health" | "sending-paused" | "upstream-unavailable" | "retry" | "campaign-paused" | "domain-warming" | "onboarding-review" | "content-review" | null;
766
+ reviewExpectedAt: string | null;
1203
767
  };
1204
- export type Contact = {
1205
- id: ContactId;
1206
- organizationId: OrganizationId;
1207
- type: "human" | "system";
768
+ export type DeliveryErrorDetails = {
769
+ code?: string | null | undefined;
770
+ name?: string | null | undefined;
771
+ message?: string | null | undefined;
772
+ details?: {
773
+ [key: string]: string | number | null;
774
+ } | null | undefined;
775
+ retryable?: boolean | null | undefined;
776
+ };
777
+ export type MessageContact = {
778
+ id: string;
1208
779
  name: string;
1209
780
  displayName: string | null;
1210
- avatar: string | null;
1211
- identities: Array<ContactIdentity>;
1212
- humanProfile: HumanProfile | null;
1213
- capabilities: Array<string>;
1214
- tags: Array<string>;
1215
- accessLevel: "public" | "authenticated" | "vip" | "internal";
1216
- accessConfig: ContactAccessConfig | null;
1217
- preferences: ContactPreferences | null;
1218
- status: "active" | "paused" | "blocked" | "archived";
1219
- statusReason: string | null;
1220
- externalId: string | null;
1221
- metadata: JsonObject | null;
1222
- createdAt: string;
1223
- updatedAt: string;
1224
- createdBy: ContactId | null;
1225
- lastModifiedBy: ContactId | null;
781
+ type: string;
782
+ identities: Array<{
783
+ channel: "email";
784
+ identifier: string;
785
+ verified: boolean;
786
+ }>;
1226
787
  };
1227
- export type BulkUpdateResult = {
1228
- updated: number;
1229
- failed: number;
788
+ export type MessageSubmission = {
789
+ origin: "direct" | "campaign" | "scheduled";
790
+ transport: "http" | null;
791
+ credential: SubmissionCredential | null;
792
+ userId: UserId | null;
793
+ client: SubmissionClient | null;
1230
794
  };
1231
- export type CustomFieldDefinitionId = string;
1232
- export type AnalyticsQueryError = {
1233
- _tag: "AnalyticsQueryError";
1234
- message: string;
795
+ export type SubmissionClient = {
796
+ surface: "typescript-promise" | "typescript-effect" | "cli" | "mcp";
797
+ version: string;
1235
798
  };
1236
- export type TemplateProjectId = string;
1237
- export type TemplateFamilyId = string;
1238
- export type TemplateFromDefault = {
1239
- email: string;
1240
- name?: string | null | undefined;
799
+ export type SubmissionCredential = {
800
+ kind: "api_key";
801
+ apiKeyId: ApiKeyId | null;
802
+ } | {
803
+ kind: "oauth";
804
+ clientId: string | null;
805
+ } | {
806
+ kind: "session";
1241
807
  };
1242
- export type TemplatePublicationBrand = {
1243
- /**
1244
- * The brand the publication imports.
1245
- */
1246
- slug: string;
808
+ export type MessageContent = {
809
+ text?: string | null | undefined;
810
+ html?: string | null | undefined;
811
+ markdown?: string | null | undefined;
812
+ email?: {
813
+ subject?: string | null | undefined;
814
+ html?: string | null | undefined;
815
+ text?: string | null | undefined;
816
+ headers?: {
817
+ [key: string]: string;
818
+ } | null | undefined;
819
+ tracking?: EmailTrackingOverrideV1 | undefined;
820
+ attachments?: Array<{
821
+ filename: string;
822
+ content?: string | null | undefined;
823
+ mediaId?: MediaId | null | undefined;
824
+ contentType: string;
825
+ size: number;
826
+ }> | null | undefined;
827
+ } | null | undefined;
828
+ metadata?: {
829
+ [key: string]: JsonValue;
830
+ } | null | undefined;
831
+ };
832
+ export type MediaId = string;
833
+ /**
834
+ * Requested per-send engagement tracking policy. Recipient opt-out takes precedence, then explicit fields, organization defaults, and product defaults.
835
+ */
836
+ export type EmailTrackingOverrideV1 = {
1247
837
  /**
1248
- * The brand's digest when the publication was built.
838
+ * Override open tracking for this send. Omit to inherit the organization default. A recipient tracking opt-out always disables tracking.
1249
839
  */
1250
- digest: string;
840
+ opens?: boolean | undefined;
1251
841
  /**
1252
- * Whether the brand has changed since this publication was built. Publishing the same commit again picks up the change.
842
+ * Override click tracking for this send. Omit to inherit the organization default. A recipient tracking opt-out always disables tracking.
1253
843
  */
1254
- stale: boolean;
844
+ clicks?: boolean | undefined;
1255
845
  };
1256
- export type Template = {
1257
- id: TemplateId;
846
+ export type ConversationDetail = {
847
+ id: ConversationId;
1258
848
  organizationId: OrganizationId;
1259
- projectId: TemplateProjectId;
1260
- entryPath: string;
1261
- name: string;
1262
- slug: string;
1263
- familyId: TemplateFamilyId | null;
1264
- channel: "email";
849
+ title: string | null;
1265
850
  description: string | null;
1266
- category: string | null;
1267
- fromDefault?: TemplateFromDefault | null | null | undefined;
1268
- replyToDefault?: Array<string> | null | null | undefined;
1269
- trackingDefault?: {
1270
- opens?: boolean | null | undefined;
1271
- clicks?: boolean | null | undefined;
1272
- } | null | null | undefined;
1273
- email: {
1274
- subject: string;
1275
- preheader: string | null;
1276
- headers: {
1277
- [key: string]: string;
1278
- } | null;
1279
- } | null;
1280
- publicationId: TemplatePublicationId | null;
1281
- brand: TemplatePublicationBrand | null;
1282
- inputContractId: TemplateInputContractId | null;
1283
- inputSchema: {
1284
- [key: string]: JsonValue;
1285
- } | null;
1286
- usageCount: number;
1287
- lastUsedAt: string | null;
1288
- status: string;
1289
- isActive: boolean;
1290
- isDefault: boolean;
1291
- publishedAt?: string | null | null | undefined;
1292
- publishedBy?: string | null | null | undefined;
851
+ externalId: string | null;
852
+ parentConversationId: ConversationId | null;
853
+ channels: Array<"email">;
854
+ primaryChannel: "email";
855
+ status: "active" | "waiting" | "resolved" | "escalated" | "archived";
856
+ statusReason: string | null;
857
+ priority: number;
858
+ urgency: "low" | "medium" | "high" | "critical";
859
+ complexity: "simple" | "moderate" | "complex";
860
+ metadata: ConversationMetadata | null;
861
+ actorTracking: ActorTracking;
862
+ metrics: ConversationMetrics;
863
+ context: ConversationContext | null;
864
+ tags: Array<string>;
865
+ categories: Array<string>;
866
+ isTest: boolean;
867
+ isInternal: boolean;
868
+ isPrivate: boolean;
869
+ startedAt: string;
870
+ lastActivityAt: string;
871
+ lastHumanActivityAt: string | null;
872
+ resolvedAt: string | null;
873
+ archivedAt: string | null;
874
+ resolvedBy: ActorId | null;
875
+ resolutionType: "automated" | "human_assisted" | "escalated" | "abandoned" | "timeout" | null;
876
+ resolutionNotes: string | null;
1293
877
  createdAt: string;
1294
878
  updatedAt: string;
879
+ createdBy: ActorId | null;
880
+ participants: Array<ConversationParticipant>;
1295
881
  };
1296
- export type TemplateFamily = {
1297
- id: TemplateFamilyId;
882
+ export type ConversationParticipant = {
883
+ actorId: ActorId;
884
+ actorType: "contact" | "system" | "sender" | "agent" | "user";
885
+ contact: MessageContact;
886
+ };
887
+ export type AttachmentId = string;
888
+ export type Media = {
889
+ id: MediaId;
1298
890
  organizationId: OrganizationId;
1299
- name: string;
1300
- members: Array<{
1301
- id: TemplateId;
1302
- name: string;
1303
- slug: string;
1304
- channel: "email";
1305
- status: "draft" | "pending" | "approved" | "published" | "rejected" | "archived";
1306
- isActive: boolean;
1307
- createdAt: string;
1308
- updatedAt: string;
1309
- }>;
891
+ status: "pending" | "uploading" | "processing" | "ready" | "failed" | "deleted";
892
+ filename: string;
893
+ contentType: string;
894
+ sizeBytes: number;
895
+ width: number | null;
896
+ height: number | null;
897
+ durationMs: number | null;
898
+ purpose: "attachment" | "avatar" | "review_evidence";
899
+ checksumSha256: string | null;
900
+ expiresAt: string | null;
1310
901
  createdAt: string;
1311
- updatedAt: string;
902
+ confirmedAt: string | null;
1312
903
  };
1313
- export type TemplateFamilyName = {
1314
- name: string;
904
+ export type MediaDownloadUrl = {
905
+ url: string;
906
+ expiresAt: string;
1315
907
  };
1316
- export type CreateTemplatePayload = {
1317
- name: string;
1318
- projectName?: string | null | undefined;
1319
- slug?: string | null | undefined;
1320
- galleryTemplateId?: string | null | undefined;
1321
- useBrand?: boolean | null | undefined;
1322
- description?: string | null | null | undefined;
1323
- category?: "transactional" | "marketing" | "support" | "notification" | "verification" | "reminder" | "alert" | null | null | undefined;
1324
- isActive?: boolean | null | undefined;
1325
- idempotencyKey: string;
908
+ export type CompletedMedia = {
909
+ media: Media;
910
+ downloadUrl: string;
1326
911
  };
1327
- export type AddTemplateEntryPayload = {
1328
- entryPath: string;
1329
- name: string;
1330
- slug: string;
1331
- description?: string | null | null | undefined;
1332
- category?: "transactional" | "marketing" | "support" | "notification" | "verification" | "reminder" | "alert" | null | null | undefined;
912
+ export type CreatedMedia = {
913
+ id: MediaId;
914
+ organizationId: OrganizationId;
915
+ status: "pending" | "uploading" | "processing" | "ready" | "failed" | "deleted";
916
+ filename: string;
917
+ contentType: string;
918
+ sizeBytes: number;
919
+ width: number | null;
920
+ height: number | null;
921
+ durationMs: number | null;
922
+ purpose: "attachment" | "avatar" | "review_evidence";
923
+ checksumSha256: string | null;
924
+ expiresAt: string | null;
925
+ createdAt: string;
926
+ confirmedAt: string | null;
927
+ upload: MediaUploadInstruction;
1333
928
  };
1334
- export type UpdateTemplatePayload = {
1335
- data: {
1336
- name?: string | null | undefined;
1337
- slug?: string | null | undefined;
1338
- entryPath?: string | null | undefined;
1339
- description?: string | null | null | undefined;
1340
- category?: "transactional" | "marketing" | "support" | "notification" | "verification" | "reminder" | "alert" | null | null | undefined;
1341
- fromDefault?: TemplateFromDefault | null | null | undefined;
1342
- replyToDefault?: Array<string> | null | null | undefined;
1343
- isActive?: boolean | null | undefined;
929
+ export type MediaUploadInstruction = {
930
+ url: string;
931
+ method: "PUT";
932
+ headers: {
933
+ [key: string]: string;
1344
934
  };
935
+ expiresAt: string;
1345
936
  };
1346
- export type BrandAssets = {
1347
- logoUrl?: string | null | undefined;
1348
- logoDarkUrl?: string | null | undefined;
1349
- iconUrl?: string | null | undefined;
937
+ export type CreateMediaPayload = {
938
+ filename: string;
939
+ contentType: string;
940
+ sizeBytes: number;
941
+ purpose: "attachment" | "avatar" | "review_evidence";
942
+ checksumSha256?: string | null | undefined;
1350
943
  };
1351
- export type BrandAddress = {
1352
- street1: string;
1353
- street2?: string | null | undefined;
1354
- city: string;
1355
- region: string;
1356
- postalCode: string;
1357
- country: string;
944
+ export type DomainWarming = {
945
+ domain: DomainWarmingDomainRef;
946
+ plan: DomainWarmingPlan | null;
947
+ batches: Array<DomainWarmingBatch>;
948
+ decisions: Array<DomainWarmingDecision>;
949
+ evidence: DomainWarmingEvidence;
950
+ holds: DomainWarmingHolds;
1358
951
  };
1359
- export type BrandSocialLink = {
1360
- label: string;
1361
- url: string;
952
+ export type DomainWarmingHolds = {
953
+ workspacePausedAt: string | null;
954
+ workspacePauseReason: string | null;
955
+ sendingStatus: "enabled" | "disabled" | "reinstated" | "unknown";
1362
956
  };
1363
- export type BrandFooter = {
1364
- companyName?: string | null | undefined;
1365
- address?: BrandAddress | null | undefined;
1366
- socialLinks?: Array<BrandSocialLink> | null | undefined;
957
+ export type DomainWarmingEvidence = {
958
+ observedAt: string;
959
+ windowHours: number;
960
+ minimumSends: number;
961
+ sent: number;
962
+ bounced: number;
963
+ complained: number;
964
+ hourly: Array<DomainWarmingWindowHour>;
965
+ bounceThreshold: number;
966
+ complaintThreshold: number;
967
+ verdict: "insufficient-evidence" | "healthy" | "over-threshold";
968
+ thresholdReason: string | null;
969
+ };
970
+ export type DomainWarmingWindowHour = {
971
+ sent: number;
972
+ bounced: number;
973
+ complained: number;
974
+ };
975
+ export type DomainWarmingDecision = {
976
+ id: EmailDomainWarmingDecisionId;
977
+ kind: "plan-created" | "policy-updated" | "window-opened" | "window-cancelled" | "paused" | "resumed" | "held" | "completed";
978
+ batchId: EmailDomainWarmingBatchId | null;
979
+ actor: string;
980
+ note: string | null;
981
+ createdAt: string;
982
+ };
983
+ export type EmailDomainWarmingBatchId = string;
984
+ export type EmailDomainWarmingDecisionId = string;
985
+ export type DomainWarmingBatch = {
986
+ id: EmailDomainWarmingBatchId;
987
+ sequence: number;
988
+ state: "scheduled" | "open" | "closed" | "cancelled";
989
+ startsAt: string;
990
+ endsAt: string;
991
+ allowanceRecipients: number;
992
+ dailyGrowthPercent: number;
993
+ targetDailyRecipients: number;
994
+ reservedRecipients: number;
995
+ acceptedRecipients: number;
996
+ cancelledAt: string | null;
997
+ createdAt: string;
998
+ };
999
+ export type DomainWarmingPlan = {
1000
+ id: EmailDomainWarmingPlanId;
1001
+ status: "active" | "paused" | "completed";
1002
+ identity: "new" | "migrating" | "returning";
1003
+ initialDailyRecipients: number;
1004
+ dailyGrowthPercent: number;
1005
+ targetDailyRecipients: number;
1006
+ holdReason: string | null;
1007
+ heldAt: string | null;
1008
+ pausedAt: string | null;
1009
+ completedAt: string | null;
1010
+ createdAt: string;
1011
+ updatedAt: string;
1012
+ };
1013
+ export type EmailDomainWarmingPlanId = string;
1014
+ export type DomainWarmingDomainRef = {
1015
+ id: EmailDomainId;
1016
+ domain: string;
1017
+ };
1018
+ export type EmailDomainId = string;
1019
+ export type DomainWarmingNotePayload = {
1020
+ note?: string | null | undefined;
1021
+ };
1022
+ export type UpdateDomainWarmingPolicyPayload = {
1023
+ dailyGrowthPercent: number;
1024
+ targetDailyRecipients: number;
1025
+ note?: string | null | undefined;
1026
+ };
1027
+ export type CreateDomainWarmingPlanPayload = {
1028
+ identity: "new" | "migrating" | "returning";
1029
+ initialDailyRecipients: number;
1030
+ dailyGrowthPercent: number;
1031
+ targetDailyRecipients: number;
1032
+ };
1033
+ export type EmailForwardingRuleId = string;
1034
+ export type SuccessResult = {
1035
+ success: boolean;
1036
+ message: string;
1037
+ };
1038
+ export type ForwardingConditions = {
1039
+ subjectContains?: Array<string> | null | undefined;
1040
+ fromContains?: Array<string> | null | undefined;
1041
+ hasAttachments?: boolean | null | undefined;
1042
+ };
1043
+ export type BlockedEmailId = string;
1044
+ export type BlockedEmailLogId = string;
1045
+ export type EmailChannelError = {
1046
+ _tag: "EmailChannelError";
1047
+ reason: "transport" | "rejected" | "rate_limited" | "auth";
1048
+ message: string;
1049
+ statusCode?: number | null | undefined;
1050
+ };
1051
+ export type SuppressionId = string;
1052
+ export type SuppressionEntry = {
1053
+ id: SuppressionId;
1054
+ email: string;
1055
+ type: "bounce" | "complaint" | "unsubscribe" | "manual";
1056
+ bounceType: string | null;
1057
+ bounceSubType: string | null;
1058
+ reason: string | null;
1059
+ messageId: MessageId | null;
1060
+ isActive: boolean;
1061
+ expiresAt: string | null;
1062
+ createdAt: string;
1063
+ };
1064
+ export type ExternalServiceError = {
1065
+ _tag: "ExternalServiceError";
1066
+ message: string;
1067
+ };
1068
+ export type EmailSenderId = string;
1069
+ /**
1070
+ * Daily email sends for the last 14 calendar days in the organization's own timezone, oldest first and zero-filled. Always fourteen entries; an entity that has never sent reports fourteen zeroes.
1071
+ */
1072
+ export type SendsSeries = Array<number>;
1073
+ /**
1074
+ * Bounce and complaint rates over the last 24 hours, as fractions between 0 and 1, with `windowSends`, the deliveries they were divided by, plus `sendingStatus`, which says whether the organization can currently send. The window matches the one the sending-pause rule reads. Below 200 sends that rule ignores the window entirely, so a rate over a smaller `windowSends` is a quotient rather than a reading. These are not a lifetime record; an identity with no traffic in the window reports zeroes.
1075
+ */
1076
+ export type DeliverabilityFacts = {
1077
+ bounceRate: number;
1078
+ complaintRate: number;
1079
+ windowSends: number;
1080
+ sendingStatus: "enabled" | "disabled" | "reinstated" | "unknown";
1081
+ };
1082
+ export type CustomTrackingDomainConnectCompleteResult = {
1083
+ status: "applied" | "cancelled" | "failed" | "stale" | "invalid";
1084
+ };
1085
+ export type DomainConnectApplyUrlResult = {
1086
+ url: string;
1087
+ };
1088
+ export type DomainConnectEligibility = {
1089
+ eligible: false;
1090
+ reason: "no-record" | "no-settings" | "no-sync" | "no-template" | "unavailable";
1091
+ } | {
1092
+ eligible: true;
1093
+ providerName?: string | null | undefined;
1094
+ };
1095
+ export type CustomTrackingStatus = {
1096
+ enabled: boolean;
1097
+ customTracking: {
1098
+ status: "pending" | "caa-blocked" | "active" | "teardown-scheduled" | "disabled";
1099
+ label: string;
1100
+ hostname: string;
1101
+ region: string;
1102
+ sslStatus: string | null;
1103
+ dnsRecords: {
1104
+ tracking: CustomTrackingDnsRecord | null;
1105
+ dcvDelegation: CustomTrackingDnsRecord | null;
1106
+ };
1107
+ caaBlocked: boolean;
1108
+ verificationErrors: Array<string>;
1109
+ teardownScheduledAt: string | null;
1110
+ } | null;
1111
+ };
1112
+ export type CustomTrackingDnsRecord = {
1113
+ name: string;
1114
+ type: string;
1115
+ value: string;
1116
+ };
1117
+ export type DomainConnectCompleteResult = {
1118
+ status: "applied" | "cancelled" | "failed" | "invalid";
1119
+ };
1120
+ export type EmailDomainDetailed = {
1121
+ id: EmailDomainId;
1122
+ domain: string;
1123
+ phase: "dns-setup" | "provisioning" | "verifying" | "ready" | "degraded" | "failed";
1124
+ dkimSelector?: string | null | undefined;
1125
+ dkimPublicKey?: string | null | undefined;
1126
+ dnsRecords: Array<{
1127
+ type: "A" | "AAAA" | "CNAME" | "MX" | "NS" | "SOA" | "PTR" | "SRV" | "TXT" | "CAA";
1128
+ name: string;
1129
+ value: string;
1130
+ ttl?: string | null | undefined;
1131
+ description?: string | null | undefined;
1132
+ priority?: number | null | undefined;
1133
+ }>;
1134
+ verifiedAt: string | null;
1135
+ isDefault: boolean;
1136
+ defaultSenderId: EmailSenderId | null;
1137
+ deliverability: DeliverabilityFacts;
1138
+ createdAt: string;
1139
+ updatedAt: string;
1140
+ };
1141
+ export type RateLimitedError = {
1142
+ _tag: "RateLimitedError";
1143
+ retryAfterSeconds: number;
1144
+ };
1145
+ export type EmailDomainVerification = {
1146
+ domainId: EmailDomainId;
1147
+ domain: string;
1148
+ phase: "dns-setup" | "provisioning" | "verifying" | "ready" | "degraded" | "failed";
1149
+ dns: {
1150
+ observed: boolean;
1151
+ total: number;
1152
+ satisfied: number;
1153
+ missing: number;
1154
+ mismatch: number;
1155
+ unknown: number;
1156
+ };
1157
+ requirements: Array<{
1158
+ key: string;
1159
+ record: {
1160
+ type: "A" | "AAAA" | "CNAME" | "MX" | "NS" | "SOA" | "PTR" | "SRV" | "TXT" | "CAA";
1161
+ name: string;
1162
+ value: string;
1163
+ ttl?: string | null | undefined;
1164
+ description?: string | null | undefined;
1165
+ priority?: number | null | undefined;
1166
+ };
1167
+ status: "satisfied" | "missing" | "mismatch" | "unknown";
1168
+ evidence: Array<{
1169
+ _tag: "PublicDns";
1170
+ resolver: string;
1171
+ status: "satisfied" | "missing" | "mismatch" | "unknown";
1172
+ values: Array<string>;
1173
+ detail: string | null;
1174
+ observedAt: string;
1175
+ } | {
1176
+ _tag: "Provider";
1177
+ provider: string;
1178
+ status: "satisfied" | "missing" | "mismatch" | "unknown";
1179
+ values: Array<string>;
1180
+ detail: string | null;
1181
+ observedAt: string;
1182
+ } | {
1183
+ _tag: "Host";
1184
+ source: string;
1185
+ status: "ok" | "pending" | "failed";
1186
+ label: string;
1187
+ detail: string | null;
1188
+ observedAt: string;
1189
+ }>;
1190
+ }>;
1191
+ provider: {
1192
+ identity: "pending" | "verified" | "failed" | "unknown";
1193
+ dkim?: "pending" | "verified" | "failed" | "unknown" | null | undefined;
1194
+ mailFrom?: "pending" | "verified" | "failed" | "unknown" | null | undefined;
1195
+ } | null;
1196
+ operationId: OperationId | null;
1197
+ checkedAt: string | null;
1198
+ nextCheckAt: string | null;
1199
+ failure: {
1200
+ code: string;
1201
+ message: string;
1202
+ failedAt: string;
1203
+ } | null;
1204
+ provisioning: EmailDomainProvisioningExecution;
1205
+ health: {
1206
+ actionOwner: "customer" | "samva" | "upstream" | "none";
1207
+ action: string;
1208
+ freshness: "current" | "stale" | "unknown";
1209
+ observedAt: string | null;
1210
+ staleAt: string | null;
1211
+ nextRetryAt: string | null;
1212
+ reason: "ready" | "dns-action-required" | "dns-unavailable" | "verification-pending" | "verification-failed" | "samva-repair" | "signing-custody-action-required" | "ownership-conflict" | "inactive" | "observation-stale" | "observation-unknown";
1213
+ };
1214
+ /**
1215
+ * Whether the domain, the organization, and its sending account are healthy enough to send, as last observed. Ready does not guarantee that a particular send is accepted.
1216
+ */
1217
+ sending: {
1218
+ actionOwner: "customer" | "samva" | "upstream" | "none";
1219
+ action: string;
1220
+ freshness: "current" | "stale" | "unknown";
1221
+ observedAt: string | null;
1222
+ staleAt: string | null;
1223
+ nextRetryAt: string | null;
1224
+ status: "ready" | "blocked" | "unknown";
1225
+ reason: "domain-not-ready" | "domain-observation-stale" | "operator-paused" | "sending-paused" | "sending-status-unknown" | "ready";
1226
+ };
1227
+ dmarc: {
1228
+ status: "valid" | "missing" | "invalid" | "multiple" | "unknown";
1229
+ source: "direct" | "organizational" | "none";
1230
+ policyDomain: string | null;
1231
+ policy: "none" | "quarantine" | "reject" | null;
1232
+ subdomainPolicy: "none" | "quarantine" | "reject" | null;
1233
+ effectivePolicy: "none" | "quarantine" | "reject" | null;
1234
+ observedAt: string | null;
1235
+ staleAt: string | null;
1236
+ guidance: string;
1237
+ };
1238
+ rotation: EmailDkimRotation | null;
1239
+ };
1240
+ export type EmailDkimRotation = {
1241
+ id: string;
1242
+ domainId: EmailDomainId;
1243
+ phase: "staged" | "cutover" | "complete";
1244
+ selector: string;
1245
+ record: {
1246
+ name: string;
1247
+ type: "TXT";
1248
+ value: string;
1249
+ ttl: string;
1250
+ };
1251
+ formerRecord: {
1252
+ name: string;
1253
+ type: "TXT";
1254
+ value: string;
1255
+ };
1256
+ /**
1257
+ * The earliest time the former DKIM record may be removed. Keep it published at least until then so mail signed with the former key still verifies.
1258
+ */
1259
+ minimumRetainUntil: string | null;
1260
+ };
1261
+ export type EmailDomainProvisioningExecution = {
1262
+ status: "none" | "running" | "succeeded" | "failed";
1263
+ generation: number;
1264
+ revision: number;
1265
+ };
1266
+ export type EmailRecipientTrackingPreference = {
1267
+ email: TrackingRecipientEmail;
1268
+ optedOut: boolean;
1269
+ trackingOptedOutAt: string | null;
1270
+ createdAt: string | null;
1271
+ updatedAt: string | null;
1272
+ };
1273
+ export type TrackingRecipientEmail = string;
1274
+ export type EmailTrackingDefaults = {
1275
+ opens: boolean;
1276
+ clicks: boolean;
1277
+ };
1278
+ export type OnboardingReviewStatus = {
1279
+ decision: "undecided" | "approved" | "rejected";
1280
+ trustTier: "screened" | "probation" | "established";
1281
+ stage: "collecting" | "automated_review" | "manual_review" | "information_requested" | "complete";
1282
+ generation: number;
1283
+ canSend: boolean;
1284
+ code: "review_required" | "review_in_progress" | "information_required" | "review_rejected" | "identity_review_required" | "identity_review_rejected" | "identity_changed" | null;
1285
+ nextAction: "wait_for_review" | "provide_information" | "verify_sending_identity" | "reapply" | "contact_support" | null;
1286
+ canReapply: boolean;
1287
+ informationRequest: {
1288
+ id: string;
1289
+ requestedFields: Array<string>;
1290
+ requestedAt: string;
1291
+ canRespond: boolean;
1292
+ } | null;
1293
+ identities: Array<IdentityClearanceStatus>;
1294
+ updatedAt: string | null;
1295
+ };
1296
+ export type IdentityClearanceStatus = {
1297
+ identityId: string;
1298
+ decision: "undecided" | "approved" | "rejected";
1299
+ generation: number;
1300
+ canSend: boolean;
1301
+ code: "review_required" | "review_in_progress" | "information_required" | "review_rejected" | "identity_review_required" | "identity_review_rejected" | "identity_changed" | null;
1302
+ nextAction: "wait_for_review" | "provide_information" | "verify_sending_identity" | "reapply" | "contact_support" | null;
1303
+ updatedAt: string;
1304
+ };
1305
+ export type RespondToOnboardingInformationRequestInput = {
1306
+ expectedGeneration: number;
1307
+ responseText: string;
1308
+ evidenceMediaIds: Array<MediaId>;
1309
+ };
1310
+ export type ReapplyOnboardingReviewInput = {
1311
+ expectedGeneration: number;
1312
+ };
1313
+ export type CampaignRunId = string;
1314
+ export type CampaignRecipientId = string;
1315
+ export type CampaignId = string;
1316
+ export type CampaignRunAction = {
1317
+ success: boolean;
1318
+ item: CampaignRun;
1319
+ };
1320
+ export type CampaignRun = {
1321
+ id: CampaignRunId;
1322
+ campaignId: CampaignId;
1323
+ status: "scheduled" | "resolving" | "dispatching" | "paused" | "completed" | "cancelled" | "failed";
1324
+ scheduledFor: string;
1325
+ idempotencyKey: string | null;
1326
+ startedAt: string | null;
1327
+ completedAt: string | null;
1328
+ contentSnapshot: CampaignContent;
1329
+ audienceSnapshot: CampaignAudience;
1330
+ policySnapshot: CampaignPolicy;
1331
+ totalRecipients: number;
1332
+ dispatchedCount: number;
1333
+ failedCount: number;
1334
+ skippedCount: number;
1335
+ estimatedCompletionAt: string | null;
1336
+ failureReason: string | null;
1337
+ holdReason: string | null;
1338
+ holdDomainId: EmailDomainId | null;
1339
+ lastContactId: string | null;
1340
+ createdBy: string | null;
1341
+ actorEmail: string;
1342
+ memberRole: string;
1343
+ createdAt: string;
1344
+ updatedAt: string;
1367
1345
  };
1368
- export type BrandFooterBlock = {
1369
- html: string;
1370
- text: string;
1346
+ export type CampaignPolicy = {
1347
+ unsubscribeGroupId?: UnsubscribeId | null | undefined;
1348
+ pageSize?: number | null | undefined;
1371
1349
  };
1372
- export type BrandRenderedFooter = {
1373
- withUnsubscribe: BrandFooterBlock;
1374
- withoutUnsubscribe: BrandFooterBlock;
1350
+ export type CampaignAudience = {
1351
+ includeTags?: Array<string> | null | undefined;
1352
+ excludeTags?: Array<string> | null | undefined;
1353
+ contactIds?: Array<ContactId> | null | undefined;
1354
+ groupIds?: Array<ContactGroupId> | null | undefined;
1375
1355
  };
1376
- export type BrandId = string;
1377
- export type Brand = {
1378
- id: BrandId;
1379
- /**
1380
- * The brand's handle, unique in the organization; `samva:brand/<slug>` names it.
1381
- */
1382
- slug: string;
1383
- name: string;
1384
- /**
1385
- * Whether bare `samva:brand` and domains without a brand resolve to this brand.
1386
- */
1387
- isDefault: boolean;
1388
- /**
1389
- * Brand theme CSS: `@theme` variables, one dark-mode `@theme` of colors, and `@font-face` rules with https WOFF2 sources.
1390
- */
1391
- css: string;
1392
- assets: BrandAssets;
1393
- footer: BrandFooter;
1394
- /**
1395
- * SHA-256 of the brand's css, assets and footer. A publication built against a different digest predates the brand's current content.
1396
- */
1397
- digest: string;
1398
- createdAt: string;
1399
- updatedAt: string;
1356
+ export type CampaignContent = EmailCampaignContent;
1357
+ export type CampaignContentMetadata = {
1358
+ [key: string]: JsonValue;
1359
+ } | null;
1360
+ export type CampaignConversationRef = ConversationId | null | null;
1361
+ export type EmailCampaignContent = {
1362
+ channel: "email";
1363
+ email: EmailContent;
1364
+ conversationId?: CampaignConversationRef | undefined;
1365
+ metadata?: CampaignContentMetadata | undefined;
1400
1366
  };
1401
- export type BrandList = {
1402
- items: Array<Brand>;
1367
+ export type EmailContent = {
1368
+ subject?: string | null | undefined;
1369
+ html?: string | null | undefined;
1370
+ text?: string | null | undefined;
1371
+ attachments?: EmailAttachments | undefined;
1372
+ publicationId?: TemplatePublicationId | undefined;
1373
+ inputContractId?: TemplateInputContractId | undefined;
1374
+ templateId?: TemplateId | null | undefined;
1375
+ templateSlug?: string | null | undefined;
1376
+ templateData?: TemplateData | undefined;
1377
+ locale?: RenderLocale | undefined;
1378
+ timeZone?: RenderTimeZone | undefined;
1379
+ inReplyToMessageId?: MessageId | null | undefined;
1380
+ replyTo?: ReplyToAddresses | undefined;
1381
+ unsubscribeGroupId?: UnsubscribeId | null | undefined;
1382
+ tracking?: EmailTrackingOverrideV1 | undefined;
1383
+ footer?: EmailFooterOverride | undefined;
1403
1384
  };
1404
- export type CreateBrand = {
1405
- slug: string;
1406
- name: string;
1407
- css?: string | null | undefined;
1408
- assets?: BrandAssets | null | undefined;
1409
- footer?: BrandFooter | null | undefined;
1410
- isDefault?: boolean | null | undefined;
1385
+ export type EmailFooterOverride = {
1386
+ enabled?: boolean | null | undefined;
1411
1387
  };
1412
- export type UpdateBrand = {
1413
- newSlug?: string | null | undefined;
1414
- name?: string | null | undefined;
1415
- css?: string | null | undefined;
1416
- assets?: BrandAssets | null | undefined;
1417
- footer?: BrandFooter | null | undefined;
1388
+ export type ReplyToAddresses = Array<string> | null | null;
1389
+ export type RenderTimeZone = string;
1390
+ export type RenderLocale = string;
1391
+ export type TemplateData = JsonObject | null;
1392
+ export type EmailAttachments = Array<EmailAttachment> | null;
1393
+ export type EmailAttachment = {
1394
+ filename: string;
1395
+ content?: string | null | undefined;
1396
+ mediaId?: MediaId | null | undefined;
1397
+ contentType: string;
1398
+ size: number;
1418
1399
  };
1419
- export type CreateWebhookPayload = {
1420
- name: string;
1421
- url: string;
1422
- eventTypes: Array<"message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.bounced" | "message.complained" | "message.received" | "message.opened" | "message.clicked" | "contact.created" | "contact.updated" | "contact.deleted" | "contact.unsubscribed" | "contact.resubscribed" | "conversation.created" | "conversation.updated" | "conversation.archived" | "webhook.created" | "webhook.updated" | "webhook.deleted" | "webhook.test" | "domain.updated" | "domain.warming.updated">;
1423
- channels?: Array<"email"> | null | undefined;
1424
- headers?: {
1425
- [key: string]: string;
1426
- } | null | undefined;
1427
- status?: "active" | "disabled" | null | undefined;
1400
+ export type CampaignFooterRequiredError = {
1401
+ _tag: "CampaignFooterRequiredError";
1402
+ message: string;
1428
1403
  };
1429
- export type WebhookEndpoint = {
1430
- id: WebhookEndpointId;
1431
- name: string;
1432
- url: string;
1433
- eventTypes: Array<"message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.bounced" | "message.complained" | "message.received" | "message.opened" | "message.clicked" | "contact.created" | "contact.updated" | "contact.deleted" | "contact.unsubscribed" | "contact.resubscribed" | "conversation.created" | "conversation.updated" | "conversation.archived" | "webhook.created" | "webhook.updated" | "webhook.deleted" | "webhook.test" | "domain.updated" | "domain.warming.updated">;
1434
- channels: Array<"email"> | null;
1435
- status: "active" | "disabled";
1436
- hasCustomHeaders: boolean;
1437
- failureStartedAt: string | null;
1438
- lastSucceededAt: string | null;
1439
- createdAt: string;
1440
- updatedAt: string;
1404
+ export type BrandAddressRequiredError = {
1405
+ _tag: "BrandAddressRequiredError";
1406
+ message: string;
1407
+ brand: string | null;
1441
1408
  };
1442
- export type WebhookDeliveryCounts = {
1443
- total: number;
1444
- pending: number;
1445
- delivered: number;
1446
- exhausted: number;
1447
- cancelled: number;
1409
+ export type FlagDisabledError = {
1410
+ _tag: "FlagDisabledError";
1411
+ flag: string;
1448
1412
  };
1449
- export type WebhookEndpointListItem = {
1450
- id: WebhookEndpointId;
1413
+ export type Campaign = {
1414
+ id: CampaignId;
1451
1415
  name: string;
1452
- url: string;
1453
- eventTypes: Array<"message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.bounced" | "message.complained" | "message.received" | "message.opened" | "message.clicked" | "contact.created" | "contact.updated" | "contact.deleted" | "contact.unsubscribed" | "contact.resubscribed" | "conversation.created" | "conversation.updated" | "conversation.archived" | "webhook.created" | "webhook.updated" | "webhook.deleted" | "webhook.test" | "domain.updated" | "domain.warming.updated">;
1454
- channels: Array<"email"> | null;
1455
- status: "active" | "disabled";
1456
- hasCustomHeaders: boolean;
1457
- failureStartedAt: string | null;
1458
- lastSucceededAt: string | null;
1416
+ channel: "email";
1417
+ content: CampaignContent;
1418
+ audience: CampaignAudience;
1419
+ policy: CampaignPolicy;
1420
+ definition: CampaignDefinitionSummary;
1421
+ latestRun: CampaignLatestRun | null;
1422
+ createdBy: string | null;
1423
+ actorEmail: string;
1424
+ memberRole: string;
1459
1425
  createdAt: string;
1460
1426
  updatedAt: string;
1461
- deliveries: WebhookDeliveryCounts;
1462
1427
  };
1463
- export type UpdateWebhookPayload = {
1464
- name?: string | null | undefined;
1465
- url?: string | null | undefined;
1466
- eventTypes?: Array<"message.sent" | "message.delivered" | "message.read" | "message.failed" | "message.bounced" | "message.complained" | "message.received" | "message.opened" | "message.clicked" | "contact.created" | "contact.updated" | "contact.deleted" | "contact.unsubscribed" | "contact.resubscribed" | "conversation.created" | "conversation.updated" | "conversation.archived" | "webhook.created" | "webhook.updated" | "webhook.deleted" | "webhook.test" | "domain.updated" | "domain.warming.updated"> | null | undefined;
1467
- channels?: Array<"email"> | null | null | undefined;
1468
- headers?: {
1469
- [key: string]: string;
1470
- } | null | undefined;
1471
- status?: "active" | "disabled" | null | undefined;
1428
+ export type CampaignLatestRun = {
1429
+ id: CampaignRunId;
1430
+ status: "scheduled" | "resolving" | "dispatching" | "paused" | "completed" | "cancelled" | "failed";
1431
+ scheduledFor: string;
1432
+ completedAt: string | null;
1433
+ totalRecipients: number;
1434
+ dispatchedCount: number;
1435
+ failedCount: number;
1436
+ skippedCount: number;
1437
+ estimatedCompletionAt: string | null;
1472
1438
  };
1473
- export type TestWebhookPayload = {
1474
- data?: {
1475
- [key: string]: JsonValue;
1476
- } | null | undefined;
1439
+ export type CampaignDefinitionSummary = {
1440
+ state: "editable" | "frozen" | "archived";
1441
+ frozenAt: string | null;
1477
1442
  };
1478
- export type WebhookEventId = string;
1479
- export type WebhookDeliveryId = string;
1480
- export type WebhookAttemptId = string;
1481
- export type WebhookDailyDeliveries = {
1482
- date: string;
1483
- pending: number;
1484
- delivered: number;
1485
- exhausted: number;
1486
- cancelled: number;
1443
+ export type CampaignContentInput = EmailCampaignContentInput;
1444
+ export type EmailCampaignContentInput = {
1445
+ channel: "email";
1446
+ email: EmailDispatchContent;
1447
+ conversationId?: CampaignConversationRef | undefined;
1448
+ metadata?: CampaignContentMetadata | undefined;
1487
1449
  };
1488
- export type WebhookStatsResponse = {
1489
- total: number;
1490
- pending: number;
1491
- delivered: number;
1492
- exhausted: number;
1493
- cancelled: number;
1494
- daily: Array<WebhookDailyDeliveries>;
1450
+ export type EmailDispatchContent = {
1451
+ subject?: string | null | undefined;
1452
+ html?: string | null | undefined;
1453
+ text?: string | null | undefined;
1454
+ attachments?: EmailAttachments | undefined;
1455
+ publicationId?: TemplatePublicationId | undefined;
1456
+ inputContractId?: TemplateInputContractId | undefined;
1457
+ templateId?: TemplateId | null | undefined;
1458
+ templateSlug?: string | null | undefined;
1459
+ templateData?: TemplateData | undefined;
1460
+ locale?: RenderLocale | undefined;
1461
+ timeZone?: RenderTimeZone | undefined;
1462
+ inReplyToMessageId?: MessageId | null | undefined;
1463
+ replyTo?: ReplyToAddresses | undefined;
1464
+ unsubscribeGroupId?: UnsubscribeId | null | undefined;
1465
+ tracking?: EmailTrackingOverrideV1 | undefined;
1466
+ footer?: EmailFooterOverride | undefined;
1495
1467
  };
1496
- export type Organization = {
1497
- id: string;
1498
- billingAccountId: string;
1468
+ export type CampaignListItem = {
1469
+ id: CampaignId;
1499
1470
  name: string;
1500
- slug: string;
1501
- countryCode: string;
1471
+ channel: "email";
1472
+ content: CampaignContent;
1473
+ audience: CampaignAudience;
1474
+ policy: CampaignPolicy;
1475
+ definition: CampaignDefinitionSummary;
1476
+ latestRun: CampaignLatestRun | null;
1477
+ createdBy: string | null;
1478
+ actorEmail: string;
1479
+ memberRole: string;
1480
+ createdAt: string;
1481
+ updatedAt: string;
1482
+ series: SendsSeries;
1483
+ };
1484
+ export type ScheduledMessage = {
1485
+ id: ScheduledMessageId;
1486
+ status: "pending" | "dispatching" | "paused" | "dispatched" | "cancelled" | "failed";
1487
+ scheduledFor: string;
1502
1488
  timezone: string;
1503
- plan: string;
1504
- isActive: boolean;
1489
+ send: SendMessagePayload;
1490
+ messageId: MessageId | null;
1491
+ idempotencyKey: string | null;
1492
+ referenceId: string | null;
1493
+ failureReason: string | null;
1494
+ attempts: number;
1495
+ createdBy: string | null;
1496
+ actorEmail: string;
1497
+ memberRole: string;
1505
1498
  createdAt: string;
1506
1499
  updatedAt: string;
1507
- metadata: {
1508
- [key: string]: JsonValue;
1509
- } | null;
1510
- replyToDefault: Array<string> | null;
1511
- emailFooterEnabledDefault: boolean | null;
1512
- messagesUsed: number;
1513
- messagesUsedThisMonth: number;
1514
- emailUsed: number;
1515
- emailUsedThisMonth: number;
1516
- contactsUsed: number;
1517
- conversationsUsed: number;
1518
- teamMembersUsed: number;
1519
- messagesResetAt: string | null;
1520
1500
  };
1521
- export type ApiKeyResourceAccess = {
1522
- messages?: "read" | "write" | null | undefined;
1523
- email?: "read" | "write" | null | undefined;
1524
- domains?: "read" | "write" | null | undefined;
1525
- phoneNumbers?: "read" | "write" | null | undefined;
1526
- contacts?: "read" | "write" | null | undefined;
1527
- conversations?: "read" | "write" | null | undefined;
1528
- templates?: "read" | "write" | null | undefined;
1529
- competitors?: "read" | "write" | null | undefined;
1530
- webhooks?: "read" | "write" | null | undefined;
1531
- apiKeys?: "read" | "write" | null | undefined;
1532
- organization?: "read" | "write" | null | undefined;
1533
- billing?: "read" | "write" | null | undefined;
1534
- analytics?: "read" | "write" | null | undefined;
1501
+ export type SendMessagePayload = EmailSendMessagePayload;
1502
+ export type MessageMetadata = {
1503
+ [key: string]: JsonValue;
1504
+ } | null;
1505
+ export type EmailSendMessagePayload = {
1506
+ conversationId?: ConversationId | null | null | undefined;
1507
+ metadata?: MessageMetadata | undefined;
1508
+ channel: "email";
1509
+ to: EmailRecipients;
1510
+ cc?: EmailCcRecipients | undefined;
1511
+ bcc?: EmailBccRecipients | undefined;
1512
+ from?: EmailSender | undefined;
1513
+ email: EmailContent;
1535
1514
  };
1536
- export type ApiKeyAccess = {
1537
- mode: "full";
1515
+ export type EmailSender = {
1516
+ email: string;
1517
+ name?: string | null | undefined;
1518
+ } | null;
1519
+ export type EmailBccRecipients = Array<EmailRecipient> | null | null;
1520
+ export type EmailRecipient = {
1521
+ contactId: ContactId;
1538
1522
  } | {
1539
- mode: "restricted";
1540
- resources: ApiKeyResourceAccess;
1541
- };
1542
- export type ApiKeyOwner = {
1543
- id: string;
1544
- name: string;
1545
1523
  email: string;
1524
+ name?: string | null | undefined;
1525
+ displayName?: string | null | null | undefined;
1546
1526
  };
1547
- export type ApiKeyWithSecret = {
1548
- id: string;
1549
- name: string;
1550
- key: string;
1551
- start: string | null;
1552
- description?: string | null | undefined;
1553
- createdAt: string;
1554
- expiresAt: string | null;
1555
- lastUsedAt: string | null;
1556
- isActive: boolean;
1557
- access: ApiKeyAccess;
1558
- owner: ApiKeyOwner | null;
1527
+ export type EmailCcRecipients = Array<EmailRecipient> | null | null;
1528
+ export type EmailRecipients = Array<EmailRecipient>;
1529
+ export type ScheduledMessageId = string;
1530
+ export type DispatchSendMessagePayload = EmailDispatchSendMessagePayload;
1531
+ export type EmailDispatchSendMessagePayload = {
1532
+ conversationId?: ConversationId | null | null | undefined;
1533
+ metadata?: MessageMetadata | undefined;
1534
+ channel: "email";
1535
+ to: EmailRecipients;
1536
+ cc?: EmailCcRecipients | undefined;
1537
+ bcc?: EmailBccRecipients | undefined;
1538
+ from?: EmailSender | undefined;
1539
+ email: EmailDispatchContent;
1559
1540
  };
1560
- export type ApiKey = {
1561
- id: string;
1562
- name: string;
1563
- key?: string | null | undefined;
1564
- start: string | null;
1565
- description?: string | null | undefined;
1566
- createdAt: string;
1567
- expiresAt: string | null;
1568
- lastUsedAt: string | null;
1569
- isActive: boolean;
1570
- access: ApiKeyAccess;
1571
- owner: ApiKeyOwner | null;
1541
+ export type MessageEventId = string;
1542
+ export type ValidateEmailResponse = {
1543
+ valid: true;
1544
+ from: {
1545
+ email: string;
1546
+ name: string | null;
1547
+ };
1548
+ recipientCount: number;
1549
+ content: {
1550
+ source: "inline" | "template";
1551
+ subject: string;
1552
+ hasHtml: boolean;
1553
+ hasText: boolean;
1554
+ };
1555
+ };
1556
+ export type DeliveryUnavailableError = {
1557
+ _tag: "DeliveryUnavailableError";
1558
+ message: string;
1559
+ retryAfterSeconds: number;
1560
+ };
1561
+ export type OnboardingReviewRequiredError = {
1562
+ _tag: "OnboardingReviewRequiredError";
1563
+ code: "review_required" | "review_in_progress" | "information_required" | "review_rejected" | "identity_review_required" | "identity_review_rejected" | "identity_changed";
1564
+ decision: "undecided" | "approved" | "rejected";
1565
+ stage: "collecting" | "automated_review" | "manual_review" | "information_requested" | "complete";
1566
+ nextAction: "wait_for_review" | "provide_information" | "verify_sending_identity" | "reapply" | "contact_support";
1567
+ identityId?: string | null | undefined;
1568
+ };
1569
+ export type EmailAddress = {
1570
+ email: string;
1571
+ name: string | null;
1572
1572
  };
1573
1573
  export type JsonValue = string | number | boolean | null | Array<JsonValue> | {
1574
1574
  [key: string]: JsonValue;
@@ -9675,133 +9675,6 @@ export type TemplatesPutWorkspaceAssetResponses = {
9675
9675
  };
9676
9676
  };
9677
9677
  export type TemplatesPutWorkspaceAssetResponse = TemplatesPutWorkspaceAssetResponses[keyof TemplatesPutWorkspaceAssetResponses];
9678
- export type TemplatesReconcileWorkspaceData = {
9679
- body: {
9680
- expectedRevision: string;
9681
- assetResolution?: "draft" | "remote" | undefined;
9682
- expectedRemoteHead?: string | undefined;
9683
- idempotencyKey: string;
9684
- };
9685
- path: {
9686
- id: TemplateId;
9687
- };
9688
- query?: never;
9689
- url: "/v1/templates/{id}/workspace/reconcile";
9690
- };
9691
- export type TemplatesReconcileWorkspaceErrors = {
9692
- /**
9693
- * UnauthorizedError
9694
- */
9695
- 401: UnauthorizedError;
9696
- /**
9697
- * ForbiddenError
9698
- */
9699
- 403: ForbiddenError;
9700
- /**
9701
- * ResourceNotFoundError
9702
- */
9703
- 404: ResourceNotFoundError;
9704
- /**
9705
- * ConflictError
9706
- */
9707
- 409: ConflictError;
9708
- /**
9709
- * InternalError
9710
- */
9711
- 500: InternalError;
9712
- /**
9713
- * GatewayTimeoutError
9714
- */
9715
- 504: GatewayTimeoutError;
9716
- };
9717
- export type TemplatesReconcileWorkspaceError = TemplatesReconcileWorkspaceErrors[keyof TemplatesReconcileWorkspaceErrors];
9718
- export type TemplatesReconcileWorkspaceResponses = {
9719
- /**
9720
- * Success
9721
- */
9722
- 200: {
9723
- workspace: {
9724
- projectId: TemplateProjectId;
9725
- organizationId: OrganizationId | null;
9726
- ownerEpoch: number;
9727
- repositoryName: string;
9728
- defaultBranch: string;
9729
- baseCommit: string;
9730
- remoteHead: string;
9731
- pendingRemoteHead: string | null;
9732
- revision: string;
9733
- overlay: {
9734
- [key: string]: string | null;
9735
- };
9736
- assetChanges: Array<{
9737
- path: string;
9738
- status: "added" | "modified" | "deleted";
9739
- }>;
9740
- conflicts: Array<{
9741
- path: string;
9742
- base: string | null;
9743
- draft: string | null;
9744
- main: string | null;
9745
- }>;
9746
- provenance: {
9747
- references: Array<{
9748
- kind: string;
9749
- digest: string;
9750
- locator?: string | undefined;
9751
- }>;
9752
- };
9753
- mounts: Array<{
9754
- kind: "project";
9755
- root: "/project";
9756
- access: "read-write";
9757
- } | {
9758
- root: string;
9759
- digest: string;
9760
- fileCount: number;
9761
- byteSize: number;
9762
- kind: "started-from";
9763
- access: "read-only";
9764
- templateId: string;
9765
- slug: string;
9766
- name: string;
9767
- } | {
9768
- root: string;
9769
- digest: string;
9770
- fileCount: number;
9771
- byteSize: number;
9772
- kind: "resource";
9773
- access: "read-only";
9774
- resourceId: string;
9775
- name: string;
9776
- } | {
9777
- root: string;
9778
- digest: string;
9779
- fileCount: number;
9780
- byteSize: number;
9781
- kind: "library-template";
9782
- access: "read-only";
9783
- templateId: string;
9784
- slug: string;
9785
- name: string;
9786
- }>;
9787
- libraryManifestDigest: string;
9788
- createdAt: string;
9789
- updatedAt: string;
9790
- createdBy: {
9791
- userId: UserId;
9792
- via: "api" | "mcp" | "agent";
9793
- };
9794
- updatedBy: {
9795
- userId: UserId;
9796
- via: "api" | "mcp" | "agent";
9797
- };
9798
- };
9799
- files: {
9800
- [key: string]: string;
9801
- };
9802
- };
9803
- };
9804
- export type TemplatesReconcileWorkspaceResponse = TemplatesReconcileWorkspaceResponses[keyof TemplatesReconcileWorkspaceResponses];
9805
9678
  export type TemplatesResolveWorkspaceConflictData = {
9806
9679
  body: {
9807
9680
  expectedRevision: string;