@messagebird/sdk 0.2.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts DELETED
@@ -1,2135 +0,0 @@
1
- /** Transport metadata exposed to callers via `.withResponse()`. */
2
- interface BirdResponse {
3
- status: number;
4
- headers: Headers;
5
- /** Correlation ID — the `X-Request-Id` header. */
6
- requestId: string;
7
- }
8
- /** Per-request lifecycle inputs, supplied by the resource method. */
9
- interface RequestLifecycleOptions {
10
- /** HTTP method — decides idempotency-key generation and retry safety. */
11
- method: string;
12
- /** Caller-supplied idempotency key; auto-generated for mutations if absent. */
13
- idempotencyKey?: string;
14
- /** Caller cancellation. */
15
- signal?: AbortSignal;
16
- /** Per-attempt timeout (ms). Overrides the client default. */
17
- timeout?: number;
18
- /** Max retry attempts. Overrides the client default. */
19
- maxRetries?: number;
20
- }
21
- /** The shape a generated hey-api SDK call resolves to. */
22
- interface FetchOutcome<T> {
23
- data?: T;
24
- error?: unknown;
25
- /** Present whenever the HTTP round-trip completed; absent only on a rejected call. */
26
- response?: Response;
27
- }
28
- /** Context handed to the call thunk on each attempt. */
29
- interface AttemptContext {
30
- signal: AbortSignal;
31
- idempotencyKey?: string;
32
- }
33
- interface CoreDefaults {
34
- /** Per-attempt timeout (ms). */
35
- timeout: number;
36
- /** Max retry attempts. */
37
- maxRetries: number;
38
- }
39
- declare class BirdHTTPClient {
40
- private readonly defaults;
41
- constructor(defaults: CoreDefaults);
42
- /**
43
- * Run a generated hey-api SDK call through the request lifecycle.
44
- *
45
- * @param call Invokes the SDK function; receives the per-attempt signal and
46
- * the idempotency key to set as a header.
47
- * @returns the parsed body plus transport metadata.
48
- * @throws a `BirdError` subclass on terminal failure; the native
49
- * `AbortError` if the caller's signal aborts.
50
- */
51
- request<T>(call: (ctx: AttemptContext) => Promise<FetchOutcome<T>>, options: RequestLifecycleOptions): Promise<{
52
- data: T;
53
- response: BirdResponse;
54
- }>;
55
- }
56
-
57
- /** Root of the hierarchy. Catch this to catch anything the SDK throws. */
58
- declare class BirdError extends Error {
59
- constructor(message: string);
60
- }
61
- /** Network-level failure with no HTTP response (DNS, refused, socket hangup). */
62
- declare class BirdConnectionError extends BirdError {
63
- constructor(message: string);
64
- }
65
- /** A single attempt exceeded its timeout. Retryable. */
66
- declare class BirdTimeoutError extends BirdError {
67
- readonly timeoutMs: number;
68
- constructor(message: string, timeoutMs: number);
69
- }
70
- /** A webhook payload failed signature verification (bad signature, stale timestamp, malformed headers). */
71
- declare class BirdWebhookVerificationError extends BirdError {
72
- constructor(message: string);
73
- }
74
- /** One per-field validation failure (the `details` array on a 422). */
75
- interface ErrorDetail {
76
- /** Dotted field path, e.g. `to[0].email`, `subject`, `.`. */
77
- param: string;
78
- /** What is wrong with this field. */
79
- message: string;
80
- }
81
- /** One recovery step: an operation to call to resolve the error (ADR-0073). */
82
- interface ErrorNextAction {
83
- /** operationId of the follow-up operation that resolves this error. */
84
- operation: string;
85
- /** Short human-readable label for the recovery step. */
86
- description?: string;
87
- /** Permission scope the recovery operation requires, when it is scoped. */
88
- scope?: string;
89
- }
90
- /** Constructor fields shared by every API error, mapped from the wire body. */
91
- interface BirdAPIErrorFields {
92
- statusCode: number;
93
- /** Opaque, stable error code (`E#####`). */
94
- code: string;
95
- /** Coarse category — the value callers branch on. */
96
- type: string;
97
- /** Human-readable slug for logs. Paired with `code`, never replaces it. */
98
- errorName: string;
99
- message: string;
100
- /** Stable link to the docs page for this code. */
101
- docUrl: string;
102
- /** Correlation ID — also the `X-Request-Id` response header. */
103
- requestId: string;
104
- /** Offending field, when applicable. */
105
- param?: string;
106
- /** Verbatim code from a downstream system (SMTP reply, payment decline). */
107
- vendorCode?: string;
108
- /** Human recovery line for this error, when a recovery is known (ADR-0073). */
109
- remediation?: string;
110
- /** Operations that resolve this error, in the order to try them (ADR-0073). */
111
- next?: ErrorNextAction[];
112
- }
113
- /** The server returned an error body. Base for every `type`-specific class. */
114
- declare class BirdAPIError extends BirdError {
115
- readonly statusCode: number;
116
- readonly code: string;
117
- readonly type: string;
118
- readonly errorName: string;
119
- readonly docUrl: string;
120
- readonly requestId: string;
121
- readonly param?: string;
122
- readonly vendorCode?: string;
123
- readonly remediation?: string;
124
- readonly next?: ErrorNextAction[];
125
- constructor(fields: BirdAPIErrorFields);
126
- }
127
- /** 401 — authentication failed or missing. */
128
- declare class BirdAuthError extends BirdAPIError {
129
- constructor(fields: BirdAPIErrorFields);
130
- }
131
- /** 403 — authenticated but not allowed. */
132
- declare class BirdPermissionError extends BirdAPIError {
133
- constructor(fields: BirdAPIErrorFields);
134
- }
135
- /** 404 — resource does not exist. */
136
- declare class BirdNotFoundError extends BirdAPIError {
137
- constructor(fields: BirdAPIErrorFields);
138
- }
139
- /** 409 — semantic conflict (e.g. a unique value already taken). */
140
- declare class BirdConflictError extends BirdAPIError {
141
- constructor(fields: BirdAPIErrorFields);
142
- }
143
- /** 400 — malformed request. */
144
- declare class BirdBadRequestError extends BirdAPIError {
145
- constructor(fields: BirdAPIErrorFields);
146
- }
147
- /** 402 — billing/balance problem. */
148
- declare class BirdBillingError extends BirdAPIError {
149
- constructor(fields: BirdAPIErrorFields);
150
- }
151
- /** 412/428 — a precondition was not met. */
152
- declare class BirdPreconditionError extends BirdAPIError {
153
- constructor(fields: BirdAPIErrorFields);
154
- }
155
- /** 413 — request body too large. */
156
- declare class BirdPayloadTooLargeError extends BirdAPIError {
157
- constructor(fields: BirdAPIErrorFields);
158
- }
159
- /** 500 — unexpected server error. */
160
- declare class BirdInternalError extends BirdAPIError {
161
- constructor(fields: BirdAPIErrorFields);
162
- }
163
- /** 501 — endpoint not implemented. */
164
- declare class BirdNotImplementedError extends BirdAPIError {
165
- constructor(fields: BirdAPIErrorFields);
166
- }
167
- /** 421 — request reached the wrong region (ADR-0036). */
168
- declare class BirdMisdirectedError extends BirdAPIError {
169
- constructor(fields: BirdAPIErrorFields);
170
- }
171
- /** 503 — service temporarily unavailable. */
172
- declare class BirdServiceUnavailableError extends BirdAPIError {
173
- constructor(fields: BirdAPIErrorFields);
174
- }
175
- /** 422 — field validation failed; `details` carries the per-field errors. */
176
- declare class BirdValidationError extends BirdAPIError {
177
- readonly details: ErrorDetail[];
178
- constructor(fields: BirdAPIErrorFields & {
179
- details: ErrorDetail[];
180
- });
181
- }
182
- /** 429 — rate limited; `retryAfter` is the server-advised wait in seconds. */
183
- declare class BirdRateLimitError extends BirdAPIError {
184
- readonly retryAfter?: number;
185
- constructor(fields: BirdAPIErrorFields & {
186
- retryAfter?: number;
187
- });
188
- }
189
-
190
- /** Per-request overrides accepted by every resource method. */
191
- interface RequestOptions$1 {
192
- /** Idempotency key; auto-generated for mutations if omitted, reused on retry. */
193
- idempotencyKey?: string;
194
- /** Caller cancellation. Rejects with the native `AbortError`. */
195
- signal?: AbortSignal;
196
- /** Per-attempt timeout (ms). Overrides the client default. */
197
- timeout?: number;
198
- /** Max retry attempts. Overrides the client default. */
199
- maxRetries?: number;
200
- /** Extra headers for this request. SDK-internal headers win on conflict. */
201
- headers?: Record<string, string>;
202
- }
203
- /**
204
- * The result of `.safe()` — the value or the error, never thrown. On success
205
- * `data` and the `response` envelope are present and `error` is `null`. On
206
- * failure `error` is a `BirdError` you can `instanceof`-narrow, and `data`/
207
- * `response` are `null` — the metadata you need (status, request id) is on the
208
- * error itself. A caller-initiated abort is not a Bird failure and still throws
209
- * (the native `AbortError`, ADR-0042 §1).
210
- */
211
- type SafeResult<T> = {
212
- data: T;
213
- error: null;
214
- response: BirdResponse;
215
- } | {
216
- data: null;
217
- error: BirdError;
218
- response: null;
219
- };
220
- /** Single-result return: `await` for the value, `.withResponse()` for metadata. */
221
- interface APIPromise<T> extends Promise<T> {
222
- withResponse(): Promise<{
223
- data: T;
224
- response: BirdResponse;
225
- }>;
226
- /** Resolve to `{ data, error }` instead of throwing. */
227
- safe(): Promise<SafeResult<T>>;
228
- }
229
- /** One cursor-paginated page — the wire envelope shape (snake), verbatim. */
230
- interface CursorPage<T> {
231
- data: T[];
232
- /** Pass back as `starting_after` to advance. Null at the end. */
233
- next_cursor: string | null;
234
- /** Pass back as `ending_before` to step back. Null at the start. */
235
- prev_cursor: string | null;
236
- /** Refresh anchor; pass as `ending_before` later for items since this page. */
237
- refresh_cursor: string | null;
238
- /** Total across all pages — only when `include_total=true` was passed. */
239
- total?: number | null;
240
- }
241
- /**
242
- * List return (R1): `await` resolves the first page; `for await` walks every
243
- * item across all pages, fetching subsequent pages lazily.
244
- */
245
- interface PaginatedPromise<T> extends Promise<CursorPage<T>>, AsyncIterable<T> {
246
- withResponse(): Promise<{
247
- data: CursorPage<T>;
248
- response: BirdResponse;
249
- }>;
250
- /** Resolve the first page as `{ data, error }` instead of throwing. */
251
- safe(): Promise<SafeResult<CursorPage<T>>>;
252
- }
253
-
254
- /**
255
- * Payload of the sms.undelivered event.
256
- */
257
- type EventSmsUndeliveredData = EventSmsBase & {
258
- /**
259
- * Why the message was not delivered.
260
- */
261
- error: SmsError;
262
- };
263
- /**
264
- * Bird-stable failure reason. `invalid_destination` — the number is not assigned, ported out, or malformed. `unreachable` — handset off or out of coverage. `blocked_by_carrier` — the carrier filtered the message. `blocked_by_recipient` — the recipient device blocked the sender. `landline_unreachable` — the destination is a landline that does not accept SMS. `content_rejected` — the carrier rejected the content. `sender_unregistered` — the sender is not registered for the destination. `recipient_opted_out` — the recipient is on a suppression list. `provider_unavailable` — an upstream failure after retries. `unknown` — an unmapped failure.
265
- *
266
- */
267
- type SmsErrorCode = "invalid_destination" | "unreachable" | "blocked_by_carrier" | "blocked_by_recipient" | "landline_unreachable" | "content_rejected" | "sender_unregistered" | "recipient_opted_out" | "provider_unavailable" | "unknown";
268
- /**
269
- * Failure detail for a message that could not be delivered or was rejected. Null when there is no failure.
270
- */
271
- type SmsError = {
272
- code: SmsErrorCode;
273
- /**
274
- * Human-readable explanation of the failure.
275
- */
276
- description: string;
277
- /**
278
- * Raw carrier-supplied error code, when available, for low-level debugging.
279
- */
280
- carrier_error_code?: string | null;
281
- /**
282
- * When the failure occurred.
283
- */
284
- occurred_at: string;
285
- } | null;
286
- /**
287
- * Structured key/value tag attached to an SMS message. Surfaces in list filters, the event log, and webhook payloads. Use tags for low-cardinality filtering dimensions (category, experiment ID). For arbitrary per-send context that does not need to be filterable, use `metadata`.
288
- * Tag count and per-tag size are capped to keep per-send tag payloads small — see SMSMessageSendRequest for the array maximum.
289
- *
290
- */
291
- type SmsTag = {
292
- /**
293
- * Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
294
- *
295
- */
296
- name: string;
297
- /**
298
- * Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
299
- *
300
- */
301
- value: string;
302
- };
303
- type WorkspaceId = string;
304
- type SmsMessageId = string;
305
- /**
306
- * Identity fields shared by every SMS lifecycle event payload.
307
- */
308
- type EventSmsBase = {
309
- /**
310
- * ID of the SMS message.
311
- */
312
- sms_id: SmsMessageId;
313
- /**
314
- * ID of the workspace.
315
- */
316
- workspace_id: WorkspaceId;
317
- /**
318
- * Recipient phone number in E.164 format.
319
- */
320
- to: string;
321
- /**
322
- * Sender the message was sent from — an E.164 number, an alphanumeric sender ID, or a short code.
323
- */
324
- from: string;
325
- /**
326
- * Tags provided on the send request, echoed on every event for the message so you can route and correlate without an extra lookup. Null when the message carried no tags.
327
- *
328
- */
329
- tags: Array<SmsTag> | null;
330
- /**
331
- * The metadata object provided on the send request, echoed on every event for the message so you can correlate events with your own records. Null when the message carried no metadata.
332
- *
333
- */
334
- metadata: {
335
- [key: string]: unknown;
336
- } | null;
337
- };
338
- /**
339
- * The carrier reported a non-permanent failure to deliver the message.
340
- */
341
- type EventSmsUndelivered = {
342
- /**
343
- * Event type.
344
- */
345
- type: "sms.undelivered";
346
- /**
347
- * Time the non-delivery was recorded.
348
- */
349
- timestamp: string;
350
- data: EventSmsUndeliveredData;
351
- };
352
- /**
353
- * Payload of the sms.sent event.
354
- */
355
- type EventSmsSentData = EventSmsBase & {
356
- /**
357
- * Carrier that handled the message, or null when not known.
358
- */
359
- carrier: string | null;
360
- /**
361
- * Mobile country code and mobile network code of the carrier, or null when not known.
362
- */
363
- mcc_mnc: string | null;
364
- };
365
- /**
366
- * Bird handed the message to the carrier for delivery.
367
- */
368
- type EventSmsSent = {
369
- /**
370
- * Event type.
371
- */
372
- type: "sms.sent";
373
- /**
374
- * Time the message was handed to the carrier.
375
- */
376
- timestamp: string;
377
- data: EventSmsSentData;
378
- };
379
- /**
380
- * Payload of the sms.rejected event.
381
- */
382
- type EventSmsRejectedData = EventSmsBase & {
383
- /**
384
- * Why the message was rejected before reaching the carrier.
385
- */
386
- error: SmsError;
387
- };
388
- /**
389
- * Bird rejected the message before sending it to the carrier (invalid destination, suppression, or a content/policy guard).
390
- */
391
- type EventSmsRejected = {
392
- /**
393
- * Event type.
394
- */
395
- type: "sms.rejected";
396
- /**
397
- * Time the rejection was recorded.
398
- */
399
- timestamp: string;
400
- data: EventSmsRejectedData;
401
- };
402
- /**
403
- * Payload of the sms.failed event.
404
- */
405
- type EventSmsFailedData = EventSmsBase & {
406
- /**
407
- * Why the message terminally failed.
408
- */
409
- error: SmsError;
410
- };
411
- /**
412
- * The message terminally failed and will not be delivered.
413
- */
414
- type EventSmsFailed = {
415
- /**
416
- * Event type.
417
- */
418
- type: "sms.failed";
419
- /**
420
- * Time the failure was recorded.
421
- */
422
- timestamp: string;
423
- data: EventSmsFailedData;
424
- };
425
- /**
426
- * Payload of the sms.expired event.
427
- */
428
- type EventSmsExpiredData = EventSmsBase;
429
- /**
430
- * The message's validity period elapsed before it could be delivered.
431
- */
432
- type EventSmsExpired = {
433
- /**
434
- * Event type.
435
- */
436
- type: "sms.expired";
437
- /**
438
- * Time the message expired.
439
- */
440
- timestamp: string;
441
- data: EventSmsExpiredData;
442
- };
443
- /**
444
- * Payload of the sms.delivered event.
445
- */
446
- type EventSmsDeliveredData = EventSmsBase & {
447
- /**
448
- * Carrier that delivered the message, or null when not known.
449
- */
450
- carrier: string | null;
451
- /**
452
- * Mobile country code and mobile network code of the carrier, or null when not known.
453
- */
454
- mcc_mnc: string | null;
455
- };
456
- /**
457
- * The carrier confirmed delivery of the message to the recipient handset.
458
- */
459
- type EventSmsDelivered = {
460
- /**
461
- * Event type.
462
- */
463
- type: "sms.delivered";
464
- /**
465
- * Time the carrier confirmed delivery.
466
- */
467
- timestamp: string;
468
- data: EventSmsDeliveredData;
469
- };
470
- /**
471
- * Payload of the sms.accepted event.
472
- */
473
- type EventSmsAcceptedData = EventSmsBase;
474
- /**
475
- * Bird accepted the SMS send request and queued it for processing.
476
- */
477
- type EventSmsAccepted = {
478
- /**
479
- * Event type.
480
- */
481
- type: "sms.accepted";
482
- /**
483
- * Time Bird accepted the request.
484
- */
485
- timestamp: string;
486
- data: EventSmsAcceptedData;
487
- };
488
- /**
489
- * An email address was added to the workspace's suppression list (manually, via complaint, or via hard bounce). Payload schema not yet finalized.
490
- */
491
- type EventEmailSuppressionCreated = {
492
- /**
493
- * Event type.
494
- */
495
- type: "email_suppression.created";
496
- /**
497
- * When the event occurred.
498
- */
499
- timestamp: string;
500
- /**
501
- * Event payload. The fields for this event are not yet finalized.
502
- */
503
- data: {
504
- [key: string]: never;
505
- };
506
- };
507
- /**
508
- * Payload of the email.unsubscribed event.
509
- */
510
- type EventEmailUnsubscribedData = EventEmailBase;
511
- /**
512
- * Structured key/value tag attached to an email send. Surfaces in list filters, the event log, and webhook payloads. Use tags for low-cardinality filtering dimensions (category, experiment ID, template ID). For arbitrary per-send context that does not need to be filterable, use `metadata`.
513
- * Tag count and per-tag size are capped to keep per-send tag payloads small — see EmailMessageSendRequest for the array maximum.
514
- *
515
- */
516
- type EmailTag = {
517
- /**
518
- * Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
519
- *
520
- */
521
- name: string;
522
- /**
523
- * Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
524
- *
525
- */
526
- value: string;
527
- };
528
- /**
529
- * Envelope position of a recipient on an outbound email event.
530
- */
531
- type RecipientRole = "to" | "cc" | "bcc";
532
- type RecipientId = string;
533
- type EmailId = string;
534
- /**
535
- * Identity fields shared by every email lifecycle event payload.
536
- */
537
- type EventEmailBase = {
538
- /**
539
- * ID of the email send.
540
- */
541
- email_id: EmailId;
542
- /**
543
- * ID of the recipient.
544
- */
545
- recipient_id: RecipientId;
546
- /**
547
- * ID of the workspace.
548
- */
549
- workspace_id: WorkspaceId;
550
- /**
551
- * Recipient address as it appeared on the envelope.
552
- */
553
- recipient: string;
554
- /**
555
- * Envelope position of the recipient.
556
- */
557
- recipient_role: RecipientRole;
558
- /**
559
- * Tags provided on the send request, echoed on every event for the send so you can route and correlate without an extra lookup. Null when the send carried no tags.
560
- *
561
- */
562
- tags: Array<EmailTag> | null;
563
- /**
564
- * The metadata object provided on the send request, echoed on every event for the send so you can correlate events with your own records. Null when the send carried no metadata.
565
- *
566
- */
567
- metadata: {
568
- [key: string]: unknown;
569
- } | null;
570
- };
571
- /**
572
- * Recipient unsubscribed by clicking a tracked unsubscribe link in the email. Fires once per recipient.
573
- */
574
- type EventEmailUnsubscribed = {
575
- /**
576
- * Event type.
577
- */
578
- type: "email.unsubscribed";
579
- /**
580
- * Time the unsubscribe was recorded.
581
- */
582
- timestamp: string;
583
- data: EventEmailUnsubscribedData;
584
- };
585
- /**
586
- * Payload of the email.scheduled event.
587
- */
588
- type EventEmailScheduledData = EventEmailMessageBase & {
589
- /**
590
- * When the message is scheduled to send.
591
- */
592
- scheduled_at: string;
593
- };
594
- /**
595
- * Identity fields shared by the message-level email lifecycle events (scheduled, canceled), which are not tied to a single recipient.
596
- */
597
- type EventEmailMessageBase = {
598
- /**
599
- * ID of the email send.
600
- */
601
- email_id: EmailId;
602
- /**
603
- * ID of the workspace.
604
- */
605
- workspace_id: WorkspaceId;
606
- /**
607
- * Tags provided on the send request, echoed on the event so you can route and correlate without an extra lookup. Null when the send carried no tags.
608
- *
609
- */
610
- tags: Array<EmailTag> | null;
611
- /**
612
- * The metadata object provided on the send request, echoed on the event so you can correlate events with your own records. Null when the send carried no metadata.
613
- *
614
- */
615
- metadata: {
616
- [key: string]: unknown;
617
- } | null;
618
- };
619
- /**
620
- * Bird accepted a send scheduled for a future time. Fires once per message when the schedule is created, not per recipient.
621
- */
622
- type EventEmailScheduled = {
623
- /**
624
- * Event type.
625
- */
626
- type: "email.scheduled";
627
- /**
628
- * Time the send was scheduled.
629
- */
630
- timestamp: string;
631
- data: EventEmailScheduledData;
632
- };
633
- /**
634
- * Why an email was rejected before delivery.
635
- * `recipient_suppressed` means the recipient is on the workspace suppression list, so Bird did not attempt delivery. `transmission_failed` means the message could not be transmitted for delivery. `generation_failure` means the message could not be built for delivery (a template or content issue). `policy_rejection` means the message was refused by sending policy. `domain_unverified` means the sending domain was not verified. `quota_exceeded` means the organization's send quota was reached. `recipient_not_allowed` means a recipient was not permitted for this send (for shared onboarding-domain sends, recipients must be verified workspace members).
636
- *
637
- */
638
- type EmailRejectionReason = "recipient_suppressed" | "transmission_failed" | "generation_failure" | "policy_rejection" | "domain_unverified" | "quota_exceeded" | "recipient_not_allowed";
639
- /**
640
- * Payload of the email.rejected event.
641
- */
642
- type EventEmailRejectedData = EventEmailBase & {
643
- rejection_reason: EmailRejectionReason;
644
- };
645
- /**
646
- * Bird rejected the email before sending it (suppression list hit, transmission failure, or a content/policy guard). Fires once per recipient.
647
- */
648
- type EventEmailRejected = {
649
- /**
650
- * Event type.
651
- */
652
- type: "email.rejected";
653
- /**
654
- * Time the rejection was recorded.
655
- */
656
- timestamp: string;
657
- data: EventEmailRejectedData;
658
- };
659
- type InboundEmailMessageId = string;
660
- /**
661
- * Payload of the email.received event.
662
- */
663
- type EventEmailReceivedData = {
664
- /**
665
- * ID of the received email. Use it with GET /v1/email/inbound-messages/{id} to fetch the body, raw content, and attachments.
666
- */
667
- inbound_message_id: InboundEmailMessageId;
668
- /**
669
- * ID of the workspace.
670
- */
671
- workspace_id: WorkspaceId;
672
- /**
673
- * RFC 5322 Message-ID header from the sender, or null when the sender did not include one.
674
- */
675
- message_id: string | null;
676
- /**
677
- * Envelope-from address.
678
- */
679
- from: string;
680
- /**
681
- * Recipient addresses the message was sent to.
682
- */
683
- to: Array<string>;
684
- /**
685
- * Subject line as received, or null when the message had no subject.
686
- */
687
- subject: string | null;
688
- /**
689
- * In-Reply-To header — the Message-ID this message replies to, or null when it is not a reply.
690
- */
691
- in_reply_to?: string | null;
692
- /**
693
- * Whether SPF passed for the sender, or null when the result did not carry an SPF verdict.
694
- */
695
- spf_pass?: boolean | null;
696
- /**
697
- * Whether DKIM passed for the sender, or null when the result did not carry a DKIM verdict.
698
- */
699
- dkim_pass?: boolean | null;
700
- /**
701
- * Whether DMARC passed for the sender, or null when the result did not carry a DMARC verdict.
702
- */
703
- dmarc_pass?: boolean | null;
704
- /**
705
- * Spam score for the message. Always null at present; reserved for a future content-scoring capability.
706
- */
707
- spam_score?: number | null;
708
- };
709
- /**
710
- * Bird received and parsed an inbound email. The payload carries the message's identifiers, sender and recipients, subject, threading reference, and authentication results — enough to route and triage without a fetch. Fetch the body, full headers, and attachments with GET /v1/email/inbound-messages/{id}.
711
- */
712
- type EventEmailReceived = {
713
- /**
714
- * Event type.
715
- */
716
- type: "email.received";
717
- /**
718
- * When Bird received the message.
719
- */
720
- timestamp: string;
721
- data: EventEmailReceivedData;
722
- };
723
- /**
724
- * Payload of the email.processed event.
725
- */
726
- type EventEmailProcessedData = EventEmailBase;
727
- /**
728
- * Bird processed the message and queued it for delivery to the recipient's mail server. Fires once per recipient when the message enters the SMTP delivery queue.
729
- */
730
- type EventEmailProcessed = {
731
- /**
732
- * Event type.
733
- */
734
- type: "email.processed";
735
- /**
736
- * Time Bird processed the message and queued it for SMTP delivery.
737
- */
738
- timestamp: string;
739
- data: EventEmailProcessedData;
740
- };
741
- /**
742
- * Payload of the email.out_of_band_bounce event.
743
- */
744
- type EventEmailOutOfBandBounceData = EventEmailBase & {
745
- bounce_type: EmailBounceType;
746
- /**
747
- * Numeric bounce classification for fine-grained deliverability triage, or null when the receiving server's response could not be classified.
748
- *
749
- */
750
- bounce_class: number | null;
751
- /**
752
- * SMTP reply code returned by the receiving mail server, or null when none was provided.
753
- */
754
- bounce_code: string | null;
755
- /**
756
- * Human-readable reason the receiving mail server gave for the bounce, or null when none was provided.
757
- */
758
- bounce_description: string | null;
759
- /**
760
- * The IP address used to send this message, or null when it is not known.
761
- */
762
- sending_ip: string | null;
763
- };
764
- /**
765
- * Bounce classification. `hard` is a permanent failure (invalid address or non-existent domain). `soft` is a transient failure (mailbox full, server temporarily unavailable). `block` indicates the receiving mail server blocked the sending IP for reputation reasons. `admin` indicates an administrative refusal (relaying denied, blocklisted domain). `undetermined` is used when the receiving server's response is ambiguous.
766
- *
767
- */
768
- type EmailBounceType = "hard" | "soft" | "undetermined" | "admin" | "block";
769
- /**
770
- * A bounce notification arrived after the message had already been accepted for delivery. Fires once per recipient.
771
- */
772
- type EventEmailOutOfBandBounce = {
773
- /**
774
- * Event type.
775
- */
776
- type: "email.out_of_band_bounce";
777
- /**
778
- * Time the bounce notification was recorded.
779
- */
780
- timestamp: string;
781
- data: EventEmailOutOfBandBounceData;
782
- };
783
- /**
784
- * Payload of the email.opened event.
785
- */
786
- type EventEmailOpenedData = EventEmailBase & {
787
- /**
788
- * IP address of the client that opened the email, or null when it is not known.
789
- */
790
- ip_address: string | null;
791
- /**
792
- * User-agent string of the client that opened the email, or null when it is not known.
793
- */
794
- user_agent: string | null;
795
- };
796
- /**
797
- * The recipient opened the email (the tracking pixel was loaded). May fire more than once per recipient.
798
- */
799
- type EventEmailOpened = {
800
- /**
801
- * Event type.
802
- */
803
- type: "email.opened";
804
- /**
805
- * Time the open was recorded.
806
- */
807
- timestamp: string;
808
- data: EventEmailOpenedData;
809
- };
810
- /**
811
- * Payload of the email.list_unsubscribed event.
812
- */
813
- type EventEmailListUnsubscribedData = EventEmailBase;
814
- /**
815
- * Recipient unsubscribed via the RFC 8058 one-click List-Unsubscribe mechanism. Fires once per recipient.
816
- */
817
- type EventEmailListUnsubscribed = {
818
- /**
819
- * Event type.
820
- */
821
- type: "email.list_unsubscribed";
822
- /**
823
- * Time the unsubscribe was recorded.
824
- */
825
- timestamp: string;
826
- data: EventEmailListUnsubscribedData;
827
- };
828
- /**
829
- * Payload of the email.delivered event.
830
- */
831
- type EventEmailDeliveredData = EventEmailBase;
832
- /**
833
- * An outbound email reached the recipient's mail server and was accepted.
834
- */
835
- type EventEmailDelivered = {
836
- /**
837
- * Event type.
838
- */
839
- type: "email.delivered";
840
- /**
841
- * Time the recipient's mail server accepted the message.
842
- */
843
- timestamp: string;
844
- data: EventEmailDeliveredData;
845
- };
846
- /**
847
- * Payload of the email.deferred event.
848
- */
849
- type EventEmailDeferredData = EventEmailBase & {
850
- bounce_type: EmailBounceType;
851
- /**
852
- * Numeric bounce classification for fine-grained deliverability triage, or null when the receiving server's response could not be classified. Distinguishes, for example, a greylisting deferral from a full mailbox.
853
- *
854
- */
855
- bounce_class: number | null;
856
- /**
857
- * Human-readable reason the receiving mail server gave for the deferral, or null when none was provided.
858
- */
859
- defer_reason: string | null;
860
- /**
861
- * The IP address used to send this message, or null when it is not known.
862
- */
863
- sending_ip: string | null;
864
- };
865
- /**
866
- * The recipient's mail server temporarily refused the email; delivery will be retried. May fire more than once per recipient.
867
- */
868
- type EventEmailDeferred = {
869
- /**
870
- * Event type.
871
- */
872
- type: "email.deferred";
873
- /**
874
- * Time the deferral was recorded.
875
- */
876
- timestamp: string;
877
- data: EventEmailDeferredData;
878
- };
879
- /**
880
- * Payload of the email.complained event.
881
- */
882
- type EventEmailComplainedData = EventEmailBase & {
883
- /**
884
- * The kind of feedback the mailbox provider reported (such as `abuse` or `fraud`), or null when the provider did not specify one.
885
- */
886
- feedback_type: string | null;
887
- };
888
- /**
889
- * The recipient marked the email as spam through their mailbox provider's feedback loop. Fires once per recipient.
890
- */
891
- type EventEmailComplained = {
892
- /**
893
- * Event type.
894
- */
895
- type: "email.complained";
896
- /**
897
- * Time the complaint was recorded.
898
- */
899
- timestamp: string;
900
- data: EventEmailComplainedData;
901
- };
902
- /**
903
- * Payload of the email.clicked event.
904
- */
905
- type EventEmailClickedData = EventEmailBase & {
906
- /**
907
- * The URL the recipient clicked.
908
- */
909
- url: string;
910
- /**
911
- * IP address of the client that clicked the link, or null when it is not known.
912
- */
913
- ip_address: string | null;
914
- /**
915
- * User-agent string of the client that clicked the link, or null when it is not known.
916
- */
917
- user_agent: string | null;
918
- };
919
- /**
920
- * The recipient clicked a tracked link in the email. May fire more than once per recipient.
921
- */
922
- type EventEmailClicked = {
923
- /**
924
- * Event type.
925
- */
926
- type: "email.clicked";
927
- /**
928
- * Time the click was recorded.
929
- */
930
- timestamp: string;
931
- data: EventEmailClickedData;
932
- };
933
- /**
934
- * Payload of the email.canceled event.
935
- */
936
- type EventEmailCanceledData = EventEmailMessageBase;
937
- /**
938
- * A scheduled send was canceled before it fired. Fires once per message, not per recipient.
939
- */
940
- type EventEmailCanceled = {
941
- /**
942
- * Event type.
943
- */
944
- type: "email.canceled";
945
- /**
946
- * Time the scheduled send was canceled.
947
- */
948
- timestamp: string;
949
- data: EventEmailCanceledData;
950
- };
951
- /**
952
- * Payload of the email.bounced event.
953
- */
954
- type EventEmailBouncedData = EventEmailBase & {
955
- bounce_type: EmailBounceType;
956
- /**
957
- * Numeric bounce classification for fine-grained deliverability triage, or null when the receiving server's response could not be classified. Lets you distinguish, for example, a DNS failure from a spam block when both would be `bounce_type: soft` or `bounce_type: block`.
958
- *
959
- */
960
- bounce_class: number | null;
961
- /**
962
- * SMTP reply code returned by the receiving mail server, or null when none was provided.
963
- */
964
- bounce_code: string | null;
965
- /**
966
- * Human-readable reason the receiving mail server gave for the bounce, or null when none was provided.
967
- */
968
- bounce_description: string | null;
969
- /**
970
- * The IP address used to send this message, or null when it is not known.
971
- */
972
- sending_ip: string | null;
973
- };
974
- /**
975
- * An outbound email permanently failed at the recipient's mail server. Fires once per recipient.
976
- */
977
- type EventEmailBounced = {
978
- /**
979
- * Event type.
980
- */
981
- type: "email.bounced";
982
- /**
983
- * Time the bounce was recorded.
984
- */
985
- timestamp: string;
986
- data: EventEmailBouncedData;
987
- };
988
- /**
989
- * Payload of the email.accepted event.
990
- */
991
- type EventEmailAcceptedData = EventEmailBase;
992
- /**
993
- * Bird accepted the email send and is preparing to deliver. Fires once per requested recipient at acceptance time.
994
- */
995
- type EventEmailAccepted = {
996
- /**
997
- * Event type.
998
- */
999
- type: "email.accepted";
1000
- /**
1001
- * Time Bird accepted the send.
1002
- */
1003
- timestamp: string;
1004
- data: EventEmailAcceptedData;
1005
- };
1006
- /**
1007
- * A sending domain completed DNS verification successfully. Payload schema not yet finalized.
1008
- */
1009
- type EventDomainVerified = {
1010
- /**
1011
- * Event type.
1012
- */
1013
- type: "domain.verified";
1014
- /**
1015
- * When the event occurred.
1016
- */
1017
- timestamp: string;
1018
- /**
1019
- * Event payload. The fields for this event are not yet finalized.
1020
- */
1021
- data: {
1022
- [key: string]: never;
1023
- };
1024
- };
1025
- /**
1026
- * A sending domain failed DNS verification. Payload schema not yet finalized.
1027
- */
1028
- type EventDomainFailed = {
1029
- /**
1030
- * Event type.
1031
- */
1032
- type: "domain.failed";
1033
- /**
1034
- * When the event occurred.
1035
- */
1036
- timestamp: string;
1037
- /**
1038
- * Event payload. The fields for this event are not yet finalized.
1039
- */
1040
- data: {
1041
- [key: string]: never;
1042
- };
1043
- };
1044
- /**
1045
- * Discriminated union of every webhook event the Bird platform emits.
1046
- * Each variant is the full delivery body: `type` names the event, `timestamp` is when the event occurred, and `data` carries the event-specific payload. The `type` property selects the variant — SDKs that consume this schema (openapi-typescript, oapi-codegen) generate a narrowed union keyed on `type`, so customer code can switch on the event id and access the variant-specific payload fields without casting.
1047
- * Delivery metadata (the event id and per-attempt signature headers) rides in HTTP headers per Standard Webhooks and is handled by the SDK's webhook verification helper, which returns one of these variants.
1048
- *
1049
- */
1050
- type WebhookEvent = ({
1051
- type: "domain.failed";
1052
- } & EventDomainFailed) | ({
1053
- type: "domain.verified";
1054
- } & EventDomainVerified) | ({
1055
- type: "email.accepted";
1056
- } & EventEmailAccepted) | ({
1057
- type: "email.bounced";
1058
- } & EventEmailBounced) | ({
1059
- type: "email.canceled";
1060
- } & EventEmailCanceled) | ({
1061
- type: "email.clicked";
1062
- } & EventEmailClicked) | ({
1063
- type: "email.complained";
1064
- } & EventEmailComplained) | ({
1065
- type: "email.deferred";
1066
- } & EventEmailDeferred) | ({
1067
- type: "email.delivered";
1068
- } & EventEmailDelivered) | ({
1069
- type: "email.list_unsubscribed";
1070
- } & EventEmailListUnsubscribed) | ({
1071
- type: "email.opened";
1072
- } & EventEmailOpened) | ({
1073
- type: "email.out_of_band_bounce";
1074
- } & EventEmailOutOfBandBounce) | ({
1075
- type: "email.processed";
1076
- } & EventEmailProcessed) | ({
1077
- type: "email.received";
1078
- } & EventEmailReceived) | ({
1079
- type: "email.rejected";
1080
- } & EventEmailRejected) | ({
1081
- type: "email.scheduled";
1082
- } & EventEmailScheduled) | ({
1083
- type: "email.unsubscribed";
1084
- } & EventEmailUnsubscribed) | ({
1085
- type: "email_suppression.created";
1086
- } & EventEmailSuppressionCreated) | ({
1087
- type: "sms.accepted";
1088
- } & EventSmsAccepted) | ({
1089
- type: "sms.delivered";
1090
- } & EventSmsDelivered) | ({
1091
- type: "sms.expired";
1092
- } & EventSmsExpired) | ({
1093
- type: "sms.failed";
1094
- } & EventSmsFailed) | ({
1095
- type: "sms.rejected";
1096
- } & EventSmsRejected) | ({
1097
- type: "sms.sent";
1098
- } & EventSmsSent) | ({
1099
- type: "sms.undelivered";
1100
- } & EventSmsUndelivered);
1101
- type EmailMessageBatchResponse = {
1102
- /**
1103
- * One entry per message in the batch, in submission order.
1104
- */
1105
- data: Array<EmailMessageBatchItem>;
1106
- };
1107
- type EmailMessageBatchItem = {
1108
- /**
1109
- * Message ID assigned to this batch item.
1110
- */
1111
- readonly id: EmailId;
1112
- /**
1113
- * Initial status of this message in the batch.
1114
- */
1115
- readonly status: "accepted";
1116
- /**
1117
- * Resolved category for this batch item.
1118
- */
1119
- category: "marketing" | "transactional";
1120
- };
1121
- /**
1122
- * Batch of email message send requests. All items are validated before any are queued. Attachments are allowed on individual messages. Each message must stay within the 20 MB estimated generated message-size cap. The serialized JSON request body for the batch has a hard 20 MB cap.
1123
- *
1124
- */
1125
- type EmailMessageBatchRequest = Array<EmailMessageSendRequest>;
1126
- /**
1127
- * File attached to an email send. The attachment bytes are passed as base64-encoded `content` directly in the request body (required). The `path` field (provide a URL and Bird fetches the attachment for you) is a preview feature and currently unavailable. Requests are rejected with 422 if `content` is missing — `path` alone does not satisfy the schema. When `path` becomes generally available, the schema will be relaxed so that exactly one of `content` or `path` is required.
1128
- * Inline images for `<img src="cid:..."/>` references in the HTML body use the `content_id` field together with `content`.
1129
- * Bird enforces a **20 MB estimated generated message size** cap. The estimate is the HTML and text body plus all attachments and inline images measured after base64 encoding. This is not a raw file-size cap. As a rule of thumb, keep total raw attachment content at or below **15 MB** so the generated message has enough room after encoding and MIME wrapping.
1130
- * Recipient-side delivery reality: downstream limits vary by product and tenant/server policy. Gmail personal and Outlook.com document 25 MB attachment limits. Exchange Online defaults to 35 MB send / 36 MB receive, but admins can configure limits; on-prem Exchange Server organizational defaults are 10 MB. Sends close to Bird's 20 MB generated-message cap may be accepted by Bird but bounce at the recipient's mail server.
1131
- * Batch sends can include attachments on individual message objects. Each message still has the 20 MB estimated generated-size cap, and the serialized JSON request body for the whole batch has a hard 20 MB cap. Certain executable / script content types are rejected at validation time.
1132
- *
1133
- */
1134
- type EmailAttachment = {
1135
- /**
1136
- * Filename shown to the recipient. Required.
1137
- */
1138
- filename: string;
1139
- /**
1140
- * Base64-encoded attachment bytes. Required. Counts toward the 20 MB estimated generated message-size cap after encoding and MIME wrapping.
1141
- *
1142
- */
1143
- content: string;
1144
- /**
1145
- * Preview feature — provide a URL and Bird fetches the attachment for you. Currently unavailable. Use `content` instead. The schema currently requires `content`, so a request with only `path` is rejected with 422 for missing `content`; a request supplying both `content` and `path` is rejected with 422 `unsupported_feature` until this preview ships. When generally available: HTTPS-only, single redirect followed and re-validated, private IP ranges blocked, request timeout enforced, fetched content counts toward the 20 MB estimated generated message-size cap after encoding and MIME wrapping.
1146
- *
1147
- */
1148
- path?: string;
1149
- /**
1150
- * MIME type. Inferred from `filename` extension when omitted. Used to enforce the blocklist of disallowed executable / script types.
1151
- *
1152
- */
1153
- content_type?: string;
1154
- /**
1155
- * RFC 2392 Content-ID. When set, the attachment is rendered inline and can be referenced from the HTML body as `<img src="cid:{content_id}"/>`. When omitted, the attachment is rendered as a regular file attachment.
1156
- *
1157
- */
1158
- content_id?: string;
1159
- };
1160
- /**
1161
- * An email address with an optional display name.
1162
- */
1163
- type EmailAddress = {
1164
- /**
1165
- * Email address.
1166
- */
1167
- email: string;
1168
- /**
1169
- * Display name shown alongside the address in mail clients.
1170
- */
1171
- name?: string;
1172
- };
1173
- /**
1174
- * A sender or recipient address. Accepts a plain email string (`jane@example.com`), an RFC 5322 mailbox string with an embedded display name (`Jane Doe <jane@example.com>`), or an object carrying the address and an optional display name. All forms can be mixed freely within one request; responses always return the object form.
1175
- *
1176
- */
1177
- type EmailAddressInput = string | EmailAddress;
1178
- type EmailMessageSendRequest = {
1179
- /**
1180
- * Sender address, as a plain email string, an RFC 5322 mailbox string (`Jane <jane@example.com>`), or an object with an optional display name. Must be from a verified domain in this workspace.
1181
- */
1182
- from: EmailAddressInput;
1183
- /**
1184
- * Primary recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@example.com>`), or an object with an optional display name.
1185
- */
1186
- to: Array<EmailAddressInput>;
1187
- /**
1188
- * CC recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@example.com>`), or an object with an optional display name.
1189
- */
1190
- cc?: Array<EmailAddressInput>;
1191
- /**
1192
- * BCC recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@example.com>`), or an object with an optional display name.
1193
- */
1194
- bcc?: Array<EmailAddressInput>;
1195
- /**
1196
- * Message subject line.
1197
- */
1198
- subject: string;
1199
- /**
1200
- * HTML body. At least one of html or text must be provided.
1201
- */
1202
- html?: string;
1203
- /**
1204
- * Plain-text body. At least one of html or text must be provided.
1205
- */
1206
- text?: string;
1207
- /**
1208
- * Reply-To addresses, each a plain email string, an RFC 5322 mailbox string, or an object with an optional display name. RFC 5322 allows multiple. Every recipient reply hits all listed addresses, so 1-2 is typical; the 25 cap exists to prevent runaway header sizes that some MTAs reject.
1209
- *
1210
- */
1211
- reply_to?: Array<EmailAddressInput>;
1212
- /**
1213
- * Custom email headers as key-value pairs.
1214
- */
1215
- headers?: {
1216
- [key: string]: string;
1217
- };
1218
- /**
1219
- * Structured `{name, value}` labels for **filtering and analytics**. Tags become first-class query dimensions: filter the list endpoint by tag name, slice analytics rollups by tag, and surface in webhook payloads. Cap: 20 tags per send. Use tags for low-cardinality dimensions (`category`, `experiment_variant`, `template_id`). For arbitrary structured context that you do not need as a filter dimension, use `metadata` instead.
1220
- *
1221
- */
1222
- tags?: Array<EmailTag>;
1223
- /**
1224
- * Arbitrary JSON object **stored, returned on API reads, and echoed in webhook payloads**. Path-queryable in analytics (e.g. filter on `metadata.order_id`) but not surfaced as a first-class dashboard filter dimension. Cap: 2 KB serialized. Use metadata for per-send context like internal IDs, foreign keys, and structured payloads you want round-tripped through events. For low-cardinality filterable labels, use `tags` instead.
1225
- *
1226
- */
1227
- metadata?: {
1228
- [key: string]: unknown;
1229
- };
1230
- /**
1231
- * Whether to track open events for this message.
1232
- */
1233
- track_opens?: boolean;
1234
- /**
1235
- * Whether to track click events for this message.
1236
- */
1237
- track_clicks?: boolean;
1238
- /**
1239
- * ID of the IP pool to send from (`ipp_` prefix), or `ipp_shared` to route through the shared pool explicitly. Omit to use your organization's default pool. An unknown pool, or a pool with no dedicated IPs available to send from, is rejected with a `422`.
1240
- *
1241
- */
1242
- ip_pool_id?: string;
1243
- /**
1244
- * Content classification — independent of which endpoint you use. Controls suppression policy: `marketing` blocks on all suppression reasons (use for marketing content); `transactional` allows delivery through complaint and unsubscribe suppressions (use for receipts, password resets, and similar operational messages). Default: transactional.
1245
- *
1246
- */
1247
- category?: "marketing" | "transactional";
1248
- /**
1249
- * Preview feature — threaded replies. Currently unavailable; supplying this field returns `422 unsupported_feature`. When generally available, sets In-Reply-To and References headers automatically.
1250
- */
1251
- in_reply_to_message_id?: EmailId;
1252
- /**
1253
- * File attachments. Bird rejects sends whose estimated generated message size exceeds 20 MB. The estimate is the HTML and text body plus all attachments and inline images measured after base64 encoding. Keep total raw attachment content at or below 15 MB for reliable headroom. In batch sends, this per-message cap still applies and the serialized JSON request body for the whole batch has a hard 20 MB cap. See the EmailAttachment schema for the full field contract.
1254
- *
1255
- */
1256
- attachments?: Array<EmailAttachment>;
1257
- /**
1258
- * Preview feature — send-later scheduling. Currently unavailable; supplying this field returns `422 unsupported_feature`.
1259
- */
1260
- scheduled_at?: string;
1261
- /**
1262
- * Preview feature — contact-targeted sends. Currently unavailable; supplying this field returns `422 unsupported_feature`.
1263
- */
1264
- contact_id?: string;
1265
- /**
1266
- * Preview feature — topic-gated sends. Currently unavailable; supplying this field returns `422 unsupported_feature`. When generally available, a non-empty `topic_id` gates delivery on the recipient's opt-in state for that topic — if the recipient is opt_out, the send is silently suppressed and an `email.suppressed` event fires with `reason: topic_opt_out`.
1267
- *
1268
- */
1269
- topic_id?: string;
1270
- };
1271
- type EmailAttachmentId = string;
1272
- /**
1273
- * Attachment metadata returned on API reads. The original content is not echoed back inline — only the metadata needed for display and audit. To download the raw attachment bytes (while content storage is enabled and within the retention window), use `GET /v1/email/messages/{message_id}/attachments/{attachment_id}`, which returns the file with its own content type and a Content-Disposition filename.
1274
- *
1275
- */
1276
- type EmailAttachmentRef = {
1277
- /**
1278
- * Attachment ID, stable per email send.
1279
- */
1280
- readonly id?: EmailAttachmentId;
1281
- /**
1282
- * Filename as shown to the recipient.
1283
- */
1284
- filename: string;
1285
- /**
1286
- * Resolved MIME type at send time.
1287
- */
1288
- content_type?: string;
1289
- /**
1290
- * Decoded size in bytes.
1291
- */
1292
- size: number;
1293
- /**
1294
- * True when the attachment was sent inline via a `content_id` reference in the HTML body, false for regular file attachments.
1295
- *
1296
- */
1297
- inline?: boolean;
1298
- /**
1299
- * The Content-ID set at send time, when the attachment was inline.
1300
- */
1301
- content_id?: string | null;
1302
- };
1303
- type EmailMessage = {
1304
- /**
1305
- * Message ID.
1306
- */
1307
- readonly id: EmailId;
1308
- /**
1309
- * Sender address. `name` is present when a display name was provided on the send.
1310
- */
1311
- from: EmailAddress;
1312
- /**
1313
- * Primary recipients. Length is the recipient count; use the broadcasts endpoint for audience-targeted sends. Each entry's `name` is present when a display name was provided on the send.
1314
- */
1315
- to: Array<EmailAddress>;
1316
- /**
1317
- * CC recipients.
1318
- */
1319
- cc?: Array<EmailAddress>;
1320
- /**
1321
- * BCC recipients.
1322
- */
1323
- bcc?: Array<EmailAddress>;
1324
- /**
1325
- * Message subject line.
1326
- */
1327
- subject: string;
1328
- /**
1329
- * Content classification. Controls suppression policy — `marketing` blocks on all suppression reasons; `transactional` allows delivery through complaint and unsubscribe suppressions.
1330
- *
1331
- */
1332
- category: "marketing" | "transactional";
1333
- /**
1334
- * Reply-To addresses, if set on the send. Empty/null when no Reply-To was provided.
1335
- */
1336
- reply_to?: Array<EmailAddress> | null;
1337
- /**
1338
- * Aggregate delivery status derived from recipient states. `scheduled` means the message is queued to send at a future time and has not been dispatched yet. `accepted` means Bird has the send and is preparing to deliver. `processed` means Bird has processed the message and queued it for delivery to the recipient's mail server. `canceled` means a scheduled message was canceled before it was sent.
1339
- *
1340
- */
1341
- readonly status: "scheduled" | "accepted" | "processed" | "deferred" | "delivered" | "partial_failure" | "bounced" | "complained" | "rejected" | "canceled";
1342
- /**
1343
- * Number of recipients currently in the `accepted` state — Bird has the send and is preparing to deliver.
1344
- */
1345
- readonly accepted_count: number;
1346
- /**
1347
- * Number of recipients for whom Bird has processed the message and queued it for delivery.
1348
- */
1349
- readonly processed_count: number;
1350
- /**
1351
- * Number of recipients whose messages were accepted by the remote MTA.
1352
- */
1353
- readonly delivered_count: number;
1354
- /**
1355
- * Number of recipients that resulted in a permanent delivery failure.
1356
- */
1357
- readonly bounced_count: number;
1358
- /**
1359
- * Number of recipients that reported spam.
1360
- */
1361
- readonly complained_count: number;
1362
- /**
1363
- * Number of recipients in transient delivery deferral; the provider is retrying.
1364
- */
1365
- readonly deferred_count: number;
1366
- /**
1367
- * Number of recipients rejected before delivery. See the per-recipient `rejection_reason` field on `GET /v1/email/messages/{message_id}/recipients` for the specific cause (suppression match, transmission failure, generation failure, or policy refusal).
1368
- *
1369
- */
1370
- readonly rejected_count: number;
1371
- /**
1372
- * Time between Bird accepting the send and the message being processed for delivery, in milliseconds, for the fastest recipient. Null until the first recipient reaches `processed`.
1373
- *
1374
- */
1375
- readonly processing_latency_ms?: number | null;
1376
- /**
1377
- * Time between the message being processed and the receiving mail server accepting it, in milliseconds, for the fastest delivered recipient. Null until the first recipient is delivered.
1378
- *
1379
- */
1380
- readonly delivery_latency_ms?: number | null;
1381
- /**
1382
- * End-to-end accept → delivered time for the fastest delivered recipient, in milliseconds. Null until the first recipient is delivered.
1383
- *
1384
- */
1385
- readonly total_latency_ms?: number | null;
1386
- /**
1387
- * Total open events across all recipients.
1388
- */
1389
- readonly open_count: number;
1390
- /**
1391
- * Total click events across all recipients.
1392
- */
1393
- readonly click_count: number;
1394
- /**
1395
- * Structured `{name, value}` filter labels applied to this send. See EmailMessageSendRequest for the tags vs metadata distinction.
1396
- */
1397
- tags?: Array<EmailTag>;
1398
- /**
1399
- * Arbitrary JSON metadata stored on the message object and echoed in webhook payloads. See EmailMessageSendRequest for the tags vs metadata distinction.
1400
- */
1401
- metadata?: {
1402
- [key: string]: unknown;
1403
- };
1404
- /**
1405
- * Attachment metadata for the send. Empty when no attachments were included. Raw content is not echoed; use the future content-retrieval endpoint when storage is enabled.
1406
- */
1407
- attachments?: Array<EmailAttachmentRef>;
1408
- /**
1409
- * Whether open tracking is enabled for this send.
1410
- */
1411
- track_opens: boolean;
1412
- /**
1413
- * Whether click tracking is enabled for this send.
1414
- */
1415
- track_clicks: boolean;
1416
- /**
1417
- * When the send request was accepted.
1418
- */
1419
- readonly created_at: string;
1420
- /**
1421
- * Thread this message belongs to. Null until threading is enabled.
1422
- */
1423
- readonly thread_id?: string | null;
1424
- /**
1425
- * The message this one is a reply to, if any.
1426
- */
1427
- readonly in_reply_to_message_id?: EmailId | null;
1428
- /**
1429
- * When all recipients reached a terminal delivered state, or null if not yet fully delivered.
1430
- */
1431
- readonly delivered_at?: string | null;
1432
- /**
1433
- * When this message is scheduled to send, for a send created with a future send time. Null for an immediate send. Stays set after the scheduled send fires.
1434
- */
1435
- readonly scheduled_at?: string | null;
1436
- };
1437
- type ListEmailMessagesData = {
1438
- body?: never;
1439
- path?: never;
1440
- query?: {
1441
- /**
1442
- * Maximum number of items to return per page.
1443
- */
1444
- limit?: number;
1445
- /**
1446
- * Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
1447
- */
1448
- starting_after?: string;
1449
- /**
1450
- * Cursor from the `prev_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order.
1451
- */
1452
- ending_before?: string;
1453
- /**
1454
- * Return only resources created strictly after this timestamp. RFC 3339 / ISO 8601 with timezone.
1455
- */
1456
- created_after?: string;
1457
- /**
1458
- * Return only resources created strictly before this timestamp. RFC 3339 / ISO 8601 with timezone.
1459
- */
1460
- created_before?: string;
1461
- /**
1462
- * Filter by aggregate delivery status.
1463
- */
1464
- status?: "scheduled" | "accepted" | "processed" | "deferred" | "delivered" | "partial_failure" | "bounced" | "complained" | "rejected" | "canceled";
1465
- /**
1466
- * Filter by tag. Accepts `name` to match any send carrying that tag name, or `name:value` to match a specific tag pair (e.g. `category:welcome`). For filtering on arbitrary `metadata` fields, use the metadata path-filter parameters instead.
1467
- *
1468
- */
1469
- tag?: string;
1470
- /**
1471
- * Filter by category.
1472
- */
1473
- category?: "marketing" | "transactional";
1474
- /**
1475
- * Filter by recipient address. Exact match against any `to`/`cc`/`bcc` recipient on the message; normalised to lowercase before comparison.
1476
- *
1477
- */
1478
- to?: string;
1479
- /**
1480
- * Filter by sender address. Exact match against the message `from` field; normalised to lowercase before comparison.
1481
- *
1482
- */
1483
- from?: string;
1484
- };
1485
- url: "/v1/email/messages";
1486
- };
1487
-
1488
- type AuthToken = string | undefined;
1489
- interface Auth {
1490
- /**
1491
- * Which part of the request do we use to send the auth?
1492
- *
1493
- * @default 'header'
1494
- */
1495
- in?: "header" | "query" | "cookie";
1496
- /**
1497
- * Header or query parameter name.
1498
- *
1499
- * @default 'Authorization'
1500
- */
1501
- name?: string;
1502
- scheme?: "basic" | "bearer";
1503
- type: "apiKey" | "http";
1504
- }
1505
-
1506
- interface SerializerOptions<T> {
1507
- /**
1508
- * @default true
1509
- */
1510
- explode: boolean;
1511
- style: T;
1512
- }
1513
- type ArrayStyle = "form" | "spaceDelimited" | "pipeDelimited";
1514
- type ObjectStyle = "form" | "deepObject";
1515
-
1516
- type QuerySerializer = (query: Record<string, unknown>) => string;
1517
- type BodySerializer = (body: unknown) => unknown;
1518
- type QuerySerializerOptionsObject = {
1519
- allowReserved?: boolean;
1520
- array?: Partial<SerializerOptions<ArrayStyle>>;
1521
- object?: Partial<SerializerOptions<ObjectStyle>>;
1522
- };
1523
- type QuerySerializerOptions = QuerySerializerOptionsObject & {
1524
- /**
1525
- * Per-parameter serialization overrides. When provided, these settings
1526
- * override the global array/object settings for specific parameter names.
1527
- */
1528
- parameters?: Record<string, QuerySerializerOptionsObject>;
1529
- };
1530
-
1531
- type HttpMethod = "connect" | "delete" | "get" | "head" | "options" | "patch" | "post" | "put" | "trace";
1532
- type Client$1<RequestFn = never, Config = unknown, MethodFn = never, BuildUrlFn = never, SseFn = never> = {
1533
- /**
1534
- * Returns the final request URL.
1535
- */
1536
- buildUrl: BuildUrlFn;
1537
- getConfig: () => Config;
1538
- request: RequestFn;
1539
- setConfig: (config: Config) => Config;
1540
- } & {
1541
- [K in HttpMethod]: MethodFn;
1542
- } & ([SseFn] extends [never] ? {
1543
- sse?: never;
1544
- } : {
1545
- sse: {
1546
- [K in HttpMethod]: SseFn;
1547
- };
1548
- });
1549
- interface Config$1 {
1550
- /**
1551
- * Auth token or a function returning auth token. The resolved value will be
1552
- * added to the request payload as defined by its `security` array.
1553
- */
1554
- auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
1555
- /**
1556
- * A function for serializing request body parameter. By default,
1557
- * {@link JSON.stringify()} will be used.
1558
- */
1559
- bodySerializer?: BodySerializer | null;
1560
- /**
1561
- * An object containing any HTTP headers that you want to pre-populate your
1562
- * `Headers` object with.
1563
- *
1564
- * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
1565
- */
1566
- headers?: RequestInit["headers"] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>;
1567
- /**
1568
- * The request method.
1569
- *
1570
- * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
1571
- */
1572
- method?: Uppercase<HttpMethod>;
1573
- /**
1574
- * A function for serializing request query parameters. By default, arrays
1575
- * will be exploded in form style, objects will be exploded in deepObject
1576
- * style, and reserved characters are percent-encoded.
1577
- *
1578
- * This method will have no effect if the native `paramsSerializer()` Axios
1579
- * API function is used.
1580
- *
1581
- * {@link https://swagger.io/docs/specification/serialization/#query View examples}
1582
- */
1583
- querySerializer?: QuerySerializer | QuerySerializerOptions;
1584
- /**
1585
- * A function validating request data. This is useful if you want to ensure
1586
- * the request conforms to the desired shape, so it can be safely sent to
1587
- * the server.
1588
- */
1589
- requestValidator?: (data: unknown) => Promise<unknown>;
1590
- /**
1591
- * A function transforming response data before it's returned. This is useful
1592
- * for post-processing data, e.g., converting ISO strings into Date objects.
1593
- */
1594
- responseTransformer?: (data: unknown) => Promise<unknown>;
1595
- /**
1596
- * A function validating response data. This is useful if you want to ensure
1597
- * the response conforms to the desired shape, so it can be safely passed to
1598
- * the transformers and returned to the user.
1599
- */
1600
- responseValidator?: (data: unknown) => Promise<unknown>;
1601
- }
1602
-
1603
- type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, "method"> & Pick<Config$1, "method" | "responseTransformer" | "responseValidator"> & {
1604
- /**
1605
- * Fetch API implementation. You can use this option to provide a custom
1606
- * fetch instance.
1607
- *
1608
- * @default globalThis.fetch
1609
- */
1610
- fetch?: typeof fetch;
1611
- /**
1612
- * Implementing clients can call request interceptors inside this hook.
1613
- */
1614
- onRequest?: (url: string, init: RequestInit) => Promise<Request>;
1615
- /**
1616
- * Callback invoked when a network or parsing error occurs during streaming.
1617
- *
1618
- * This option applies only if the endpoint returns a stream of events.
1619
- *
1620
- * @param error The error that occurred.
1621
- */
1622
- onSseError?: (error: unknown) => void;
1623
- /**
1624
- * Callback invoked when an event is streamed from the server.
1625
- *
1626
- * This option applies only if the endpoint returns a stream of events.
1627
- *
1628
- * @param event Event streamed from the server.
1629
- * @returns Nothing (void).
1630
- */
1631
- onSseEvent?: (event: StreamEvent<TData>) => void;
1632
- serializedBody?: RequestInit["body"];
1633
- /**
1634
- * Default retry delay in milliseconds.
1635
- *
1636
- * This option applies only if the endpoint returns a stream of events.
1637
- *
1638
- * @default 3000
1639
- */
1640
- sseDefaultRetryDelay?: number;
1641
- /**
1642
- * Maximum number of retry attempts before giving up.
1643
- */
1644
- sseMaxRetryAttempts?: number;
1645
- /**
1646
- * Maximum retry delay in milliseconds.
1647
- *
1648
- * Applies only when exponential backoff is used.
1649
- *
1650
- * This option applies only if the endpoint returns a stream of events.
1651
- *
1652
- * @default 30000
1653
- */
1654
- sseMaxRetryDelay?: number;
1655
- /**
1656
- * Optional sleep function for retry backoff.
1657
- *
1658
- * Defaults to using `setTimeout`.
1659
- */
1660
- sseSleepFn?: (ms: number) => Promise<void>;
1661
- url: string;
1662
- };
1663
- interface StreamEvent<TData = unknown> {
1664
- data: TData;
1665
- event?: string;
1666
- id?: string;
1667
- retry?: number;
1668
- }
1669
- type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = {
1670
- stream: AsyncGenerator<TData extends Record<string, unknown> ? TData[keyof TData] : TData, TReturn, TNext>;
1671
- };
1672
-
1673
- type ErrInterceptor<Err, Res, Req, Options> = (error: Err,
1674
- /** response may be undefined due to a network error where no response object is produced */
1675
- response: Res | undefined,
1676
- /** request may be undefined, because error may be from building the request object itself */
1677
- request: Req | undefined, options: Options) => Err | Promise<Err>;
1678
- type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;
1679
- type ResInterceptor<Res, Req, Options> = (response: Res, request: Req, options: Options) => Res | Promise<Res>;
1680
- declare class Interceptors<Interceptor> {
1681
- fns: Array<Interceptor | null>;
1682
- clear(): void;
1683
- eject(id: number | Interceptor): void;
1684
- exists(id: number | Interceptor): boolean;
1685
- getInterceptorIndex(id: number | Interceptor): number;
1686
- update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false;
1687
- use(fn: Interceptor): number;
1688
- }
1689
- interface Middleware<Req, Res, Err, Options> {
1690
- error: Interceptors<ErrInterceptor<Err, Res, Req, Options>>;
1691
- request: Interceptors<ReqInterceptor<Req, Options>>;
1692
- response: Interceptors<ResInterceptor<Res, Req, Options>>;
1693
- }
1694
-
1695
- type ResponseStyle = "data" | "fields";
1696
- interface Config<T extends ClientOptions = ClientOptions> extends Omit<RequestInit, "body" | "headers" | "method">, Config$1 {
1697
- /**
1698
- * Base URL for all requests made by this client.
1699
- */
1700
- baseUrl?: T["baseUrl"];
1701
- /**
1702
- * Fetch API implementation. You can use this option to provide a custom
1703
- * fetch instance.
1704
- *
1705
- * @default globalThis.fetch
1706
- */
1707
- fetch?: typeof fetch;
1708
- /**
1709
- * Please don't use the Fetch client for Next.js applications. The `next`
1710
- * options won't have any effect.
1711
- *
1712
- * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
1713
- */
1714
- next?: never;
1715
- /**
1716
- * Return the response data parsed in a specified format. By default, `auto`
1717
- * will infer the appropriate method from the `Content-Type` response header.
1718
- * You can override this behavior with any of the {@link Body} methods.
1719
- * Select `stream` if you don't want to parse response data at all.
1720
- *
1721
- * @default 'auto'
1722
- */
1723
- parseAs?: "arrayBuffer" | "auto" | "blob" | "formData" | "json" | "stream" | "text";
1724
- /**
1725
- * Should we return only data or multiple fields (data, error, response, etc.)?
1726
- *
1727
- * @default 'fields'
1728
- */
1729
- responseStyle?: ResponseStyle;
1730
- /**
1731
- * Throw an error instead of returning it in the response?
1732
- *
1733
- * @default false
1734
- */
1735
- throwOnError?: T["throwOnError"];
1736
- }
1737
- interface RequestOptions<TData = unknown, TResponseStyle extends ResponseStyle = "fields", ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{
1738
- responseStyle: TResponseStyle;
1739
- throwOnError: ThrowOnError;
1740
- }>, Pick<ServerSentEventsOptions<TData>, "onRequest" | "onSseError" | "onSseEvent" | "sseDefaultRetryDelay" | "sseMaxRetryAttempts" | "sseMaxRetryDelay"> {
1741
- /**
1742
- * Any body that you want to add to your request.
1743
- *
1744
- * {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
1745
- */
1746
- body?: unknown;
1747
- path?: Record<string, unknown>;
1748
- query?: Record<string, unknown>;
1749
- /**
1750
- * Security mechanism(s) to use for the request.
1751
- */
1752
- security?: ReadonlyArray<Auth>;
1753
- url: Url;
1754
- }
1755
- interface ResolvedRequestOptions<TResponseStyle extends ResponseStyle = "fields", ThrowOnError extends boolean = boolean, Url extends string = string> extends RequestOptions<unknown, TResponseStyle, ThrowOnError, Url> {
1756
- headers: Headers;
1757
- serializedBody?: string;
1758
- }
1759
- type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = "fields"> = ThrowOnError extends true ? Promise<TResponseStyle extends "data" ? TData extends Record<string, unknown> ? TData[keyof TData] : TData : {
1760
- data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
1761
- request: Request;
1762
- response: Response;
1763
- }> : Promise<TResponseStyle extends "data" ? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined : ({
1764
- data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
1765
- error: undefined;
1766
- } | {
1767
- data: undefined;
1768
- error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
1769
- }) & {
1770
- /** request may be undefined, because error may be from building the request object itself */
1771
- request?: Request;
1772
- /** response may be undefined, because error may be from building the request object itself or from a network error */
1773
- response?: Response;
1774
- }>;
1775
- interface ClientOptions {
1776
- baseUrl?: string;
1777
- responseStyle?: ResponseStyle;
1778
- throwOnError?: boolean;
1779
- }
1780
- type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = "fields">(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, "method">) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
1781
- type SseFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = "fields">(options: Omit<RequestOptions<never, TResponseStyle, ThrowOnError>, "method">) => Promise<ServerSentEventsResult<TData, TError>>;
1782
- type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = "fields">(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, "method"> & Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, "method">) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
1783
- type BuildUrlFn = <TData extends {
1784
- body?: unknown;
1785
- path?: Record<string, unknown>;
1786
- query?: Record<string, unknown>;
1787
- url: string;
1788
- }>(options: TData & Options<TData>) => string;
1789
- type Client = Client$1<RequestFn, Config, MethodFn, BuildUrlFn, SseFn> & {
1790
- interceptors: Middleware<Request, Response, unknown, ResolvedRequestOptions>;
1791
- };
1792
- interface TDataShape {
1793
- body?: unknown;
1794
- headers?: unknown;
1795
- path?: unknown;
1796
- query?: unknown;
1797
- url: string;
1798
- }
1799
- type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
1800
- type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, TResponseStyle extends ResponseStyle = "fields"> = OmitKeys<RequestOptions<TResponse, TResponseStyle, ThrowOnError>, "body" | "path" | "query" | "url"> & ([TData] extends [never] ? unknown : Omit<TData, "url">);
1801
-
1802
- /** Resolved per-attempt inputs handed to the hey-api SDK call. */
1803
- interface CallContext {
1804
- signal: AbortSignal;
1805
- /** Merged headers: caller `headers` plus the resolved `Idempotency-Key`. */
1806
- headers: Record<string, string>;
1807
- }
1808
- declare abstract class Resource {
1809
- protected readonly core: BirdHTTPClient;
1810
- protected readonly client: Client;
1811
- constructor(core: BirdHTTPClient, client: Client);
1812
- /** Run a single typed call through the lifecycle. */
1813
- protected call<T>(method: string, options: RequestOptions$1 | undefined, invoke: (ctx: CallContext) => Promise<FetchOutcome<T>>): APIPromise<T>;
1814
- /** Run a cursor-paginated list through the lifecycle (each page retried independently). */
1815
- protected paginated<T>(method: string, options: RequestOptions$1 | undefined, invoke: (ctx: CallContext, cursor: string | undefined) => Promise<FetchOutcome<CursorPage<T>>>): PaginatedPromise<T>;
1816
- }
1817
-
1818
- /** Body for `bird.email.send`. */
1819
- type EmailSendParams = EmailMessageSendRequest;
1820
- /** Body for `bird.email.sendBatch` — an array of send params, validated as a unit. */
1821
- type EmailSendBatchParams = EmailMessageBatchRequest;
1822
- /** Result of `bird.email.sendBatch` — one accepted item per submitted message. */
1823
- type EmailSendBatchResult = EmailMessageBatchResponse;
1824
- /** Filters and cursor params for `bird.email.list`. */
1825
- type EmailListQuery = NonNullable<ListEmailMessagesData["query"]>;
1826
- /**
1827
- * Channel-level defaults set at client construction. Field names mirror the
1828
- * send params (so they read as pre-filled fields). Any field set here becomes
1829
- * optional in `send` and is filled when omitted (per-send value wins).
1830
- */
1831
- type EmailChannelDefaults = Partial<Pick<EmailSendParams, "from" | "reply_to" | "category" | "track_opens" | "track_clicks" | "headers" | "tags" | "metadata">>;
1832
- type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
1833
- /** Keys that carry a configured default — made optional in `send`. */
1834
- type DefaultedKeys<D> = D extends object ? Extract<keyof D, keyof EmailSendParams> : never;
1835
- /** `send` params with defaulted fields made optional. */
1836
- type EmailSend<D> = PartialBy<EmailSendParams, DefaultedKeys<D>>;
1837
- declare class EmailResource<D extends EmailChannelDefaults | undefined = undefined> extends Resource {
1838
- #private;
1839
- constructor(core: ConstructorParameters<typeof Resource>[0], client: ConstructorParameters<typeof Resource>[1], defaults?: D);
1840
- /**
1841
- * Send an email message. Resolves once the message is accepted for delivery
1842
- * (the API's 202). Throws on failure — a 422 (unverified sender, all
1843
- * recipients suppressed, validation) is a `BirdValidationError`. Fields set as
1844
- * channel defaults may be omitted (per-send value wins).
1845
- *
1846
- * @example Send a message
1847
- * const msg = await bird.email.send({
1848
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
1849
- * to: ["delivered@messagebird.dev"],
1850
- * subject: "Hello from Bird",
1851
- * html: "<p>My first Bird email.</p>",
1852
- * });
1853
- * console.log(msg.id, msg.status); // "em_…", "accepted"
1854
- *
1855
- * @example A richer send — cc/bcc, reply-to, tags, metadata, click-tracking off, and an idempotency key (safe to retry; the server dedupes)
1856
- * await bird.email.send(
1857
- * {
1858
- * from: "hello@acme.com",
1859
- * to: ["a@example.com", "b@example.com"],
1860
- * cc: ["manager@example.com"],
1861
- * reply_to: ["support@acme.com"],
1862
- * subject: "Your March invoice",
1863
- * html: "<p>Attached.</p>",
1864
- * tags: [{ name: "category", value: "billing" }],
1865
- * metadata: { invoice_id: "inv_123" },
1866
- * track_clicks: false,
1867
- * },
1868
- * { idempotencyKey: "invoice-march/cust_1" },
1869
- * );
1870
- *
1871
- * @example Branch on the typed error hierarchy
1872
- * import { BirdRateLimitError, BirdValidationError, BirdAPIError } from "@messagebird/sdk";
1873
- *
1874
- * try {
1875
- * await bird.email.send({
1876
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
1877
- * to: ["delivered@messagebird.dev"],
1878
- * subject: "Hello from Bird",
1879
- * html: "<p>My first Bird email.</p>",
1880
- * });
1881
- * } catch (err) {
1882
- * if (err instanceof BirdRateLimitError) console.log(`rate limited — retry in ${err.retryAfter}s`);
1883
- * else if (err instanceof BirdValidationError) console.error(err.details);
1884
- * else if (err instanceof BirdAPIError) console.error(err.code, err.requestId);
1885
- * else throw err;
1886
- * }
1887
- *
1888
- * @example Errors as values with `.safe()`
1889
- * const { data, error } = await bird.email
1890
- * .send({
1891
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
1892
- * to: ["delivered@messagebird.dev"],
1893
- * subject: "Hello from Bird",
1894
- * html: "<p>My first Bird email.</p>",
1895
- * })
1896
- * .safe();
1897
- * if (error) console.error(error.message);
1898
- * else console.log(data.id);
1899
- */
1900
- send(params: EmailSend<D>, options?: RequestOptions$1): APIPromise<EmailMessage>;
1901
- /**
1902
- * Send a batch of up to 100 independent email messages in one request. The
1903
- * batch is validated as a unit — if any item fails validation (unverified
1904
- * sender, all recipients suppressed, field-level errors) the whole batch is
1905
- * rejected with a `BirdValidationError` and nothing is queued. Resolves with
1906
- * one accepted item per submitted message, in submission order, once the batch
1907
- * is accepted (the API's 202). Channel defaults are applied per item.
1908
- *
1909
- * @example Send a batch of messages
1910
- * const batch = await bird.email.sendBatch([
1911
- * {
1912
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
1913
- * to: ["alice@example.com"],
1914
- * subject: "Your receipt",
1915
- * html: "<p>Thanks, Alice.</p>",
1916
- * },
1917
- * {
1918
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
1919
- * to: ["bob@example.com"],
1920
- * subject: "Your receipt",
1921
- * html: "<p>Thanks, Bob.</p>",
1922
- * },
1923
- * ]);
1924
- * for (const item of batch.data) console.log(item.id, item.status);
1925
- */
1926
- sendBatch(params: EmailSendBatchParams, options?: RequestOptions$1): APIPromise<EmailSendBatchResult>;
1927
- /**
1928
- * Fetch a message with aggregate delivery status.
1929
- *
1930
- * @example
1931
- * const msg = await bird.email.get("em_abc123");
1932
- * msg.status; // "accepted" | "processed" | "delivered" | "bounced" | …
1933
- * msg.delivered_count;
1934
- * msg.bounced_count;
1935
- */
1936
- get(messageId: string, options?: RequestOptions$1): APIPromise<EmailMessage>;
1937
- /**
1938
- * List messages, newest first. `await` resolves the first page; `for await`
1939
- * walks every message across all pages.
1940
- *
1941
- * @example Iterate every message, or take one page
1942
- * for await (const message of bird.email.list({ status: "bounced" })) {
1943
- * console.log(message.id);
1944
- * }
1945
- * const page = await bird.email.list({ limit: 50 }); // page.data, page.next_cursor
1946
- */
1947
- list(query?: EmailListQuery, options?: RequestOptions$1): PaginatedPromise<EmailMessage>;
1948
- }
1949
-
1950
- /** A verified webhook event — discriminated on `type` (ADR-0028 wire contract). */
1951
- type BirdWebhookEvent = WebhookEvent;
1952
- /** Inbound request headers, as a `Headers` object or a plain record. */
1953
- type WebhookHeaders = Headers | Record<string, string>;
1954
- /** Client-level webhooks config (`new BirdClient({ webhooks: { secret } })`). */
1955
- interface WebhookOptions {
1956
- /** Signing secret used by `unwrap`; a per-call `secret` overrides it. */
1957
- secret?: string;
1958
- }
1959
- declare class WebhooksResource {
1960
- #private;
1961
- constructor(config?: WebhookOptions);
1962
- /**
1963
- * Verify a webhook delivery and return the typed event.
1964
- *
1965
- * **Pass the raw request body**, exactly as received — do NOT parse it first.
1966
- * The Standard Webhooks signature is computed over the raw bytes, so parsing
1967
- * and re-serializing before verifying is the classic webhook bug.
1968
- *
1969
- * The secret comes from `webhooks.secret` on the client; pass `{ secret }` to
1970
- * override per call. Throws {@link BirdWebhookVerificationError} on a bad
1971
- * signature, a stale timestamp, or missing/malformed headers. Unknown event
1972
- * types are returned as-is (handle them in a `default` case) so a newer server
1973
- * event can't break an older SDK.
1974
- *
1975
- * @example One call verifies the signature and returns the typed event
1976
- * // Pass the RAW request body; set the secret via new BirdClient({ webhooks: { secret } }).
1977
- * const event = bird.webhooks.unwrap(rawBody, headers);
1978
- * console.log(event.type); // discriminated union — narrow on event.type
1979
- *
1980
- * @example Verify and dispatch — pass the raw request body, never the parsed JSON
1981
- * // new BirdClient({ apiKey, webhooks: { secret } })
1982
- * try {
1983
- * const event = bird.webhooks.unwrap(rawBody, req.headers);
1984
- * switch (event.type) {
1985
- * case "email.delivered":
1986
- * markDelivered(event.email_id, event.recipient); // narrowed; fields are flat
1987
- * break;
1988
- * case "email.bounced":
1989
- * case "email.complained":
1990
- * suppress(event.recipient);
1991
- * break;
1992
- * default: // unknown future event types — an older SDK won't break on a new one
1993
- * }
1994
- * } catch (err) {
1995
- * if (err instanceof BirdWebhookVerificationError) {
1996
- * // reject with 400 — bad signature, stale timestamp, or missing/malformed headers
1997
- * } else throw err;
1998
- * }
1999
- */
2000
- unwrap(payload: string, headers: WebhookHeaders, options?: WebhookOptions): BirdWebhookEvent;
2001
- }
2002
-
2003
- interface BirdClientOptions {
2004
- apiKey: string;
2005
- /** Explicit base URL; overrides region resolution. For local/self-hosted use. */
2006
- baseUrl?: string;
2007
- /** Region override (e.g. `"eu1"`); the API key prefix is used by default. */
2008
- region?: string;
2009
- /** Per-attempt timeout in ms. Default 60_000. */
2010
- timeout?: number;
2011
- /** Max retry attempts on retryable failures (429, 5xx, network). Default 2. */
2012
- maxRetries?: number;
2013
- /** Custom fetch — testing, proxying, edge-runtime adapters. Default global fetch. */
2014
- fetch?: typeof fetch;
2015
- /** Headers added to every request. SDK-internal headers win on conflict. */
2016
- defaultHeaders?: Record<string, string>;
2017
- /**
2018
- * Email channel defaults. Any field set here may be omitted in
2019
- * `bird.email.send` (the type enforces this); the per-send value wins.
2020
- */
2021
- email?: EmailChannelDefaults;
2022
- /** Webhooks config — `secret` is the default used by `bird.webhooks.unwrap`. */
2023
- webhooks?: WebhookOptions;
2024
- }
2025
- /** A raw request for the `bird.request` escape hatch. */
2026
- interface BirdRequest {
2027
- method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
2028
- /**
2029
- * Absolute path on the API host, e.g. `/v1/email/domains`; must start
2030
- * with a single `/`.
2031
- */
2032
- path: string;
2033
- query?: Record<string, string | number | boolean | undefined>;
2034
- /** JSON request body. */
2035
- body?: unknown;
2036
- headers?: Record<string, string>;
2037
- }
2038
- type EmailDefaultsOf<O> = O extends {
2039
- email: infer E extends EmailChannelDefaults;
2040
- } ? E : undefined;
2041
- /**
2042
- * The Bird API client. Construct it with an API key; the region is taken from
2043
- * the key's prefix (`bk_{region}_…`) — pass `baseUrl` or `region` to override.
2044
- *
2045
- * @example Construct and send
2046
- * const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });
2047
- * const msg = await bird.email.send({
2048
- * from: "hello@acme.com",
2049
- * to: ["customer@example.com"],
2050
- * subject: "Welcome aboard",
2051
- * html: "<h1>Hi there 👋</h1>",
2052
- * });
2053
- * console.log(msg.id);
2054
- *
2055
- * @example Channel defaults — set common send fields once; a per-send value always wins
2056
- * const bird = new BirdClient({
2057
- * apiKey: process.env.BIRD_API_KEY!,
2058
- * email: { from: "hello@acme.com", category: "transactional" },
2059
- * });
2060
- * // `from` and `category` are filled from the defaults; both stay optional in `send`.
2061
- * await bird.email.send({ to: ["customer@example.com"], subject: "Hi", html: "<p>hi</p>" });
2062
- *
2063
- * @example All client options
2064
- * const bird = new BirdClient({
2065
- * apiKey: process.env.BIRD_API_KEY!,
2066
- * region: "eu1", // optional — override the region from the key prefix
2067
- * baseUrl: "http://localhost:8080", // optional — overrides region entirely (local/self-hosted)
2068
- * timeout: 60_000, // per-attempt timeout in ms (default 60_000)
2069
- * maxRetries: 2, // retry budget for transient failures (default 2)
2070
- * });
2071
- */
2072
- declare class BirdClient<const O extends BirdClientOptions = BirdClientOptions> {
2073
- #private;
2074
- protected readonly core: BirdHTTPClient;
2075
- /** The email channel — `bird.email.send(...)`, `.get(...)`, `.list(...)`. */
2076
- readonly email: EmailResource<EmailDefaultsOf<O>>;
2077
- /** Webhooks — `bird.webhooks.unwrap(payload, headers)` verifies an inbound delivery. */
2078
- readonly webhooks: WebhooksResource;
2079
- constructor(options: O);
2080
- /**
2081
- * Escape hatch for endpoints the typed resources don't cover. Runs the full
2082
- * lifecycle (auth, retries, idempotency, error mapping); you supply the
2083
- * response type. Prefer a typed resource method where one exists.
2084
- *
2085
- * @throws {TypeError} if `req.path` does not start with exactly one `/` or
2086
- * resolves to a different origin than the configured Bird API base URL.
2087
- *
2088
- * @example Reach an endpoint outside the curated surface — you supply the response type
2089
- * type Suppressions = { data: Array<{ recipient: string }> };
2090
- * const suppressions = await bird.request<Suppressions>({ method: "GET", path: "/v1/email/suppressions" });
2091
- * console.log(suppressions.data.length);
2092
- */
2093
- request<T = unknown>(req: BirdRequest, options?: RequestOptions$1): APIPromise<T>;
2094
- }
2095
-
2096
- /** Extracts the region code from a `bk_{region}_{token}` key, or undefined. */
2097
- declare function regionFromApiKey(apiKey: string): string | undefined;
2098
- declare function baseUrlForRegion(region: string): string;
2099
-
2100
- /**
2101
- * Webhook event types known at this SDK version. The wire value is an open
2102
- * string: a value added by a newer server is returned by `unwrap` unchanged,
2103
- * so switch on these with a `default` branch.
2104
- */
2105
- declare const WebhookEventType: {
2106
- readonly DomainFailed: "domain.failed";
2107
- readonly DomainVerified: "domain.verified";
2108
- readonly EmailAccepted: "email.accepted";
2109
- readonly EmailBounced: "email.bounced";
2110
- readonly EmailCanceled: "email.canceled";
2111
- readonly EmailClicked: "email.clicked";
2112
- readonly EmailComplained: "email.complained";
2113
- readonly EmailDeferred: "email.deferred";
2114
- readonly EmailDelivered: "email.delivered";
2115
- readonly EmailListUnsubscribed: "email.list_unsubscribed";
2116
- readonly EmailOpened: "email.opened";
2117
- readonly EmailOutOfBandBounce: "email.out_of_band_bounce";
2118
- readonly EmailProcessed: "email.processed";
2119
- readonly EmailReceived: "email.received";
2120
- readonly EmailRejected: "email.rejected";
2121
- readonly EmailScheduled: "email.scheduled";
2122
- readonly EmailSuppressionCreated: "email_suppression.created";
2123
- readonly EmailUnsubscribed: "email.unsubscribed";
2124
- readonly SmsAccepted: "sms.accepted";
2125
- readonly SmsDelivered: "sms.delivered";
2126
- readonly SmsExpired: "sms.expired";
2127
- readonly SmsFailed: "sms.failed";
2128
- readonly SmsRejected: "sms.rejected";
2129
- readonly SmsSent: "sms.sent";
2130
- readonly SmsUndelivered: "sms.undelivered";
2131
- };
2132
- /** A known webhook event type value. */
2133
- type WebhookEventTypeValue = (typeof WebhookEventType)[keyof typeof WebhookEventType];
2134
-
2135
- export { type APIPromise, BirdAPIError, BirdAuthError, BirdBadRequestError, BirdBillingError, BirdClient, type BirdClientOptions, BirdConflictError, BirdConnectionError, BirdError, BirdInternalError, BirdMisdirectedError, BirdNotFoundError, BirdNotImplementedError, BirdPayloadTooLargeError, BirdPermissionError, BirdPreconditionError, BirdRateLimitError, type BirdRequest, type BirdResponse, BirdServiceUnavailableError, BirdTimeoutError, BirdValidationError, type BirdWebhookEvent, BirdWebhookVerificationError, type CursorPage, type EmailChannelDefaults, type EmailListQuery, type EmailMessage, type EmailSendBatchParams, type EmailSendBatchResult, type EmailSendParams, type ErrorDetail, type ErrorNextAction, type PaginatedPromise, type RequestOptions$1 as RequestOptions, type SafeResult, WebhookEventType, type WebhookEventTypeValue, type WebhookHeaders, type WebhookOptions, baseUrlForRegion, regionFromApiKey };