@messagebird/sdk 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -12
- package/dist/index.d.ts +391 -21
- package/dist/index.js +98 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
The official TypeScript SDK for the [Bird](https://bird.com) API — fully typed, edge-ready, ESM.
|
|
4
4
|
|
|
5
|
+
📚 **Documentation:** https://bird.com/docs/sdks/typescript
|
|
6
|
+
|
|
5
7
|
## Requirements
|
|
6
8
|
|
|
7
9
|
- **Node.js 20.3+** or a modern edge runtime (Cloudflare Workers, Vercel Edge, Deno). The SDK uses only web-standard APIs (`fetch`, `AbortSignal`, Web Crypto) and ships no Node built-ins.
|
|
@@ -17,19 +19,21 @@ pnpm add @messagebird/sdk
|
|
|
17
19
|
|
|
18
20
|
## Quickstart
|
|
19
21
|
|
|
22
|
+
<!-- bird:snippet quickstart-email -->
|
|
23
|
+
|
|
20
24
|
```ts
|
|
21
25
|
import { BirdClient } from "@messagebird/sdk";
|
|
22
26
|
|
|
23
27
|
const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });
|
|
24
28
|
|
|
25
|
-
const
|
|
26
|
-
from: "
|
|
27
|
-
to: ["
|
|
28
|
-
subject: "
|
|
29
|
-
html: "<
|
|
29
|
+
const msg = await bird.email.send({
|
|
30
|
+
from: { email: "onboarding@messagebird.dev", name: "Bird" },
|
|
31
|
+
to: ["delivered@messagebird.dev"],
|
|
32
|
+
subject: "Hello from Bird",
|
|
33
|
+
html: "<p>My first Bird email.</p>",
|
|
30
34
|
});
|
|
31
35
|
|
|
32
|
-
console.log(
|
|
36
|
+
console.log(msg.id, msg.status);
|
|
33
37
|
```
|
|
34
38
|
|
|
35
39
|
The region is inferred from the API key prefix (`bk_{region}_…`). For a local or self-hosted server, pass `baseUrl` (which overrides region resolution).
|
|
@@ -80,14 +84,22 @@ switch (event.type) {
|
|
|
80
84
|
|
|
81
85
|
Methods **throw** on failure with a typed error hierarchy you narrow with `instanceof`:
|
|
82
86
|
|
|
87
|
+
<!-- bird:snippet email.errors -->
|
|
88
|
+
|
|
83
89
|
```ts
|
|
84
|
-
import { BirdRateLimitError, BirdValidationError } from "@messagebird/sdk";
|
|
90
|
+
import { BirdRateLimitError, BirdValidationError, BirdAPIError } from "@messagebird/sdk";
|
|
85
91
|
|
|
86
92
|
try {
|
|
87
|
-
await bird.email.send({
|
|
93
|
+
await bird.email.send({
|
|
94
|
+
from: { email: "onboarding@messagebird.dev", name: "Bird" },
|
|
95
|
+
to: ["delivered@messagebird.dev"],
|
|
96
|
+
subject: "Hello from Bird",
|
|
97
|
+
html: "<p>My first Bird email.</p>",
|
|
98
|
+
});
|
|
88
99
|
} catch (err) {
|
|
89
|
-
if (err instanceof BirdRateLimitError)
|
|
100
|
+
if (err instanceof BirdRateLimitError) console.log(`rate limited — retry in ${err.retryAfter}s`);
|
|
90
101
|
else if (err instanceof BirdValidationError) console.error(err.details);
|
|
102
|
+
else if (err instanceof BirdAPIError) console.error(err.code, err.requestId);
|
|
91
103
|
else throw err;
|
|
92
104
|
}
|
|
93
105
|
```
|
|
@@ -96,10 +108,19 @@ Every API error carries `statusCode`, `requestId`, and `type`. The core retries
|
|
|
96
108
|
|
|
97
109
|
Prefer to branch on a value instead of catching? Use `.safe()`:
|
|
98
110
|
|
|
111
|
+
<!-- bird:snippet email.safe -->
|
|
112
|
+
|
|
99
113
|
```ts
|
|
100
|
-
const { data, error } = await bird.email
|
|
101
|
-
|
|
102
|
-
|
|
114
|
+
const { data, error } = await bird.email
|
|
115
|
+
.send({
|
|
116
|
+
from: { email: "onboarding@messagebird.dev", name: "Bird" },
|
|
117
|
+
to: ["delivered@messagebird.dev"],
|
|
118
|
+
subject: "Hello from Bird",
|
|
119
|
+
html: "<p>My first Bird email.</p>",
|
|
120
|
+
})
|
|
121
|
+
.safe();
|
|
122
|
+
if (error) console.error(error.message);
|
|
123
|
+
else console.log(data.id);
|
|
103
124
|
```
|
|
104
125
|
|
|
105
126
|
And `.withResponse()` exposes transport metadata (status, headers, request id) on success:
|
package/dist/index.d.ts
CHANGED
|
@@ -236,6 +236,240 @@ interface PaginatedPromise<T> extends Promise<CursorPage<T>>, AsyncIterable<T> {
|
|
|
236
236
|
safe(): Promise<SafeResult<CursorPage<T>>>;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Payload of the sms.undelivered event.
|
|
241
|
+
*/
|
|
242
|
+
type EventSmsUndeliveredData = EventSmsBase & {
|
|
243
|
+
/**
|
|
244
|
+
* Why the message was not delivered.
|
|
245
|
+
*/
|
|
246
|
+
error: SmsError;
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* 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.
|
|
250
|
+
*
|
|
251
|
+
*/
|
|
252
|
+
type SmsErrorCode = "invalid_destination" | "unreachable" | "blocked_by_carrier" | "blocked_by_recipient" | "landline_unreachable" | "content_rejected" | "sender_unregistered" | "recipient_opted_out" | "provider_unavailable" | "unknown";
|
|
253
|
+
/**
|
|
254
|
+
* Failure detail for a message that could not be delivered or was rejected. Null when there is no failure.
|
|
255
|
+
*/
|
|
256
|
+
type SmsError = {
|
|
257
|
+
code: SmsErrorCode;
|
|
258
|
+
/**
|
|
259
|
+
* Human-readable explanation of the failure.
|
|
260
|
+
*/
|
|
261
|
+
description: string;
|
|
262
|
+
/**
|
|
263
|
+
* Raw carrier-supplied error code, when available, for low-level debugging.
|
|
264
|
+
*/
|
|
265
|
+
carrier_error_code?: string | null;
|
|
266
|
+
/**
|
|
267
|
+
* When the failure occurred.
|
|
268
|
+
*/
|
|
269
|
+
occurred_at: string;
|
|
270
|
+
} | null;
|
|
271
|
+
/**
|
|
272
|
+
* 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`.
|
|
273
|
+
* Tag count and per-tag size are capped to keep per-send tag payloads small — see SMSMessageSendRequest for the array maximum.
|
|
274
|
+
*
|
|
275
|
+
*/
|
|
276
|
+
type SmsTag = {
|
|
277
|
+
/**
|
|
278
|
+
* Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
|
|
279
|
+
*
|
|
280
|
+
*/
|
|
281
|
+
name: string;
|
|
282
|
+
/**
|
|
283
|
+
* Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
|
|
284
|
+
*
|
|
285
|
+
*/
|
|
286
|
+
value: string;
|
|
287
|
+
};
|
|
288
|
+
type WorkspaceId = string;
|
|
289
|
+
type SmsMessageId = string;
|
|
290
|
+
/**
|
|
291
|
+
* Identity fields shared by every SMS lifecycle event payload.
|
|
292
|
+
*/
|
|
293
|
+
type EventSmsBase = {
|
|
294
|
+
/**
|
|
295
|
+
* ID of the SMS message.
|
|
296
|
+
*/
|
|
297
|
+
sms_id: SmsMessageId;
|
|
298
|
+
/**
|
|
299
|
+
* ID of the workspace.
|
|
300
|
+
*/
|
|
301
|
+
workspace_id: WorkspaceId;
|
|
302
|
+
/**
|
|
303
|
+
* Recipient phone number in E.164 format.
|
|
304
|
+
*/
|
|
305
|
+
to: string;
|
|
306
|
+
/**
|
|
307
|
+
* Sender the message was sent from — an E.164 number, an alphanumeric sender ID, or a short code.
|
|
308
|
+
*/
|
|
309
|
+
from: string;
|
|
310
|
+
/**
|
|
311
|
+
* 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.
|
|
312
|
+
*
|
|
313
|
+
*/
|
|
314
|
+
tags: Array<SmsTag> | null;
|
|
315
|
+
/**
|
|
316
|
+
* 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.
|
|
317
|
+
*
|
|
318
|
+
*/
|
|
319
|
+
metadata: {
|
|
320
|
+
[key: string]: unknown;
|
|
321
|
+
} | null;
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* The carrier reported a non-permanent failure to deliver the message.
|
|
325
|
+
*/
|
|
326
|
+
type EventSmsUndelivered = {
|
|
327
|
+
/**
|
|
328
|
+
* Event type.
|
|
329
|
+
*/
|
|
330
|
+
type: "sms.undelivered";
|
|
331
|
+
/**
|
|
332
|
+
* Time the non-delivery was recorded.
|
|
333
|
+
*/
|
|
334
|
+
timestamp: string;
|
|
335
|
+
data: EventSmsUndeliveredData;
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* Payload of the sms.sent event.
|
|
339
|
+
*/
|
|
340
|
+
type EventSmsSentData = EventSmsBase & {
|
|
341
|
+
/**
|
|
342
|
+
* Carrier that handled the message, or null when not known.
|
|
343
|
+
*/
|
|
344
|
+
carrier: string | null;
|
|
345
|
+
/**
|
|
346
|
+
* Mobile country code and mobile network code of the carrier, or null when not known.
|
|
347
|
+
*/
|
|
348
|
+
mcc_mnc: string | null;
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Bird handed the message to the carrier for delivery.
|
|
352
|
+
*/
|
|
353
|
+
type EventSmsSent = {
|
|
354
|
+
/**
|
|
355
|
+
* Event type.
|
|
356
|
+
*/
|
|
357
|
+
type: "sms.sent";
|
|
358
|
+
/**
|
|
359
|
+
* Time the message was handed to the carrier.
|
|
360
|
+
*/
|
|
361
|
+
timestamp: string;
|
|
362
|
+
data: EventSmsSentData;
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* Payload of the sms.rejected event.
|
|
366
|
+
*/
|
|
367
|
+
type EventSmsRejectedData = EventSmsBase & {
|
|
368
|
+
/**
|
|
369
|
+
* Why the message was rejected before reaching the carrier.
|
|
370
|
+
*/
|
|
371
|
+
error: SmsError;
|
|
372
|
+
};
|
|
373
|
+
/**
|
|
374
|
+
* Bird rejected the message before sending it to the carrier (invalid destination, suppression, or a content/policy guard).
|
|
375
|
+
*/
|
|
376
|
+
type EventSmsRejected = {
|
|
377
|
+
/**
|
|
378
|
+
* Event type.
|
|
379
|
+
*/
|
|
380
|
+
type: "sms.rejected";
|
|
381
|
+
/**
|
|
382
|
+
* Time the rejection was recorded.
|
|
383
|
+
*/
|
|
384
|
+
timestamp: string;
|
|
385
|
+
data: EventSmsRejectedData;
|
|
386
|
+
};
|
|
387
|
+
/**
|
|
388
|
+
* Payload of the sms.failed event.
|
|
389
|
+
*/
|
|
390
|
+
type EventSmsFailedData = EventSmsBase & {
|
|
391
|
+
/**
|
|
392
|
+
* Why the message terminally failed.
|
|
393
|
+
*/
|
|
394
|
+
error: SmsError;
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* The message terminally failed and will not be delivered.
|
|
398
|
+
*/
|
|
399
|
+
type EventSmsFailed = {
|
|
400
|
+
/**
|
|
401
|
+
* Event type.
|
|
402
|
+
*/
|
|
403
|
+
type: "sms.failed";
|
|
404
|
+
/**
|
|
405
|
+
* Time the failure was recorded.
|
|
406
|
+
*/
|
|
407
|
+
timestamp: string;
|
|
408
|
+
data: EventSmsFailedData;
|
|
409
|
+
};
|
|
410
|
+
/**
|
|
411
|
+
* Payload of the sms.expired event.
|
|
412
|
+
*/
|
|
413
|
+
type EventSmsExpiredData = EventSmsBase;
|
|
414
|
+
/**
|
|
415
|
+
* The message's validity period elapsed before it could be delivered.
|
|
416
|
+
*/
|
|
417
|
+
type EventSmsExpired = {
|
|
418
|
+
/**
|
|
419
|
+
* Event type.
|
|
420
|
+
*/
|
|
421
|
+
type: "sms.expired";
|
|
422
|
+
/**
|
|
423
|
+
* Time the message expired.
|
|
424
|
+
*/
|
|
425
|
+
timestamp: string;
|
|
426
|
+
data: EventSmsExpiredData;
|
|
427
|
+
};
|
|
428
|
+
/**
|
|
429
|
+
* Payload of the sms.delivered event.
|
|
430
|
+
*/
|
|
431
|
+
type EventSmsDeliveredData = EventSmsBase & {
|
|
432
|
+
/**
|
|
433
|
+
* Carrier that delivered the message, or null when not known.
|
|
434
|
+
*/
|
|
435
|
+
carrier: string | null;
|
|
436
|
+
/**
|
|
437
|
+
* Mobile country code and mobile network code of the carrier, or null when not known.
|
|
438
|
+
*/
|
|
439
|
+
mcc_mnc: string | null;
|
|
440
|
+
};
|
|
441
|
+
/**
|
|
442
|
+
* The carrier confirmed delivery of the message to the recipient handset.
|
|
443
|
+
*/
|
|
444
|
+
type EventSmsDelivered = {
|
|
445
|
+
/**
|
|
446
|
+
* Event type.
|
|
447
|
+
*/
|
|
448
|
+
type: "sms.delivered";
|
|
449
|
+
/**
|
|
450
|
+
* Time the carrier confirmed delivery.
|
|
451
|
+
*/
|
|
452
|
+
timestamp: string;
|
|
453
|
+
data: EventSmsDeliveredData;
|
|
454
|
+
};
|
|
455
|
+
/**
|
|
456
|
+
* Payload of the sms.accepted event.
|
|
457
|
+
*/
|
|
458
|
+
type EventSmsAcceptedData = EventSmsBase;
|
|
459
|
+
/**
|
|
460
|
+
* Bird accepted the SMS send request and queued it for processing.
|
|
461
|
+
*/
|
|
462
|
+
type EventSmsAccepted = {
|
|
463
|
+
/**
|
|
464
|
+
* Event type.
|
|
465
|
+
*/
|
|
466
|
+
type: "sms.accepted";
|
|
467
|
+
/**
|
|
468
|
+
* Time Bird accepted the request.
|
|
469
|
+
*/
|
|
470
|
+
timestamp: string;
|
|
471
|
+
data: EventSmsAcceptedData;
|
|
472
|
+
};
|
|
239
473
|
/**
|
|
240
474
|
* An email address was added to the workspace's suppression list (manually, via complaint, or via hard bounce). Payload schema not yet finalized.
|
|
241
475
|
*/
|
|
@@ -280,7 +514,6 @@ type EmailTag = {
|
|
|
280
514
|
* Envelope position of a recipient on an outbound email event.
|
|
281
515
|
*/
|
|
282
516
|
type RecipientRole = "to" | "cc" | "bcc";
|
|
283
|
-
type WorkspaceId = string;
|
|
284
517
|
type RecipientId = string;
|
|
285
518
|
type EmailId = string;
|
|
286
519
|
/**
|
|
@@ -360,14 +593,15 @@ type EventEmailRejected = {
|
|
|
360
593
|
timestamp: string;
|
|
361
594
|
data: EventEmailRejectedData;
|
|
362
595
|
};
|
|
596
|
+
type InboundEmailMessageId = string;
|
|
363
597
|
/**
|
|
364
598
|
* Payload of the email.received event.
|
|
365
599
|
*/
|
|
366
600
|
type EventEmailReceivedData = {
|
|
367
601
|
/**
|
|
368
|
-
* ID of the received email
|
|
602
|
+
* ID of the received email. Use it with GET /v1/email/inbound-messages/{id} to fetch the body, raw content, and attachments.
|
|
369
603
|
*/
|
|
370
|
-
inbound_message_id:
|
|
604
|
+
inbound_message_id: InboundEmailMessageId;
|
|
371
605
|
/**
|
|
372
606
|
* ID of the workspace.
|
|
373
607
|
*/
|
|
@@ -381,12 +615,36 @@ type EventEmailReceivedData = {
|
|
|
381
615
|
*/
|
|
382
616
|
from: string;
|
|
383
617
|
/**
|
|
384
|
-
*
|
|
618
|
+
* Recipient addresses the message was sent to.
|
|
385
619
|
*/
|
|
386
|
-
|
|
620
|
+
to: Array<string>;
|
|
621
|
+
/**
|
|
622
|
+
* Subject line as received, or null when the message had no subject.
|
|
623
|
+
*/
|
|
624
|
+
subject: string | null;
|
|
625
|
+
/**
|
|
626
|
+
* In-Reply-To header — the Message-ID this message replies to, or null when it is not a reply.
|
|
627
|
+
*/
|
|
628
|
+
in_reply_to?: string | null;
|
|
629
|
+
/**
|
|
630
|
+
* Whether SPF passed for the sender, or null when the result did not carry an SPF verdict.
|
|
631
|
+
*/
|
|
632
|
+
spf_pass?: boolean | null;
|
|
633
|
+
/**
|
|
634
|
+
* Whether DKIM passed for the sender, or null when the result did not carry a DKIM verdict.
|
|
635
|
+
*/
|
|
636
|
+
dkim_pass?: boolean | null;
|
|
637
|
+
/**
|
|
638
|
+
* Whether DMARC passed for the sender, or null when the result did not carry a DMARC verdict.
|
|
639
|
+
*/
|
|
640
|
+
dmarc_pass?: boolean | null;
|
|
641
|
+
/**
|
|
642
|
+
* Spam score for the message. Always null at present; reserved for a future content-scoring capability.
|
|
643
|
+
*/
|
|
644
|
+
spam_score?: number | null;
|
|
387
645
|
};
|
|
388
646
|
/**
|
|
389
|
-
* Bird received and parsed an inbound email. The payload
|
|
647
|
+
* 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}.
|
|
390
648
|
*/
|
|
391
649
|
type EventEmailReceived = {
|
|
392
650
|
/**
|
|
@@ -740,13 +998,52 @@ type WebhookEvent = ({
|
|
|
740
998
|
type: "email.unsubscribed";
|
|
741
999
|
} & EventEmailUnsubscribed) | ({
|
|
742
1000
|
type: "email_suppression.created";
|
|
743
|
-
} & EventEmailSuppressionCreated)
|
|
1001
|
+
} & EventEmailSuppressionCreated) | ({
|
|
1002
|
+
type: "sms.accepted";
|
|
1003
|
+
} & EventSmsAccepted) | ({
|
|
1004
|
+
type: "sms.delivered";
|
|
1005
|
+
} & EventSmsDelivered) | ({
|
|
1006
|
+
type: "sms.expired";
|
|
1007
|
+
} & EventSmsExpired) | ({
|
|
1008
|
+
type: "sms.failed";
|
|
1009
|
+
} & EventSmsFailed) | ({
|
|
1010
|
+
type: "sms.rejected";
|
|
1011
|
+
} & EventSmsRejected) | ({
|
|
1012
|
+
type: "sms.sent";
|
|
1013
|
+
} & EventSmsSent) | ({
|
|
1014
|
+
type: "sms.undelivered";
|
|
1015
|
+
} & EventSmsUndelivered);
|
|
1016
|
+
type EmailMessageBatchResponse = {
|
|
1017
|
+
/**
|
|
1018
|
+
* One entry per message in the batch, in submission order.
|
|
1019
|
+
*/
|
|
1020
|
+
data: Array<EmailMessageBatchItem>;
|
|
1021
|
+
};
|
|
1022
|
+
type EmailMessageBatchItem = {
|
|
1023
|
+
/**
|
|
1024
|
+
* Message ID assigned to this batch item.
|
|
1025
|
+
*/
|
|
1026
|
+
readonly id: EmailId;
|
|
1027
|
+
/**
|
|
1028
|
+
* Initial status of this message in the batch.
|
|
1029
|
+
*/
|
|
1030
|
+
readonly status: "accepted";
|
|
1031
|
+
/**
|
|
1032
|
+
* Resolved category for this batch item.
|
|
1033
|
+
*/
|
|
1034
|
+
category: "marketing" | "transactional";
|
|
1035
|
+
};
|
|
1036
|
+
/**
|
|
1037
|
+
* 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.
|
|
1038
|
+
*
|
|
1039
|
+
*/
|
|
1040
|
+
type EmailMessageBatchRequest = Array<EmailMessageSendRequest>;
|
|
744
1041
|
/**
|
|
745
1042
|
* 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.
|
|
746
1043
|
* Inline images for `<img src="cid:..."/>` references in the HTML body use the `content_id` field together with `content`.
|
|
747
|
-
*
|
|
748
|
-
* Recipient-side delivery reality:
|
|
749
|
-
*
|
|
1044
|
+
* 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.
|
|
1045
|
+
* 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.
|
|
1046
|
+
* 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.
|
|
750
1047
|
*
|
|
751
1048
|
*/
|
|
752
1049
|
type EmailAttachment = {
|
|
@@ -755,12 +1052,12 @@ type EmailAttachment = {
|
|
|
755
1052
|
*/
|
|
756
1053
|
filename: string;
|
|
757
1054
|
/**
|
|
758
|
-
* Base64-encoded attachment bytes. Required. Counts
|
|
1055
|
+
* Base64-encoded attachment bytes. Required. Counts toward the 20 MB estimated generated message-size cap after encoding and MIME wrapping.
|
|
759
1056
|
*
|
|
760
1057
|
*/
|
|
761
1058
|
content: string;
|
|
762
1059
|
/**
|
|
763
|
-
* 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
|
|
1060
|
+
* 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.
|
|
764
1061
|
*
|
|
765
1062
|
*/
|
|
766
1063
|
path?: string;
|
|
@@ -857,7 +1154,7 @@ type EmailMessageSendRequest = {
|
|
|
857
1154
|
* 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`.
|
|
858
1155
|
*
|
|
859
1156
|
*/
|
|
860
|
-
|
|
1157
|
+
ip_pool_id?: string;
|
|
861
1158
|
/**
|
|
862
1159
|
* 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.
|
|
863
1160
|
*
|
|
@@ -868,7 +1165,7 @@ type EmailMessageSendRequest = {
|
|
|
868
1165
|
*/
|
|
869
1166
|
in_reply_to_message_id?: EmailId;
|
|
870
1167
|
/**
|
|
871
|
-
* File attachments.
|
|
1168
|
+
* 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.
|
|
872
1169
|
*
|
|
873
1170
|
*/
|
|
874
1171
|
attachments?: Array<EmailAttachment>;
|
|
@@ -886,15 +1183,16 @@ type EmailMessageSendRequest = {
|
|
|
886
1183
|
*/
|
|
887
1184
|
topic_id?: string;
|
|
888
1185
|
};
|
|
1186
|
+
type EmailAttachmentId = string;
|
|
889
1187
|
/**
|
|
890
|
-
* Attachment metadata returned on API reads. The original content is not echoed back — only the metadata needed for display and audit. To
|
|
1188
|
+
* 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.
|
|
891
1189
|
*
|
|
892
1190
|
*/
|
|
893
1191
|
type EmailAttachmentRef = {
|
|
894
1192
|
/**
|
|
895
1193
|
* Attachment ID, stable per email send.
|
|
896
1194
|
*/
|
|
897
|
-
id?:
|
|
1195
|
+
readonly id?: EmailAttachmentId;
|
|
898
1196
|
/**
|
|
899
1197
|
* Filename as shown to the recipient.
|
|
900
1198
|
*/
|
|
@@ -981,7 +1279,7 @@ type EmailMessage = {
|
|
|
981
1279
|
*/
|
|
982
1280
|
readonly deferred_count: number;
|
|
983
1281
|
/**
|
|
984
|
-
* Number of recipients rejected before delivery. See the per-recipient `rejection_reason` field on `GET /v1/
|
|
1282
|
+
* 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).
|
|
985
1283
|
*
|
|
986
1284
|
*/
|
|
987
1285
|
readonly rejected_count: number;
|
|
@@ -1041,7 +1339,7 @@ type EmailMessage = {
|
|
|
1041
1339
|
/**
|
|
1042
1340
|
* The message this one is a reply to, if any.
|
|
1043
1341
|
*/
|
|
1044
|
-
readonly in_reply_to_message_id?:
|
|
1342
|
+
readonly in_reply_to_message_id?: EmailId | null;
|
|
1045
1343
|
/**
|
|
1046
1344
|
* When all recipients reached a terminal delivered state, or null if not yet fully delivered.
|
|
1047
1345
|
*/
|
|
@@ -1430,6 +1728,10 @@ declare abstract class Resource {
|
|
|
1430
1728
|
|
|
1431
1729
|
/** Body for `bird.email.send`. */
|
|
1432
1730
|
type EmailSendParams = EmailMessageSendRequest;
|
|
1731
|
+
/** Body for `bird.email.sendBatch` — an array of send params, validated as a unit. */
|
|
1732
|
+
type EmailSendBatchParams = EmailMessageBatchRequest;
|
|
1733
|
+
/** Result of `bird.email.sendBatch` — one accepted item per submitted message. */
|
|
1734
|
+
type EmailSendBatchResult = EmailMessageBatchResponse;
|
|
1433
1735
|
/** Filters and cursor params for `bird.email.list`. */
|
|
1434
1736
|
type EmailListQuery = NonNullable<ListEmailMessagesData["query"]>;
|
|
1435
1737
|
/**
|
|
@@ -1485,7 +1787,7 @@ declare class EmailResource<D extends EmailChannelDefaults | undefined = undefin
|
|
|
1485
1787
|
*
|
|
1486
1788
|
* try {
|
|
1487
1789
|
* await bird.email.send({
|
|
1488
|
-
* from: "onboarding@messagebird.dev",
|
|
1790
|
+
* from: { email: "onboarding@messagebird.dev", name: "Bird" },
|
|
1489
1791
|
* to: ["delivered@messagebird.dev"],
|
|
1490
1792
|
* subject: "Hello from Bird",
|
|
1491
1793
|
* html: "<p>My first Bird email.</p>",
|
|
@@ -1502,7 +1804,7 @@ declare class EmailResource<D extends EmailChannelDefaults | undefined = undefin
|
|
|
1502
1804
|
* // bird:snippet:start email.safe
|
|
1503
1805
|
* const { data, error } = await bird.email
|
|
1504
1806
|
* .send({
|
|
1505
|
-
* from: "onboarding@messagebird.dev",
|
|
1807
|
+
* from: { email: "onboarding@messagebird.dev", name: "Bird" },
|
|
1506
1808
|
* to: ["delivered@messagebird.dev"],
|
|
1507
1809
|
* subject: "Hello from Bird",
|
|
1508
1810
|
* html: "<p>My first Bird email.</p>",
|
|
@@ -1513,6 +1815,34 @@ declare class EmailResource<D extends EmailChannelDefaults | undefined = undefin
|
|
|
1513
1815
|
* // bird:snippet:end email.safe
|
|
1514
1816
|
*/
|
|
1515
1817
|
send(params: EmailSend<D>, options?: RequestOptions$1): APIPromise<EmailMessage>;
|
|
1818
|
+
/**
|
|
1819
|
+
* Send a batch of up to 100 independent email messages in one request. The
|
|
1820
|
+
* batch is validated as a unit — if any item fails validation (unverified
|
|
1821
|
+
* sender, all recipients suppressed, field-level errors) the whole batch is
|
|
1822
|
+
* rejected with a `BirdValidationError` and nothing is queued. Resolves with
|
|
1823
|
+
* one accepted item per submitted message, in submission order, once the batch
|
|
1824
|
+
* is accepted (the API's 202). Channel defaults are applied per item.
|
|
1825
|
+
*
|
|
1826
|
+
* @example Send a batch of messages
|
|
1827
|
+
* // bird:snippet:start email.sendBatch
|
|
1828
|
+
* const batch = await bird.email.sendBatch([
|
|
1829
|
+
* {
|
|
1830
|
+
* from: { email: "onboarding@messagebird.dev", name: "Bird" },
|
|
1831
|
+
* to: ["alice@example.com"],
|
|
1832
|
+
* subject: "Your receipt",
|
|
1833
|
+
* html: "<p>Thanks, Alice.</p>",
|
|
1834
|
+
* },
|
|
1835
|
+
* {
|
|
1836
|
+
* from: { email: "onboarding@messagebird.dev", name: "Bird" },
|
|
1837
|
+
* to: ["bob@example.com"],
|
|
1838
|
+
* subject: "Your receipt",
|
|
1839
|
+
* html: "<p>Thanks, Bob.</p>",
|
|
1840
|
+
* },
|
|
1841
|
+
* ]);
|
|
1842
|
+
* for (const item of batch.data) console.log(item.id, item.status);
|
|
1843
|
+
* // bird:snippet:end email.sendBatch
|
|
1844
|
+
*/
|
|
1845
|
+
sendBatch(params: EmailSendBatchParams, options?: RequestOptions$1): APIPromise<EmailSendBatchResult>;
|
|
1516
1846
|
/**
|
|
1517
1847
|
* Fetch a message with aggregate delivery status.
|
|
1518
1848
|
*
|
|
@@ -1567,6 +1897,13 @@ declare class WebhooksResource {
|
|
|
1567
1897
|
* types are returned as-is (handle them in a `default` case) so a newer server
|
|
1568
1898
|
* event can't break an older SDK.
|
|
1569
1899
|
*
|
|
1900
|
+
* @example One call verifies the signature and returns the typed event
|
|
1901
|
+
* // bird:snippet:start webhook.unwrap
|
|
1902
|
+
* // Pass the RAW request body; set the secret via new BirdClient({ webhooks: { secret } }).
|
|
1903
|
+
* const event = bird.webhooks.unwrap(rawBody, headers);
|
|
1904
|
+
* console.log(event.type); // discriminated union — narrow on event.type
|
|
1905
|
+
* // bird:snippet:end webhook.unwrap
|
|
1906
|
+
*
|
|
1570
1907
|
* @example Verify and dispatch — pass the raw request body, never the parsed JSON
|
|
1571
1908
|
* // new BirdClient({ apiKey, webhooks: { secret } })
|
|
1572
1909
|
* try {
|
|
@@ -1689,4 +2026,37 @@ declare class BirdClient<const O extends BirdClientOptions = BirdClientOptions>
|
|
|
1689
2026
|
declare function regionFromApiKey(apiKey: string): string | undefined;
|
|
1690
2027
|
declare function baseUrlForRegion(region: string): string;
|
|
1691
2028
|
|
|
1692
|
-
|
|
2029
|
+
/**
|
|
2030
|
+
* Webhook event types known at this SDK version. The wire value is an open
|
|
2031
|
+
* string: a value added by a newer server is returned by `unwrap` unchanged,
|
|
2032
|
+
* so switch on these with a `default` branch.
|
|
2033
|
+
*/
|
|
2034
|
+
declare const WebhookEventType: {
|
|
2035
|
+
readonly DomainFailed: "domain.failed";
|
|
2036
|
+
readonly DomainVerified: "domain.verified";
|
|
2037
|
+
readonly EmailAccepted: "email.accepted";
|
|
2038
|
+
readonly EmailBounced: "email.bounced";
|
|
2039
|
+
readonly EmailClicked: "email.clicked";
|
|
2040
|
+
readonly EmailComplained: "email.complained";
|
|
2041
|
+
readonly EmailDeferred: "email.deferred";
|
|
2042
|
+
readonly EmailDelivered: "email.delivered";
|
|
2043
|
+
readonly EmailListUnsubscribed: "email.list_unsubscribed";
|
|
2044
|
+
readonly EmailOpened: "email.opened";
|
|
2045
|
+
readonly EmailOutOfBandBounce: "email.out_of_band_bounce";
|
|
2046
|
+
readonly EmailProcessed: "email.processed";
|
|
2047
|
+
readonly EmailReceived: "email.received";
|
|
2048
|
+
readonly EmailRejected: "email.rejected";
|
|
2049
|
+
readonly EmailSuppressionCreated: "email_suppression.created";
|
|
2050
|
+
readonly EmailUnsubscribed: "email.unsubscribed";
|
|
2051
|
+
readonly SmsAccepted: "sms.accepted";
|
|
2052
|
+
readonly SmsDelivered: "sms.delivered";
|
|
2053
|
+
readonly SmsExpired: "sms.expired";
|
|
2054
|
+
readonly SmsFailed: "sms.failed";
|
|
2055
|
+
readonly SmsRejected: "sms.rejected";
|
|
2056
|
+
readonly SmsSent: "sms.sent";
|
|
2057
|
+
readonly SmsUndelivered: "sms.undelivered";
|
|
2058
|
+
};
|
|
2059
|
+
/** A known webhook event type value. */
|
|
2060
|
+
type WebhookEventTypeValue = (typeof WebhookEventType)[keyof typeof WebhookEventType];
|
|
2061
|
+
|
|
2062
|
+
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 PaginatedPromise, type RequestOptions$1 as RequestOptions, type SafeResult, WebhookEventType, type WebhookEventTypeValue, type WebhookHeaders, type WebhookOptions, baseUrlForRegion, regionFromApiKey };
|