@messagebird/sdk 0.9.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +2996 -901
- package/dist/index.mjs +839 -53
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1185,7 +1185,8 @@ const client = createClient(createConfig());
|
|
|
1185
1185
|
/**
|
|
1186
1186
|
* List messages
|
|
1187
1187
|
*
|
|
1188
|
-
* Returns
|
|
1188
|
+
* Returns the workspace's sent and scheduled messages, newest first, as a cursor page. Each item carries the aggregate delivery `status` and per-state recipient counts, not the message body. Combine filters to narrow the page: `status`, `category`, `tag`, exact `to`/`from` address, and a `created_after`/`created_before` time window.
|
|
1189
|
+
*
|
|
1189
1190
|
*/
|
|
1190
1191
|
const listEmailMessages = (options) => (options?.client ?? client).get({
|
|
1191
1192
|
security: [{
|
|
@@ -1202,9 +1203,22 @@ const listEmailMessages = (options) => (options?.client ?? client).get({
|
|
|
1202
1203
|
/**
|
|
1203
1204
|
* Send a message
|
|
1204
1205
|
*
|
|
1205
|
-
* Sends an email to the recipients you list explicitly in `to`/`cc`/`bcc`. Use
|
|
1206
|
-
*
|
|
1207
|
-
*
|
|
1206
|
+
* Sends an email to the recipients you list explicitly in `to`/`cc`/`bcc`. Use it for
|
|
1207
|
+
* transactional sends (receipts, password resets, alerts) and for marketing sends where
|
|
1208
|
+
* you have the recipient addresses on hand; to submit many independent messages in one
|
|
1209
|
+
* request, use [Send a batch of messages](/docs/api/reference/create-email-message-batch)
|
|
1210
|
+
* instead. The `category` field controls suppression policy independently of content:
|
|
1211
|
+
* set it to `marketing` when sending marketing content from this endpoint.
|
|
1212
|
+
*
|
|
1213
|
+
* The `202` response means the message is safely accepted for delivery, not yet
|
|
1214
|
+
* delivered. Fetch it by `id` or subscribe to webhook events to follow delivery. The
|
|
1215
|
+
* request never half-succeeds: an unverified sender domain or any field-level
|
|
1216
|
+
* validation failure rejects it immediately with a `422` naming the reason.
|
|
1217
|
+
* Suppression is evaluated per recipient after acceptance: suppressed recipients
|
|
1218
|
+
* surface as `rejected` on the message's recipient list, never as a synchronous
|
|
1219
|
+
* error. New workspaces can send from the shared onboarding domain before verifying
|
|
1220
|
+
* their own; the [quickstart](/docs/get-started/send-your-first-email) covers its
|
|
1221
|
+
* recipient and volume limits.
|
|
1208
1222
|
*
|
|
1209
1223
|
*/
|
|
1210
1224
|
const createEmailMessage = (options) => (options.client ?? client).post({
|
|
@@ -1226,7 +1240,7 @@ const createEmailMessage = (options) => (options.client ?? client).post({
|
|
|
1226
1240
|
/**
|
|
1227
1241
|
* Send a batch of messages
|
|
1228
1242
|
*
|
|
1229
|
-
* Accepts up to 100 independent email messages and queues them for delivery. All items are validated before any are queued
|
|
1243
|
+
* Accepts up to 100 independent email messages and queues them for delivery. All items are validated before any are queued: if one fails validation, the entire batch is rejected. Field-level validation failures and business-rule failures (such as `domain_not_verified`) both return `422`. Suppression is evaluated per recipient after acceptance, never as a synchronous error. The `202` response returns one entry per message in submission order, each with its own `id` to fetch or correlate webhook events against. Attachments are allowed per message. Each message must stay within the 20 MB estimated generated message-size cap, and the serialized JSON request body for the whole batch has a hard 20 MB cap.
|
|
1230
1244
|
*
|
|
1231
1245
|
*/
|
|
1232
1246
|
const createEmailMessageBatch = (options) => (options.client ?? client).post({
|
|
@@ -1248,7 +1262,7 @@ const createEmailMessageBatch = (options) => (options.client ?? client).post({
|
|
|
1248
1262
|
/**
|
|
1249
1263
|
* Get a message
|
|
1250
1264
|
*
|
|
1251
|
-
* Returns a single
|
|
1265
|
+
* Returns a single message with its aggregate delivery `status` and per-state recipient counts. The response never includes the `html`/`text` bodies; when content storage is enabled for the send, fetch the stored bodies with [Get stored message content](/docs/api/reference/get-email-message-content). Per-recipient statuses and the event timeline are separate sub-resources.
|
|
1252
1266
|
*
|
|
1253
1267
|
*/
|
|
1254
1268
|
const getEmailMessage = (options) => (options.client ?? client).get({
|
|
@@ -1284,7 +1298,7 @@ const cancelEmailMessage = (options) => (options.client ?? client).post({
|
|
|
1284
1298
|
/**
|
|
1285
1299
|
* List contacts
|
|
1286
1300
|
*
|
|
1287
|
-
* Returns a paginated list of contacts in the workspace, newest first. Look up a single contact by its exact `email` or `external_id`, or search by email substring with `
|
|
1301
|
+
* Returns a paginated list of contacts in the workspace, newest first. Look up a single contact by its exact `email` or `external_id`, or search by email substring with `q`.
|
|
1288
1302
|
*
|
|
1289
1303
|
*/
|
|
1290
1304
|
const listContacts = (options) => (options?.client ?? client).get({
|
|
@@ -1302,7 +1316,9 @@ const listContacts = (options) => (options?.client ?? client).get({
|
|
|
1302
1316
|
/**
|
|
1303
1317
|
* Create a contact
|
|
1304
1318
|
*
|
|
1305
|
-
* Creates a contact in the workspace.
|
|
1319
|
+
* Creates a contact in the workspace. The email address is the contact's identity: it is stored trimmed and lowercased, and creating a second contact with the same email, or reusing another contact's `external_id`, returns a conflict error.
|
|
1320
|
+
*
|
|
1321
|
+
* To create or update many contacts in one request, or to write a contact without knowing whether the address already exists, use [Create or update contacts in bulk](/docs/api/reference/create-contact-batch) instead.
|
|
1306
1322
|
*
|
|
1307
1323
|
*/
|
|
1308
1324
|
const createContact = (options) => (options.client ?? client).post({
|
|
@@ -1324,7 +1340,9 @@ const createContact = (options) => (options.client ?? client).post({
|
|
|
1324
1340
|
/**
|
|
1325
1341
|
* Create or update contacts in bulk
|
|
1326
1342
|
*
|
|
1327
|
-
* Creates or updates up to 1,000 contacts in one request, matched by email address (trimmed and lowercased before matching).
|
|
1343
|
+
* Creates or updates up to 1,000 contacts in one request, matched by email address (trimmed and lowercased before matching). A new address creates a contact; an existing one is updated with the fields that entry supplies, and omitted fields keep their stored values. Optionally adds every contact in the request to up to 10 audiences.
|
|
1344
|
+
*
|
|
1345
|
+
* Each entry succeeds or fails on its own: the response lists one result per contact in submission order (`created`, `updated`, or `failed` with the reason), and a failed entry does not abort the rest. If the request itself is invalid, for example when an entry in `audience_ids` does not exist, the whole request fails with a validation error and no contacts are written.
|
|
1328
1346
|
*
|
|
1329
1347
|
*/
|
|
1330
1348
|
const createContactBatch = (options) => (options.client ?? client).post({
|
|
@@ -1346,7 +1364,7 @@ const createContactBatch = (options) => (options.client ?? client).post({
|
|
|
1346
1364
|
/**
|
|
1347
1365
|
* Delete a contact
|
|
1348
1366
|
*
|
|
1349
|
-
* Deletes a contact and removes it from every audience it belongs to. Suppression records for the address are not affected
|
|
1367
|
+
* Deletes a contact permanently and removes it from every audience it belongs to. Suppression records for the address are not affected: an unsubscribed or bounced address stays suppressed even after the contact is deleted.
|
|
1350
1368
|
*
|
|
1351
1369
|
*/
|
|
1352
1370
|
const deleteContact = (options) => (options.client ?? client).delete({
|
|
@@ -1364,7 +1382,8 @@ const deleteContact = (options) => (options.client ?? client).delete({
|
|
|
1364
1382
|
/**
|
|
1365
1383
|
* Get a contact
|
|
1366
1384
|
*
|
|
1367
|
-
* Returns a single contact by
|
|
1385
|
+
* Returns a single contact, including its custom `data` values and the channels it can be reached on. To find a contact's ID by email address or `external_id`, use [List contacts](/docs/api/reference/list-contacts).
|
|
1386
|
+
*
|
|
1368
1387
|
*/
|
|
1369
1388
|
const getContact = (options) => (options.client ?? client).get({
|
|
1370
1389
|
security: [{
|
|
@@ -1381,7 +1400,9 @@ const getContact = (options) => (options.client ?? client).get({
|
|
|
1381
1400
|
/**
|
|
1382
1401
|
* Update a contact
|
|
1383
1402
|
*
|
|
1384
|
-
* Updates a contact. Supplied fields are changed
|
|
1403
|
+
* Updates a contact. Supplied fields are changed and omitted fields are left unchanged; set `first_name`, `last_name`, or `external_id` to null to clear them. Custom values in `data` are merged: keys you supply are set, keys set to null are removed, and keys you omit are unchanged.
|
|
1404
|
+
*
|
|
1405
|
+
* Changing the email address or `external_id` to a value already used by another contact returns a conflict error.
|
|
1385
1406
|
*
|
|
1386
1407
|
*/
|
|
1387
1408
|
const updateContact = (options) => (options.client ?? client).patch({
|
|
@@ -1403,7 +1424,8 @@ const updateContact = (options) => (options.client ?? client).patch({
|
|
|
1403
1424
|
/**
|
|
1404
1425
|
* List contact properties
|
|
1405
1426
|
*
|
|
1406
|
-
* Returns a paginated list of the workspace's contact properties.
|
|
1427
|
+
* Returns a paginated list of the workspace's contact properties, newest first. Archived properties are included; check each entry's `archived` flag.
|
|
1428
|
+
*
|
|
1407
1429
|
*/
|
|
1408
1430
|
const listContactProperties = (options) => (options?.client ?? client).get({
|
|
1409
1431
|
security: [{
|
|
@@ -1420,7 +1442,9 @@ const listContactProperties = (options) => (options?.client ?? client).get({
|
|
|
1420
1442
|
/**
|
|
1421
1443
|
* Create a contact property
|
|
1422
1444
|
*
|
|
1423
|
-
* Defines a custom property that contacts in the workspace can carry. The key becomes available in contact `data` and as a template variable in broadcasts.
|
|
1445
|
+
* Defines a custom property that contacts in the workspace can carry. The key becomes available in contact `data` and as a template variable in broadcasts. The key and type cannot be changed after creation.
|
|
1446
|
+
*
|
|
1447
|
+
* A key already in use returns a conflict error. A workspace can hold at most 200 properties; archived properties keep their key and count toward that limit.
|
|
1424
1448
|
*
|
|
1425
1449
|
*/
|
|
1426
1450
|
const createContactProperty = (options) => (options.client ?? client).post({
|
|
@@ -1442,7 +1466,8 @@ const createContactProperty = (options) => (options.client ?? client).post({
|
|
|
1442
1466
|
/**
|
|
1443
1467
|
* Get a contact property
|
|
1444
1468
|
*
|
|
1445
|
-
* Returns a single contact property
|
|
1469
|
+
* Returns a single contact property: its immutable key and type, the fallback value, and whether it is archived.
|
|
1470
|
+
*
|
|
1446
1471
|
*/
|
|
1447
1472
|
const getContactProperty = (options) => (options.client ?? client).get({
|
|
1448
1473
|
security: [{
|
|
@@ -1459,7 +1484,7 @@ const getContactProperty = (options) => (options.client ?? client).get({
|
|
|
1459
1484
|
/**
|
|
1460
1485
|
* Update a contact property
|
|
1461
1486
|
*
|
|
1462
|
-
* Updates a contact property's fallback value. The key and type cannot be changed after creation
|
|
1487
|
+
* Updates a contact property's fallback value, the only mutable field. The key and type cannot be changed after creation; create a new property instead.
|
|
1463
1488
|
*
|
|
1464
1489
|
*/
|
|
1465
1490
|
const updateContactProperty = (options) => (options.client ?? client).patch({
|
|
@@ -1481,7 +1506,9 @@ const updateContactProperty = (options) => (options.client ?? client).patch({
|
|
|
1481
1506
|
/**
|
|
1482
1507
|
* Archive a contact property
|
|
1483
1508
|
*
|
|
1484
|
-
* Archives a contact property. The key stops being accepted in
|
|
1509
|
+
* Archives a contact property. The key stops being accepted in contact writes and stops rendering in templates, but every value already stored on your contacts is preserved and still returned when you read a contact.
|
|
1510
|
+
*
|
|
1511
|
+
* The key stays reserved and still counts toward the workspace's 200-property limit, so it cannot be re-created with a different type. Archiving an already-archived property returns a conflict error; reverse it with [Unarchive a contact property](/docs/api/reference/unarchive-contact-property).
|
|
1485
1512
|
*
|
|
1486
1513
|
*/
|
|
1487
1514
|
const archiveContactProperty = (options) => (options.client ?? client).post({
|
|
@@ -1499,7 +1526,7 @@ const archiveContactProperty = (options) => (options.client ?? client).post({
|
|
|
1499
1526
|
/**
|
|
1500
1527
|
* Unarchive a contact property
|
|
1501
1528
|
*
|
|
1502
|
-
* Reactivates an archived contact property. The key is accepted in contact writes and renders in templates again; stored values were never removed, so they are unchanged.
|
|
1529
|
+
* Reactivates an archived contact property. The key is accepted in contact writes and renders in templates again; stored values were never removed, so they are unchanged. Unarchiving a property that is not archived returns a conflict error.
|
|
1503
1530
|
*
|
|
1504
1531
|
*/
|
|
1505
1532
|
const unarchiveContactProperty = (options) => (options.client ?? client).post({
|
|
@@ -1517,7 +1544,7 @@ const unarchiveContactProperty = (options) => (options.client ?? client).post({
|
|
|
1517
1544
|
/**
|
|
1518
1545
|
* List audiences
|
|
1519
1546
|
*
|
|
1520
|
-
* Returns a paginated list of audiences in the workspace, newest first. Filter to audiences whose name contains a substring with `
|
|
1547
|
+
* Returns a paginated list of audiences in the workspace, newest first. Filter to audiences whose name contains a substring with `q`.
|
|
1521
1548
|
*
|
|
1522
1549
|
*/
|
|
1523
1550
|
const listAudiences = (options) => (options?.client ?? client).get({
|
|
@@ -1535,7 +1562,7 @@ const listAudiences = (options) => (options?.client ?? client).get({
|
|
|
1535
1562
|
/**
|
|
1536
1563
|
* Create an audience
|
|
1537
1564
|
*
|
|
1538
|
-
* Creates an audience in the workspace.
|
|
1565
|
+
* Creates an audience in the workspace. New audiences start empty: add members with [Add contacts to an audience](/docs/api/reference/assign-audience-contacts) or through [Create or update contacts in bulk](/docs/api/reference/create-contact-batch). Only `static` audiences can be created today; requesting `dynamic` or `external` returns a validation error.
|
|
1539
1566
|
*
|
|
1540
1567
|
*/
|
|
1541
1568
|
const createAudience = (options) => (options.client ?? client).post({
|
|
@@ -1557,7 +1584,7 @@ const createAudience = (options) => (options.client ?? client).post({
|
|
|
1557
1584
|
/**
|
|
1558
1585
|
* Delete an audience
|
|
1559
1586
|
*
|
|
1560
|
-
* Deletes an audience and its memberships. Contacts themselves are not deleted. An audience cannot be deleted while a broadcast targeting it is scheduled, accepted, sending, or canceling
|
|
1587
|
+
* Deletes an audience and its memberships. Contacts themselves are not deleted. An audience cannot be deleted while a broadcast targeting it is scheduled, accepted, sending, or canceling; cancel that broadcast first, then retry.
|
|
1561
1588
|
*
|
|
1562
1589
|
*/
|
|
1563
1590
|
const deleteAudience = (options) => (options.client ?? client).delete({
|
|
@@ -1575,7 +1602,8 @@ const deleteAudience = (options) => (options.client ?? client).delete({
|
|
|
1575
1602
|
/**
|
|
1576
1603
|
* Get an audience
|
|
1577
1604
|
*
|
|
1578
|
-
* Returns a single audience
|
|
1605
|
+
* Returns a single audience: its name, description, and type. The member list is separate; fetch it with [List an audience's contacts](/docs/api/reference/list-audience-contacts).
|
|
1606
|
+
*
|
|
1579
1607
|
*/
|
|
1580
1608
|
const getAudience = (options) => (options.client ?? client).get({
|
|
1581
1609
|
security: [{
|
|
@@ -1592,7 +1620,8 @@ const getAudience = (options) => (options.client ?? client).get({
|
|
|
1592
1620
|
/**
|
|
1593
1621
|
* Update an audience
|
|
1594
1622
|
*
|
|
1595
|
-
* Updates an audience's name or description.
|
|
1623
|
+
* Updates an audience's name or description. Omitted fields are left unchanged; set `description` to null to clear it.
|
|
1624
|
+
*
|
|
1596
1625
|
*/
|
|
1597
1626
|
const updateAudience = (options) => (options.client ?? client).patch({
|
|
1598
1627
|
security: [{
|
|
@@ -1631,7 +1660,7 @@ const listAudienceContacts = (options) => (options.client ?? client).get({
|
|
|
1631
1660
|
/**
|
|
1632
1661
|
* Add contacts to an audience
|
|
1633
1662
|
*
|
|
1634
|
-
* Adds up to 1,000 contacts to
|
|
1663
|
+
* Adds up to 1,000 contacts to an audience. Adding is idempotent: contacts that are already members are left in place and keep their original join time. If any contact ID does not exist in the workspace, the whole request fails with a validation error and no contacts are added.
|
|
1635
1664
|
*
|
|
1636
1665
|
*/
|
|
1637
1666
|
const assignAudienceContacts = (options) => (options.client ?? client).post({
|
|
@@ -1653,7 +1682,7 @@ const assignAudienceContacts = (options) => (options.client ?? client).post({
|
|
|
1653
1682
|
/**
|
|
1654
1683
|
* Remove contacts from an audience
|
|
1655
1684
|
*
|
|
1656
|
-
* Removes up to 1,000 contacts from
|
|
1685
|
+
* Removes up to 1,000 contacts from an audience. Contacts that are not members are skipped. If any contact ID does not exist in the workspace, the whole request fails with a validation error and no memberships are removed. The contacts themselves are not deleted and remain members of any other audiences.
|
|
1657
1686
|
*
|
|
1658
1687
|
*/
|
|
1659
1688
|
const unassignAudienceContacts = (options) => (options.client ?? client).post({
|
|
@@ -1693,7 +1722,8 @@ const unassignAudienceContact = (options) => (options.client ?? client).delete({
|
|
|
1693
1722
|
/**
|
|
1694
1723
|
* List SMS messages
|
|
1695
1724
|
*
|
|
1696
|
-
* Returns a paginated list
|
|
1725
|
+
* Returns the workspace's SMS messages as a cursor-paginated list, newest first. Filter by direction, status, category, recipient, sender, failure reason, tag, or creation time; pass the response's `next_cursor` back as `starting_after` to fetch the next page. To follow a single message's delivery, use [Get an SMS message](/docs/api/reference/get-sms-message) instead.
|
|
1726
|
+
*
|
|
1697
1727
|
*/
|
|
1698
1728
|
const listSmsMessages = (options) => (options?.client ?? client).get({
|
|
1699
1729
|
security: [{
|
|
@@ -1710,7 +1740,22 @@ const listSmsMessages = (options) => (options?.client ?? client).get({
|
|
|
1710
1740
|
/**
|
|
1711
1741
|
* Send an SMS message
|
|
1712
1742
|
*
|
|
1713
|
-
* Sends
|
|
1743
|
+
* Sends one SMS message to a single recipient. A send carries exactly one
|
|
1744
|
+
* content form: `text` (free text, which also requires `category`) or
|
|
1745
|
+
* `template` (a stored template that supplies the body and category). To
|
|
1746
|
+
* submit up to 100 independent messages in one request, use
|
|
1747
|
+
* [Send a batch of SMS messages](/docs/api/reference/create-sms-message-batch)
|
|
1748
|
+
* instead.
|
|
1749
|
+
*
|
|
1750
|
+
* The `202` response means Bird durably accepted the message for asynchronous
|
|
1751
|
+
* delivery, not that it was delivered. Follow delivery with
|
|
1752
|
+
* [Get an SMS message](/docs/api/reference/get-sms-message) or by subscribing
|
|
1753
|
+
* to `sms.*` webhook events.
|
|
1754
|
+
*
|
|
1755
|
+
* Sends fail with a `422` when a field is invalid, the body exceeds the
|
|
1756
|
+
* 12-segment cap, the destination country is not enabled for the workspace,
|
|
1757
|
+
* or the sender is not permitted for the destination; a send from a
|
|
1758
|
+
* workspace with no wallet balance fails with a `402`.
|
|
1714
1759
|
*
|
|
1715
1760
|
*/
|
|
1716
1761
|
const createSmsMessage = (options) => (options.client ?? client).post({
|
|
@@ -1732,7 +1777,16 @@ const createSmsMessage = (options) => (options.client ?? client).post({
|
|
|
1732
1777
|
/**
|
|
1733
1778
|
* Send a batch of SMS messages
|
|
1734
1779
|
*
|
|
1735
|
-
*
|
|
1780
|
+
* Sends up to 100 independent SMS messages in one request. Each item is a
|
|
1781
|
+
* complete send request with its own recipient, content, id, status, and
|
|
1782
|
+
* cost. For a single message, use
|
|
1783
|
+
* [Send an SMS message](/docs/api/reference/create-sms-message) instead.
|
|
1784
|
+
*
|
|
1785
|
+
* Acceptance is all-or-nothing: every item is validated before any is queued,
|
|
1786
|
+
* and one invalid item rejects the whole batch with a `422` (nothing is
|
|
1787
|
+
* sent). A batch from a workspace with no wallet balance fails with a `402`.
|
|
1788
|
+
* The `202` response lists the accepted messages in submission order; each
|
|
1789
|
+
* delivers asynchronously and is tracked individually, like a single send.
|
|
1736
1790
|
*
|
|
1737
1791
|
*/
|
|
1738
1792
|
const createSmsMessageBatch = (options) => (options.client ?? client).post({
|
|
@@ -1754,7 +1808,8 @@ const createSmsMessageBatch = (options) => (options.client ?? client).post({
|
|
|
1754
1808
|
/**
|
|
1755
1809
|
* Get an SMS message
|
|
1756
1810
|
*
|
|
1757
|
-
* Returns a single SMS message
|
|
1811
|
+
* Returns a single SMS message: its current delivery status, segment breakdown, cost, and failure detail when it failed. The `status` advances asynchronously as delivery progresses, and `cost` is null until the message has been priced, so poll this endpoint (or subscribe to `sms.*` webhook events) after a send to confirm delivery. To scan messages in bulk, use [List SMS messages](/docs/api/reference/list-sms-messages) instead.
|
|
1812
|
+
*
|
|
1758
1813
|
*/
|
|
1759
1814
|
const getSmsMessage = (options) => (options.client ?? client).get({
|
|
1760
1815
|
security: [{
|
|
@@ -1771,7 +1826,7 @@ const getSmsMessage = (options) => (options.client ?? client).get({
|
|
|
1771
1826
|
/**
|
|
1772
1827
|
* List SMS templates
|
|
1773
1828
|
*
|
|
1774
|
-
* Returns the SMS templates
|
|
1829
|
+
* Returns the SMS templates you can send from, including Bird's built-in templates. Filter by scope, category, or language; the catalogue is small and returned in full, so this list is not paginated. To read one template's variables before sending with it, use [Get an SMS template](/docs/api/reference/get-sms-template).
|
|
1775
1830
|
*
|
|
1776
1831
|
*/
|
|
1777
1832
|
const listSmsTemplates = (options) => (options?.client ?? client).get({
|
|
@@ -1789,7 +1844,8 @@ const listSmsTemplates = (options) => (options?.client ?? client).get({
|
|
|
1789
1844
|
/**
|
|
1790
1845
|
* Get an SMS template
|
|
1791
1846
|
*
|
|
1792
|
-
* Returns a single SMS template
|
|
1847
|
+
* Returns a single SMS template: its body preview, category, the `variables` it expects (each with its accepted format), and the languages it is available in. Fetch a template before sending with it to see which `parameters` keys are required; an unknown reference returns a `404`. To browse the whole catalogue, use [List SMS templates](/docs/api/reference/list-sms-templates) instead.
|
|
1848
|
+
*
|
|
1793
1849
|
*/
|
|
1794
1850
|
const getSmsTemplate = (options) => (options.client ?? client).get({
|
|
1795
1851
|
security: [{
|
|
@@ -1806,7 +1862,11 @@ const getSmsTemplate = (options) => (options.client ?? client).get({
|
|
|
1806
1862
|
/**
|
|
1807
1863
|
* Create a verification
|
|
1808
1864
|
*
|
|
1809
|
-
* Creates a verification for a recipient and sends them a one-time passcode. Provide
|
|
1865
|
+
* Creates a verification for a recipient and sends them a one-time passcode. Provide the recipient in `to`: an email address (verified over email), a phone number (verified over SMS), or both. With both, the passcode is sent over one channel at a time and delivery falls over to the other channel if the first fails; it is never sent to both at once.
|
|
1866
|
+
*
|
|
1867
|
+
* Calling this again for the same recipient resumes the verification in progress rather than starting a second one: within the resend cooldown the request returns the current state without sending, and after it a fresh passcode is sent. Use the same call to send and to resend.
|
|
1868
|
+
*
|
|
1869
|
+
* The `200` response is the verification's current state; the passcode itself is never returned. Submit the passcode the recipient enters with POST /v1/verify/verifications/check before the verification's `expires_at`. An invalid recipient returns `422`, and requesting passcodes for the same recipient too often returns `429`.
|
|
1810
1870
|
*
|
|
1811
1871
|
*/
|
|
1812
1872
|
const createVerification = (options) => (options.client ?? client).post({
|
|
@@ -1828,7 +1888,11 @@ const createVerification = (options) => (options.client ?? client).post({
|
|
|
1828
1888
|
/**
|
|
1829
1889
|
* Check a verification passcode
|
|
1830
1890
|
*
|
|
1831
|
-
* Checks a passcode for a recipient and returns the outcome together with the verification's current state. Identify the verification by the same `to`
|
|
1891
|
+
* Checks a passcode for a recipient and returns the outcome together with the verification's current state. Identify the verification by the same `to` used to create it; you do not need to store a verification ID.
|
|
1892
|
+
*
|
|
1893
|
+
* A wrong or expired passcode is a normal outcome, not an HTTP error: the response is `200` with `success` set to `false` and a `reason` such as `incorrect_code` or `expired`. `success: true` means the verification is complete. Each verification reports its final outcome exactly once and is no longer checkable afterwards.
|
|
1894
|
+
*
|
|
1895
|
+
* An error status is returned only when the check cannot be evaluated: `404` when no verification matches the recipient or the matching one already reached its final state, `422` for an invalid recipient, and `429` when passcodes for a recipient are checked too quickly.
|
|
1832
1896
|
*
|
|
1833
1897
|
*/
|
|
1834
1898
|
const createVerificationCheck = (options) => (options.client ?? client).post({
|
|
@@ -1850,7 +1914,8 @@ const createVerificationCheck = (options) => (options.client ?? client).post({
|
|
|
1850
1914
|
/**
|
|
1851
1915
|
* List WhatsApp messages
|
|
1852
1916
|
*
|
|
1853
|
-
* Returns a paginated list
|
|
1917
|
+
* Returns the workspace's WhatsApp messages as a cursor-paginated list, newest first. Filter by status, contact phone number, business-scoped user ID, tag, or creation time; pass the response's `next_cursor` back as `starting_after` to fetch the next page. To follow a single message's delivery, use [Get a WhatsApp message](/docs/api/reference/get-whats-app-message) instead.
|
|
1918
|
+
*
|
|
1854
1919
|
*/
|
|
1855
1920
|
const listWhatsAppMessages = (options) => (options?.client ?? client).get({
|
|
1856
1921
|
security: [{
|
|
@@ -1865,9 +1930,27 @@ const listWhatsAppMessages = (options) => (options?.client ?? client).get({
|
|
|
1865
1930
|
...options
|
|
1866
1931
|
});
|
|
1867
1932
|
/**
|
|
1868
|
-
* Send a message
|
|
1933
|
+
* Send a WhatsApp message
|
|
1934
|
+
*
|
|
1935
|
+
* Sends a WhatsApp message built from a message template to one recipient.
|
|
1936
|
+
* Name the template, optionally pick its language variant, and fill its
|
|
1937
|
+
* placeholders in `components`; Bird selects the sender number from the
|
|
1938
|
+
* template's category, so the request carries no sender field. Templates are
|
|
1939
|
+
* the only supported content type: a request without `template` is rejected
|
|
1940
|
+
* with a `422`. Browse what you can send with
|
|
1941
|
+
* [List available message templates](/docs/api/reference/list-whats-app-templates).
|
|
1942
|
+
*
|
|
1943
|
+
* The `202` response is the accepted message, echoing the resolved template
|
|
1944
|
+
* and language; it is not a delivery confirmation. Follow delivery with
|
|
1945
|
+
* [Get a WhatsApp message](/docs/api/reference/get-whats-app-message), the
|
|
1946
|
+
* per-message timeline from
|
|
1947
|
+
* [List events for a WhatsApp message](/docs/api/reference/list-whats-app-message-events),
|
|
1948
|
+
* or `whatsapp.*` webhook events.
|
|
1949
|
+
*
|
|
1950
|
+
* A template name or language the catalogue does not stock, parameter values
|
|
1951
|
+
* that do not match the template's declared placeholders, and a recipient
|
|
1952
|
+
* that is not a valid phone number each return a `422`.
|
|
1869
1953
|
*
|
|
1870
|
-
* Sends a template message. Bird selects the sender number from the template's category.
|
|
1871
1954
|
*/
|
|
1872
1955
|
const sendWhatsAppMessage = (options) => (options.client ?? client).post({
|
|
1873
1956
|
security: [{
|
|
@@ -1888,7 +1971,8 @@ const sendWhatsAppMessage = (options) => (options.client ?? client).post({
|
|
|
1888
1971
|
/**
|
|
1889
1972
|
* Get a WhatsApp message
|
|
1890
1973
|
*
|
|
1891
|
-
* Returns a single WhatsApp message
|
|
1974
|
+
* Returns a single WhatsApp message: its current delivery status, per-stage timestamps (`sent_at`, `delivered_at`, `read_at`), the template it was sent from, and failure detail when it failed. The `status` advances asynchronously as delivery progresses, so poll this endpoint (or subscribe to `whatsapp.*` webhook events) after a send to confirm delivery. For the per-event timeline, use [List events for a WhatsApp message](/docs/api/reference/list-whats-app-message-events) instead.
|
|
1975
|
+
*
|
|
1892
1976
|
*/
|
|
1893
1977
|
const getWhatsAppMessage = (options) => (options.client ?? client).get({
|
|
1894
1978
|
security: [{
|
|
@@ -1905,7 +1989,8 @@ const getWhatsAppMessage = (options) => (options.client ?? client).get({
|
|
|
1905
1989
|
/**
|
|
1906
1990
|
* List events for a WhatsApp message
|
|
1907
1991
|
*
|
|
1908
|
-
* Returns
|
|
1992
|
+
* Returns a WhatsApp message's lifecycle events in chronological order, one entry per delivery transition (`whatsapp.accepted`, `whatsapp.sent`, `whatsapp.delivered`, `whatsapp.read`, `whatsapp.failed`). The timeline is bounded and returned in full, so this list is not paginated; an unknown message id returns a `404`. For the message's current state in a single field, use [Get a WhatsApp message](/docs/api/reference/get-whats-app-message) instead.
|
|
1993
|
+
*
|
|
1909
1994
|
*/
|
|
1910
1995
|
const listWhatsAppMessageEvents = (options) => (options.client ?? client).get({
|
|
1911
1996
|
security: [{
|
|
@@ -1922,7 +2007,8 @@ const listWhatsAppMessageEvents = (options) => (options.client ?? client).get({
|
|
|
1922
2007
|
/**
|
|
1923
2008
|
* List available message templates
|
|
1924
2009
|
*
|
|
1925
|
-
* Returns the message templates
|
|
2010
|
+
* Returns the WhatsApp message templates you can send from. Each entry carries the template's `name` (the reference you pass when sending), its language, category, review status, and its content blocks with example values for every placeholder. The catalogue is returned in full, so this list is not paginated, and it can differ by region: you see the templates stocked for the region you call. Pick a template here, then fill its placeholders in the `components` of [Send a WhatsApp message](/docs/api/reference/send-whats-app-message).
|
|
2011
|
+
*
|
|
1926
2012
|
*/
|
|
1927
2013
|
const listWhatsAppTemplates = (options) => (options?.client ?? client).get({
|
|
1928
2014
|
security: [{
|
|
@@ -1937,9 +2023,362 @@ const listWhatsAppTemplates = (options) => (options?.client ?? client).get({
|
|
|
1937
2023
|
...options
|
|
1938
2024
|
});
|
|
1939
2025
|
/**
|
|
2026
|
+
* Daily sending statistics
|
|
2027
|
+
*
|
|
2028
|
+
* Returns one row of aggregate sending statistics per calendar day for the workspace: UTC days by default, or your local days when `timezone` is set. Days with no activity are included with zero counts, so the series charts without client-side gap handling. Suited to charts and trend lines; for per-message exact accounting use the message detail endpoints.
|
|
2029
|
+
*
|
|
2030
|
+
* Rows are bucketed by event time, not send time: a complaint received on Wednesday for a message sent the prior Monday is counted in Wednesday's row.
|
|
2031
|
+
*
|
|
2032
|
+
* The maximum window is 365 days; requesting a longer range returns 422.
|
|
2033
|
+
*
|
|
2034
|
+
*/
|
|
2035
|
+
const getEmailStatsDaily = (options) => (options?.client ?? client).get({
|
|
2036
|
+
security: [{
|
|
2037
|
+
scheme: "bearer",
|
|
2038
|
+
type: "http"
|
|
2039
|
+
}, {
|
|
2040
|
+
in: "cookie",
|
|
2041
|
+
name: "bird_session",
|
|
2042
|
+
type: "apiKey"
|
|
2043
|
+
}],
|
|
2044
|
+
url: "/v1/email/stats/daily",
|
|
2045
|
+
...options
|
|
2046
|
+
});
|
|
2047
|
+
/**
|
|
2048
|
+
* Hourly sending statistics
|
|
2049
|
+
*
|
|
2050
|
+
* Returns one row of aggregate sending statistics per hour for the workspace: UTC hours by default, or your local hours when `timezone` is set (a timezone with a sub-hour offset gets correctly aligned hours). Useful for inspecting send rate, deliverability, and engagement inside a single day or a recent window; hours with no activity are included with zero counts.
|
|
2051
|
+
*
|
|
2052
|
+
* Rows are bucketed by event time, not send time: a click recorded at 14:07 for a message sent at 09:00 lands in the 14:00 row.
|
|
2053
|
+
*
|
|
2054
|
+
* A single request may span at most 30 days (720 hourly rows); for longer ranges use the daily endpoint, which has a 365-day window. An hourly window longer than 30 days, or a `from` after `to`, returns 422.
|
|
2055
|
+
*
|
|
2056
|
+
*/
|
|
2057
|
+
const getEmailStatsHourly = (options) => (options?.client ?? client).get({
|
|
2058
|
+
security: [{
|
|
2059
|
+
scheme: "bearer",
|
|
2060
|
+
type: "http"
|
|
2061
|
+
}, {
|
|
2062
|
+
in: "cookie",
|
|
2063
|
+
name: "bird_session",
|
|
2064
|
+
type: "apiKey"
|
|
2065
|
+
}],
|
|
2066
|
+
url: "/v1/email/stats/hourly",
|
|
2067
|
+
...options
|
|
2068
|
+
});
|
|
2069
|
+
/**
|
|
2070
|
+
* Stats by tag
|
|
2071
|
+
*
|
|
2072
|
+
* Returns aggregate delivery and engagement counts grouped by tag for the requested period. Rows are ranked by the `sort` metric (default `processed`) descending and capped at the requested `limit` (default 50, hard maximum 200). Use this to compare campaign performance across tags you set at send time.
|
|
2073
|
+
*
|
|
2074
|
+
* Rows are computed against event time (not send time), so engagement received during the period for messages sent earlier is included.
|
|
2075
|
+
*
|
|
2076
|
+
* The maximum window is 365 days; requesting a longer range returns 422.
|
|
2077
|
+
*
|
|
2078
|
+
*/
|
|
2079
|
+
const getEmailStatsByTag = (options) => (options?.client ?? client).get({
|
|
2080
|
+
security: [{
|
|
2081
|
+
scheme: "bearer",
|
|
2082
|
+
type: "http"
|
|
2083
|
+
}, {
|
|
2084
|
+
in: "cookie",
|
|
2085
|
+
name: "bird_session",
|
|
2086
|
+
type: "apiKey"
|
|
2087
|
+
}],
|
|
2088
|
+
url: "/v1/email/stats/tags",
|
|
2089
|
+
...options
|
|
2090
|
+
});
|
|
2091
|
+
/**
|
|
2092
|
+
* Aggregate stats summary
|
|
2093
|
+
*
|
|
2094
|
+
* Returns a single-row aggregate across the requested period covering delivery, bounce, complaint, open, and click counts plus the derived rates, along with processing, delivery, and total latency percentiles (p50/p95/p99). Suitable for KPI tiles, campaign reports, and email digests; the daily and hourly endpoints carry the same metrics per time bucket.
|
|
2095
|
+
*
|
|
2096
|
+
* The aggregate is computed against event time (not send time), so engagement received during the period for messages sent earlier is included. Rate fields are null when their denominator is zero.
|
|
2097
|
+
*
|
|
2098
|
+
* The window grain follows the form of `from` and `to`: calendar days (`YYYY-MM-DD`, up to 365 days) or RFC 3339 instants (hour grain, up to 720 hours, 30 days), so a rolling window such as the last 24 hours is a single request. Mixing the two forms returns 422. Set `timezone` to compute day and hour boundaries in a local zone instead of UTC, and `compare=previous_period` to include the preceding equal-length window in the same response.
|
|
2099
|
+
*
|
|
2100
|
+
*/
|
|
2101
|
+
const getEmailStatsSummary = (options) => (options?.client ?? client).get({
|
|
2102
|
+
security: [{
|
|
2103
|
+
scheme: "bearer",
|
|
2104
|
+
type: "http"
|
|
2105
|
+
}, {
|
|
2106
|
+
in: "cookie",
|
|
2107
|
+
name: "bird_session",
|
|
2108
|
+
type: "apiKey"
|
|
2109
|
+
}],
|
|
2110
|
+
url: "/v1/email/stats/summary",
|
|
2111
|
+
...options
|
|
2112
|
+
});
|
|
2113
|
+
/**
|
|
2114
|
+
* Stats by sending IP
|
|
2115
|
+
*
|
|
2116
|
+
* Returns delivery and deliverability counts grouped by the specific IP address used to send each message. Use this to identify per-IP reputation issues: block bounces concentrated on a single IP usually indicate a reputation problem on that IP, and `sort=bounces.block` surfaces those IPs first.
|
|
2117
|
+
*
|
|
2118
|
+
* A sending IP is known only once the upstream mail system reports delivery, bounce, deferral, or a late bounce, so rows cover the delivery stage onward: `accepted` and `processed` counts, processing latency, engagement, and complaint attribution are not available per IP. For workspace-wide figures use `GET /v1/email/stats/daily`. Rows are computed against event time (not send time).
|
|
2119
|
+
*
|
|
2120
|
+
* Rows are ranked by the `sort` field (default `delivered`) descending and capped at the requested `limit` (default 50, hard maximum 200). The maximum window is 365 days; requesting a longer range returns 422.
|
|
2121
|
+
*
|
|
2122
|
+
*/
|
|
2123
|
+
const getEmailStatsBySendingIp = (options) => (options?.client ?? client).get({
|
|
2124
|
+
security: [{
|
|
2125
|
+
scheme: "bearer",
|
|
2126
|
+
type: "http"
|
|
2127
|
+
}, {
|
|
2128
|
+
in: "cookie",
|
|
2129
|
+
name: "bird_session",
|
|
2130
|
+
type: "apiKey"
|
|
2131
|
+
}],
|
|
2132
|
+
url: "/v1/email/stats/sending-ips",
|
|
2133
|
+
...options
|
|
2134
|
+
});
|
|
2135
|
+
/**
|
|
2136
|
+
* Stats by sending domain
|
|
2137
|
+
*
|
|
2138
|
+
* Returns delivery, engagement, and deliverability counts grouped by sending domain (the portion of the `From` address after the `@`). Use this to compare deliverability across multiple verified domains in your workspace, for example transactional versus marketing domains, or sub-domain segregation during IP warming.
|
|
2139
|
+
*
|
|
2140
|
+
* Rows are computed against event time (not send time), so engagement and bounces received during the period for messages sent earlier are included.
|
|
2141
|
+
*
|
|
2142
|
+
* Rows are ranked by the `sort` metric (default `processed`) descending and capped at the requested `limit` (default 50, hard maximum 200). The maximum window is 365 days; requesting a longer range returns 422.
|
|
2143
|
+
*
|
|
2144
|
+
*/
|
|
2145
|
+
const getEmailStatsBySendingDomain = (options) => (options?.client ?? client).get({
|
|
2146
|
+
security: [{
|
|
2147
|
+
scheme: "bearer",
|
|
2148
|
+
type: "http"
|
|
2149
|
+
}, {
|
|
2150
|
+
in: "cookie",
|
|
2151
|
+
name: "bird_session",
|
|
2152
|
+
type: "apiKey"
|
|
2153
|
+
}],
|
|
2154
|
+
url: "/v1/email/stats/sending-domains",
|
|
2155
|
+
...options
|
|
2156
|
+
});
|
|
2157
|
+
/**
|
|
2158
|
+
* Stats by category
|
|
2159
|
+
*
|
|
2160
|
+
* Returns aggregate delivery and engagement counts grouped by category for the requested period. Rows are ranked by the `sort` metric (default `processed`) descending and capped at the requested `limit` (default 50, hard maximum 200). Use this to compare deliverability and engagement between your transactional and marketing traffic.
|
|
2161
|
+
*
|
|
2162
|
+
* Rows are computed against event time (not send time), so engagement received during the period for messages sent earlier is included.
|
|
2163
|
+
*
|
|
2164
|
+
* The maximum window is 365 days; requesting a longer range returns 422.
|
|
2165
|
+
*
|
|
2166
|
+
*/
|
|
2167
|
+
const getEmailStatsByCategory = (options) => (options?.client ?? client).get({
|
|
2168
|
+
security: [{
|
|
2169
|
+
scheme: "bearer",
|
|
2170
|
+
type: "http"
|
|
2171
|
+
}, {
|
|
2172
|
+
in: "cookie",
|
|
2173
|
+
name: "bird_session",
|
|
2174
|
+
type: "apiKey"
|
|
2175
|
+
}],
|
|
2176
|
+
url: "/v1/email/stats/categories",
|
|
2177
|
+
...options
|
|
2178
|
+
});
|
|
2179
|
+
/**
|
|
2180
|
+
* Stats by mailbox provider
|
|
2181
|
+
*
|
|
2182
|
+
* Returns delivery, engagement, and deliverability counts grouped by recipient mailbox provider (for example `gmail`, `yahoo`, `microsoft`, `apple`): the deliverability-by-inbox-provider view. Use this to compare how each major inbox provider treats your mail, for example to spot a delivered-rate dip or complaint spike at one provider before it spreads; for a per-region split within a provider, use the mailbox-provider-region breakdown.
|
|
2183
|
+
*
|
|
2184
|
+
* A recipient's mailbox provider is known only once the receiving mail system reports an outcome, so rows cover the delivery stage onward: `accepted`, `processed`, and `rejected` counts and processing latency are not included. Rows are computed against event time (not send time).
|
|
2185
|
+
*
|
|
2186
|
+
* Rows are ranked by the `sort` metric (default `delivered`) descending and capped at the requested `limit` (default 50, hard maximum 200). The maximum window is 365 days; requesting a longer range returns 422.
|
|
2187
|
+
*
|
|
2188
|
+
*/
|
|
2189
|
+
const getEmailStatsByMailboxProvider = (options) => (options?.client ?? client).get({
|
|
2190
|
+
security: [{
|
|
2191
|
+
scheme: "bearer",
|
|
2192
|
+
type: "http"
|
|
2193
|
+
}, {
|
|
2194
|
+
in: "cookie",
|
|
2195
|
+
name: "bird_session",
|
|
2196
|
+
type: "apiKey"
|
|
2197
|
+
}],
|
|
2198
|
+
url: "/v1/email/stats/mailbox-providers",
|
|
2199
|
+
...options
|
|
2200
|
+
});
|
|
2201
|
+
/**
|
|
2202
|
+
* Stats by mailbox provider region
|
|
2203
|
+
*
|
|
2204
|
+
* Returns delivery, engagement, and deliverability counts grouped by mailbox provider and provider region pair, for example `gmail` in `NA` or `microsoft` in `EU`. The provider region is the regional pod the receiving mail system reports for the recipient's provider; pairing it with the provider disambiguates a region label that several providers share. Use this to spot a deliverability problem isolated to one provider in one region; for a per-provider view without the region split, use the mailbox-provider breakdown.
|
|
2205
|
+
*
|
|
2206
|
+
* A provider region is known only once the receiving mail system reports an outcome, so rows cover the delivery stage onward: `accepted`, `processed`, and `rejected` counts and processing latency are not included. Rows are computed against event time (not send time).
|
|
2207
|
+
*
|
|
2208
|
+
* Rows are ranked by the `sort` metric (default `delivered`) descending and capped at the requested `limit` (default 50, hard maximum 200). The maximum window is 365 days; requesting a longer range returns 422.
|
|
2209
|
+
*
|
|
2210
|
+
*/
|
|
2211
|
+
const getEmailStatsByMailboxProviderRegion = (options) => (options?.client ?? client).get({
|
|
2212
|
+
security: [{
|
|
2213
|
+
scheme: "bearer",
|
|
2214
|
+
type: "http"
|
|
2215
|
+
}, {
|
|
2216
|
+
in: "cookie",
|
|
2217
|
+
name: "bird_session",
|
|
2218
|
+
type: "apiKey"
|
|
2219
|
+
}],
|
|
2220
|
+
url: "/v1/email/stats/mailbox-provider-regions",
|
|
2221
|
+
...options
|
|
2222
|
+
});
|
|
2223
|
+
/**
|
|
2224
|
+
* Stats by recipient domain
|
|
2225
|
+
*
|
|
2226
|
+
* Returns aggregate delivery and engagement counts grouped by recipient mailbox domain (the part of each recipient address after the `@`, for example `gmail.com`, `yahoo.com`, `outlook.com`) for the requested period. This is the finest-grained deliverability view: where the mailbox-provider breakdown groups recipients into provider buckets such as `gmail` or `microsoft`, this keys on the exact destination domain. Use it to spot a delivery-rate dip or complaint spike at a specific domain.
|
|
2227
|
+
*
|
|
2228
|
+
* Rows are ranked by the `sort` metric (default `processed`) descending and capped at the requested `limit` (default 50, hard maximum 200). Rows are computed against event time (not send time), so engagement received during the period for messages sent earlier is included.
|
|
2229
|
+
*
|
|
2230
|
+
* The maximum window is 365 days; requesting a longer range returns 422.
|
|
2231
|
+
*
|
|
2232
|
+
*/
|
|
2233
|
+
const getEmailStatsByRecipientDomain = (options) => (options?.client ?? client).get({
|
|
2234
|
+
security: [{
|
|
2235
|
+
scheme: "bearer",
|
|
2236
|
+
type: "http"
|
|
2237
|
+
}, {
|
|
2238
|
+
in: "cookie",
|
|
2239
|
+
name: "bird_session",
|
|
2240
|
+
type: "apiKey"
|
|
2241
|
+
}],
|
|
2242
|
+
url: "/v1/email/stats/recipient-domains",
|
|
2243
|
+
...options
|
|
2244
|
+
});
|
|
2245
|
+
/**
|
|
2246
|
+
* Stats by template
|
|
2247
|
+
*
|
|
2248
|
+
* Returns aggregate delivery and engagement counts grouped by the template each message was sent with, so a template's deliverability and engagement can be compared side by side. Attribution is by the template used at send time; only messages sent with a template appear here, so a workspace that has sent none returns an empty list rather than an error. Each row is keyed by the template ID (`emt_…`); a template deleted after sending still appears by its ID.
|
|
2249
|
+
*
|
|
2250
|
+
* Rows are ranked by the `sort` metric (default `processed`) descending and capped at the requested `limit` (default 50, hard maximum 200). Rows are computed against event time (not send time), so engagement received during the period for messages sent earlier is included.
|
|
2251
|
+
*
|
|
2252
|
+
* The maximum window is 365 days; requesting a longer range returns 422.
|
|
2253
|
+
*
|
|
2254
|
+
*/
|
|
2255
|
+
const getEmailStatsByTemplate = (options) => (options?.client ?? client).get({
|
|
2256
|
+
security: [{
|
|
2257
|
+
scheme: "bearer",
|
|
2258
|
+
type: "http"
|
|
2259
|
+
}, {
|
|
2260
|
+
in: "cookie",
|
|
2261
|
+
name: "bird_session",
|
|
2262
|
+
type: "apiKey"
|
|
2263
|
+
}],
|
|
2264
|
+
url: "/v1/email/stats/templates",
|
|
2265
|
+
...options
|
|
2266
|
+
});
|
|
2267
|
+
/**
|
|
2268
|
+
* Engagement by location
|
|
2269
|
+
*
|
|
2270
|
+
* Returns engagement counts (opens and clicks) grouped by the location they were recorded from, for the requested period. Use it to see where your audience engages, for example the top countries by unique opens. Location is known from open and click events only, so rows carry engagement counts but no delivery counts or rates.
|
|
2271
|
+
*
|
|
2272
|
+
* Use `group_by` to choose the granularity: `country` (default), `region`, or `city`. Each row carries the location hierarchy down to the requested level (a `city` grouping also reports the row's region and country). Rows are ranked by the `sort` metric (default `unique_opens`) descending and capped at the requested `limit` (default 50, hard maximum 200).
|
|
2273
|
+
*
|
|
2274
|
+
* Rows are computed against event time (not send time). The maximum window is 365 days; requesting a longer range returns 422.
|
|
2275
|
+
*
|
|
2276
|
+
*/
|
|
2277
|
+
const getEmailStatsByLocation = (options) => (options?.client ?? client).get({
|
|
2278
|
+
security: [{
|
|
2279
|
+
scheme: "bearer",
|
|
2280
|
+
type: "http"
|
|
2281
|
+
}, {
|
|
2282
|
+
in: "cookie",
|
|
2283
|
+
name: "bird_session",
|
|
2284
|
+
type: "apiKey"
|
|
2285
|
+
}],
|
|
2286
|
+
url: "/v1/email/stats/locations",
|
|
2287
|
+
...options
|
|
2288
|
+
});
|
|
2289
|
+
/**
|
|
2290
|
+
* Engagement by email client
|
|
2291
|
+
*
|
|
2292
|
+
* Returns engagement counts (opens and clicks) grouped by the email client, operating system, or device type they were recorded from, for the requested period. Use it for the classic "opens by mail client" view, for example the share of opens from Apple Mail versus Gmail versus Outlook. The reading environment is known from open and click events only, so rows carry engagement counts but no delivery counts or rates.
|
|
2293
|
+
*
|
|
2294
|
+
* Use `group_by` to choose the facet: `email_client` (default), `os`, or `device_type`. Each row populates the chosen facet and leaves the other two null. Rows are ranked by the `sort` metric (default `unique_opens`) descending and capped at the requested `limit` (default 50, hard maximum 200).
|
|
2295
|
+
*
|
|
2296
|
+
* Rows are computed against event time (not send time). The maximum window is 365 days; requesting a longer range returns 422.
|
|
2297
|
+
*
|
|
2298
|
+
*/
|
|
2299
|
+
const getEmailStatsByClient = (options) => (options?.client ?? client).get({
|
|
2300
|
+
security: [{
|
|
2301
|
+
scheme: "bearer",
|
|
2302
|
+
type: "http"
|
|
2303
|
+
}, {
|
|
2304
|
+
in: "cookie",
|
|
2305
|
+
name: "bird_session",
|
|
2306
|
+
type: "apiKey"
|
|
2307
|
+
}],
|
|
2308
|
+
url: "/v1/email/stats/clients",
|
|
2309
|
+
...options
|
|
2310
|
+
});
|
|
2311
|
+
/**
|
|
2312
|
+
* Bounces by SMTP error code
|
|
2313
|
+
*
|
|
2314
|
+
* Returns bounce counts grouped by the SMTP error code the receiving mail server returned, for the requested period: the deliverability-debugging view that answers "which SMTP responses are driving my bounces". Each row reports the bounced recipients for one code plus the hard/soft/admin/block/undetermined split.
|
|
2315
|
+
*
|
|
2316
|
+
* This breakdown reports the failure side only: it has no delivered, open, click, or rate fields, because a bounce code is recorded only on bounce events.
|
|
2317
|
+
*
|
|
2318
|
+
* Rows are ranked by the `sort` metric (default `bounced`) descending, capped at the requested `limit` (default 50, hard maximum 200), and computed against event time (not send time). The maximum window is 365 days; requesting a longer range returns 422.
|
|
2319
|
+
*
|
|
2320
|
+
*/
|
|
2321
|
+
const getEmailStatsByBounceCode = (options) => (options?.client ?? client).get({
|
|
2322
|
+
security: [{
|
|
2323
|
+
scheme: "bearer",
|
|
2324
|
+
type: "http"
|
|
2325
|
+
}, {
|
|
2326
|
+
in: "cookie",
|
|
2327
|
+
name: "bird_session",
|
|
2328
|
+
type: "apiKey"
|
|
2329
|
+
}],
|
|
2330
|
+
url: "/v1/email/stats/bounce-codes",
|
|
2331
|
+
...options
|
|
2332
|
+
});
|
|
2333
|
+
/**
|
|
2334
|
+
* Complaints by type
|
|
2335
|
+
*
|
|
2336
|
+
* Returns spam-complaint counts grouped by the feedback-loop complaint type reported by the mailbox provider (for example `abuse`, `fraud`, `virus`), for the requested period. Use it to understand what kind of complaints your mail attracts.
|
|
2337
|
+
*
|
|
2338
|
+
* This breakdown reports the complaint side only: each row carries the complained count for one type and nothing else, because a complaint type is recorded only on spam-complaint events.
|
|
2339
|
+
*
|
|
2340
|
+
* Rows are ranked by `complained` descending, capped at the requested `limit` (default 50, hard maximum 200), and computed against event time (not send time). The maximum window is 365 days; requesting a longer range returns 422.
|
|
2341
|
+
*
|
|
2342
|
+
*/
|
|
2343
|
+
const getEmailStatsByComplaintType = (options) => (options?.client ?? client).get({
|
|
2344
|
+
security: [{
|
|
2345
|
+
scheme: "bearer",
|
|
2346
|
+
type: "http"
|
|
2347
|
+
}, {
|
|
2348
|
+
in: "cookie",
|
|
2349
|
+
name: "bird_session",
|
|
2350
|
+
type: "apiKey"
|
|
2351
|
+
}],
|
|
2352
|
+
url: "/v1/email/stats/complaint-types",
|
|
2353
|
+
...options
|
|
2354
|
+
});
|
|
2355
|
+
/**
|
|
2356
|
+
* Stats by broadcast
|
|
2357
|
+
*
|
|
2358
|
+
* Returns aggregate delivery and engagement counts grouped by broadcast for the requested period, so each broadcast's deliverability and engagement can be compared side by side. Only messages sent as part of a broadcast appear here; one-off and transactional sends are not included, so a workspace that has not sent broadcasts returns an empty list rather than an error.
|
|
2359
|
+
*
|
|
2360
|
+
* Rows are ranked by the `sort` metric (default `processed`) descending and capped at the requested `limit` (default 50, hard maximum 200). Rows are computed against event time (not send time), so engagement received during the period for messages sent earlier is included.
|
|
2361
|
+
*
|
|
2362
|
+
* The maximum window is 365 days; requesting a longer range returns 422. This breakdown is computed from per-message activity retained for 30 days, so it reflects roughly the last 30 days of activity even when the requested window reaches further back.
|
|
2363
|
+
*
|
|
2364
|
+
*/
|
|
2365
|
+
const getEmailStatsByBroadcast = (options) => (options?.client ?? client).get({
|
|
2366
|
+
security: [{
|
|
2367
|
+
scheme: "bearer",
|
|
2368
|
+
type: "http"
|
|
2369
|
+
}, {
|
|
2370
|
+
in: "cookie",
|
|
2371
|
+
name: "bird_session",
|
|
2372
|
+
type: "apiKey"
|
|
2373
|
+
}],
|
|
2374
|
+
url: "/v1/email/stats/broadcasts",
|
|
2375
|
+
...options
|
|
2376
|
+
});
|
|
2377
|
+
/**
|
|
1940
2378
|
* List sending domains
|
|
1941
2379
|
*
|
|
1942
|
-
* Returns all sending domains for the current workspace,
|
|
2380
|
+
* Returns all sending domains for the current workspace, newest first by default. Each item is the full domain object, including capability statuses and `dns_records`, so no per-domain follow-up read is needed. Filter with `name` to find a specific domain.
|
|
2381
|
+
*
|
|
1943
2382
|
*/
|
|
1944
2383
|
const listDomains = (options) => (options?.client ?? client).get({
|
|
1945
2384
|
security: [{
|
|
@@ -1956,7 +2395,20 @@ const listDomains = (options) => (options?.client ?? client).get({
|
|
|
1956
2395
|
/**
|
|
1957
2396
|
* Add a sending domain
|
|
1958
2397
|
*
|
|
1959
|
-
* Registers a new sending domain and returns the DNS records
|
|
2398
|
+
* Registers a new sending domain and returns the DNS records to publish
|
|
2399
|
+
* for it. The DKIM TXT record proves ownership, and together with the
|
|
2400
|
+
* return-path CNAME (which also covers SPF; no separate SPF record is
|
|
2401
|
+
* needed) and a DMARC policy it gates sending. The tracking CNAME is
|
|
2402
|
+
* optional and gates branded link tracking only. Publish the records at
|
|
2403
|
+
* your DNS provider, then check progress with
|
|
2404
|
+
* [Trigger domain verification](/docs/api/reference/verify-domain); Bird
|
|
2405
|
+
* also re-checks published records automatically. Setup walkthrough:
|
|
2406
|
+
* [Sending domains](/docs/guides/email/sending-domains).
|
|
2407
|
+
*
|
|
2408
|
+
* The domain starts in `pending` status. A domain already registered in
|
|
2409
|
+
* this workspace returns `409`, and creation beyond your organization's
|
|
2410
|
+
* domain quota returns `422` `E10000`. A domain that never verifies
|
|
2411
|
+
* ownership is removed after about 14 days, with a reminder email first.
|
|
1960
2412
|
*
|
|
1961
2413
|
*/
|
|
1962
2414
|
const createDomain = (options) => (options.client ?? client).post({
|
|
@@ -1996,7 +2448,8 @@ const deleteDomain = (options) => (options.client ?? client).delete({
|
|
|
1996
2448
|
/**
|
|
1997
2449
|
* Get a sending domain
|
|
1998
2450
|
*
|
|
1999
|
-
* Returns the domain with
|
|
2451
|
+
* Returns the domain with its capability statuses and every DNS record's current verification state. This read reports the stored result of the last check; to run a fresh DNS check, use [Trigger domain verification](/docs/api/reference/verify-domain).
|
|
2452
|
+
*
|
|
2000
2453
|
*/
|
|
2001
2454
|
const getDomain = (options) => (options.client ?? client).get({
|
|
2002
2455
|
security: [{
|
|
@@ -2013,7 +2466,18 @@ const getDomain = (options) => (options.client ?? client).get({
|
|
|
2013
2466
|
/**
|
|
2014
2467
|
* Update a sending domain
|
|
2015
2468
|
*
|
|
2016
|
-
* Updates settings and configuration on a sending domain. `settings`
|
|
2469
|
+
* Updates settings and configuration on a sending domain. `settings`
|
|
2470
|
+
* changes apply immediately. Changes to `return_path`, `tracking`, or
|
|
2471
|
+
* `dkim` on a verified capability are staged: the current configuration
|
|
2472
|
+
* keeps serving until the new one's DNS records verify, then the change
|
|
2473
|
+
* is promoted automatically. Staged values are visible under
|
|
2474
|
+
* `capabilities.*.pending`; the records to publish appear in
|
|
2475
|
+
* `dns_records` with `state: pending`.
|
|
2476
|
+
*
|
|
2477
|
+
* Invalid combinations are rejected: enabling tracking toggles without a
|
|
2478
|
+
* tracking domain, or removing the tracking domain while a toggle is on,
|
|
2479
|
+
* returns `409`; enabling inbound receiving has verification
|
|
2480
|
+
* prerequisites that return `422`. Each rule is detailed on its field.
|
|
2017
2481
|
*
|
|
2018
2482
|
*/
|
|
2019
2483
|
const updateDomain = (options) => (options.client ?? client).patch({
|
|
@@ -2035,7 +2499,17 @@ const updateDomain = (options) => (options.client ?? client).patch({
|
|
|
2035
2499
|
/**
|
|
2036
2500
|
* Trigger domain verification
|
|
2037
2501
|
*
|
|
2038
|
-
*
|
|
2502
|
+
* Runs a fresh DNS check across the domain's records (DKIM, return path,
|
|
2503
|
+
* DMARC, tracking, inbound MX, and any staged changes) and returns the
|
|
2504
|
+
* updated domain. Use it for an immediate result after publishing or
|
|
2505
|
+
* correcting records; [Get a sending domain](/docs/api/reference/get-domain)
|
|
2506
|
+
* only reports the last stored result, and Bird re-checks published
|
|
2507
|
+
* records automatically in the background.
|
|
2508
|
+
*
|
|
2509
|
+
* A `200` with records still `pending` is not a failure: the records were
|
|
2510
|
+
* not found yet, which is normal while DNS propagates (minutes to hours).
|
|
2511
|
+
* Recently verified records are not re-queried, so the call is safe to
|
|
2512
|
+
* repeat while you wait.
|
|
2039
2513
|
*
|
|
2040
2514
|
*/
|
|
2041
2515
|
const verifyDomain = (options) => (options.client ?? client).post({
|
|
@@ -2090,12 +2564,319 @@ function mergeHeaders(idempotencyKey, extra) {
|
|
|
2090
2564
|
};
|
|
2091
2565
|
}
|
|
2092
2566
|
//#endregion
|
|
2567
|
+
//#region src/resources/emailStats.ts
|
|
2568
|
+
/**
|
|
2569
|
+
* `bird.email.stats` — read-only email statistics. Every method takes an
|
|
2570
|
+
* optional query object (window, timezone, and — for breakdowns — `limit` and
|
|
2571
|
+
* `sort`) and resolves the typed aggregate or breakdown for that window. These
|
|
2572
|
+
* are point reads, not cursor lists, so each returns an `APIPromise`, not a
|
|
2573
|
+
* paginated iterator. Reached as `bird.email.stats.*`.
|
|
2574
|
+
*/
|
|
2575
|
+
var EmailStatsResource = class extends Resource {
|
|
2576
|
+
/**
|
|
2577
|
+
* Aggregate delivery, engagement, and latency for a window. Pass
|
|
2578
|
+
* `compare: "previous_period"` to also get the preceding window and the
|
|
2579
|
+
* change between the two.
|
|
2580
|
+
*
|
|
2581
|
+
* @example Summary for a month
|
|
2582
|
+
* const s = await bird.email.stats.summary({ from: "2026-05-01", to: "2026-05-31" });
|
|
2583
|
+
* console.log(s.sends_accepted, s.delivery.delivered);
|
|
2584
|
+
*/
|
|
2585
|
+
summary(query, options) {
|
|
2586
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsSummary({
|
|
2587
|
+
client: this.client,
|
|
2588
|
+
query,
|
|
2589
|
+
headers,
|
|
2590
|
+
signal
|
|
2591
|
+
}));
|
|
2592
|
+
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Daily time series — one row per calendar day in the window.
|
|
2595
|
+
*
|
|
2596
|
+
* @example Per-day series for a month
|
|
2597
|
+
* const series = await bird.email.stats.daily({ from: "2026-05-01", to: "2026-05-31" });
|
|
2598
|
+
* for (const row of series.data) console.log(row.bucket, row.delivery.delivered);
|
|
2599
|
+
*/
|
|
2600
|
+
daily(query, options) {
|
|
2601
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsDaily({
|
|
2602
|
+
client: this.client,
|
|
2603
|
+
query,
|
|
2604
|
+
headers,
|
|
2605
|
+
signal
|
|
2606
|
+
}));
|
|
2607
|
+
}
|
|
2608
|
+
/**
|
|
2609
|
+
* Hourly time series — one row per hour in the window (max 720 hours).
|
|
2610
|
+
*
|
|
2611
|
+
* @example Per-hour series for a day
|
|
2612
|
+
* const series = await bird.email.stats.hourly({ from: "2026-05-01", to: "2026-05-02" });
|
|
2613
|
+
* for (const row of series.data) console.log(row.bucket, row.delivery.delivered);
|
|
2614
|
+
*/
|
|
2615
|
+
hourly(query, options) {
|
|
2616
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsHourly({
|
|
2617
|
+
client: this.client,
|
|
2618
|
+
query,
|
|
2619
|
+
headers,
|
|
2620
|
+
signal
|
|
2621
|
+
}));
|
|
2622
|
+
}
|
|
2623
|
+
/**
|
|
2624
|
+
* Breakdown by tag, ranked by `sort` (default `processed`) descending.
|
|
2625
|
+
*
|
|
2626
|
+
* @example Top 10 tags by delivered
|
|
2627
|
+
* const { data } = await bird.email.stats.byTag({
|
|
2628
|
+
* from: "2026-05-01",
|
|
2629
|
+
* to: "2026-05-31",
|
|
2630
|
+
* sort: "delivered",
|
|
2631
|
+
* limit: 10,
|
|
2632
|
+
* });
|
|
2633
|
+
* for (const row of data) console.log(row.tag, row.delivery.delivered);
|
|
2634
|
+
*/
|
|
2635
|
+
byTag(query, options) {
|
|
2636
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByTag({
|
|
2637
|
+
client: this.client,
|
|
2638
|
+
query,
|
|
2639
|
+
headers,
|
|
2640
|
+
signal
|
|
2641
|
+
}));
|
|
2642
|
+
}
|
|
2643
|
+
/**
|
|
2644
|
+
* Breakdown by category (`transactional` / `marketing`).
|
|
2645
|
+
*
|
|
2646
|
+
* @example By category for a month
|
|
2647
|
+
* const { data } = await bird.email.stats.byCategory({ from: "2026-05-01", to: "2026-05-31" });
|
|
2648
|
+
* for (const row of data) console.log(row.category, row.delivery.delivered);
|
|
2649
|
+
*/
|
|
2650
|
+
byCategory(query, options) {
|
|
2651
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByCategory({
|
|
2652
|
+
client: this.client,
|
|
2653
|
+
query,
|
|
2654
|
+
headers,
|
|
2655
|
+
signal
|
|
2656
|
+
}));
|
|
2657
|
+
}
|
|
2658
|
+
/**
|
|
2659
|
+
* Breakdown by sending IP, ranked by `sort` (default `delivered`) descending.
|
|
2660
|
+
*
|
|
2661
|
+
* @example IPs with the most block bounces
|
|
2662
|
+
* const { data } = await bird.email.stats.bySendingIp({
|
|
2663
|
+
* from: "2026-05-01",
|
|
2664
|
+
* to: "2026-05-31",
|
|
2665
|
+
* sort: "bounces.block",
|
|
2666
|
+
* limit: 20,
|
|
2667
|
+
* });
|
|
2668
|
+
* for (const row of data) console.log(row.sending_ip, row.delivery.delivered);
|
|
2669
|
+
*/
|
|
2670
|
+
bySendingIp(query, options) {
|
|
2671
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsBySendingIp({
|
|
2672
|
+
client: this.client,
|
|
2673
|
+
query,
|
|
2674
|
+
headers,
|
|
2675
|
+
signal
|
|
2676
|
+
}));
|
|
2677
|
+
}
|
|
2678
|
+
/**
|
|
2679
|
+
* Breakdown by sending domain.
|
|
2680
|
+
*
|
|
2681
|
+
* @example By sending domain
|
|
2682
|
+
* const { data } = await bird.email.stats.bySendingDomain({
|
|
2683
|
+
* from: "2026-05-01",
|
|
2684
|
+
* to: "2026-05-31",
|
|
2685
|
+
* sort: "delivery_rate",
|
|
2686
|
+
* limit: 25,
|
|
2687
|
+
* });
|
|
2688
|
+
* for (const row of data) console.log(row.sending_domain, row.delivery.delivery_rate);
|
|
2689
|
+
*/
|
|
2690
|
+
bySendingDomain(query, options) {
|
|
2691
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsBySendingDomain({
|
|
2692
|
+
client: this.client,
|
|
2693
|
+
query,
|
|
2694
|
+
headers,
|
|
2695
|
+
signal
|
|
2696
|
+
}));
|
|
2697
|
+
}
|
|
2698
|
+
/**
|
|
2699
|
+
* Breakdown by recipient mailbox domain (e.g. `gmail.com`).
|
|
2700
|
+
*
|
|
2701
|
+
* @example Recipient domains with the highest bounce rate
|
|
2702
|
+
* const { data } = await bird.email.stats.byRecipientDomain({
|
|
2703
|
+
* from: "2026-05-01",
|
|
2704
|
+
* to: "2026-05-31",
|
|
2705
|
+
* sort: "bounce_rate",
|
|
2706
|
+
* limit: 25,
|
|
2707
|
+
* });
|
|
2708
|
+
* for (const row of data) console.log(row.recipient_domain, row.delivery.bounce_rate);
|
|
2709
|
+
*/
|
|
2710
|
+
byRecipientDomain(query, options) {
|
|
2711
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByRecipientDomain({
|
|
2712
|
+
client: this.client,
|
|
2713
|
+
query,
|
|
2714
|
+
headers,
|
|
2715
|
+
signal
|
|
2716
|
+
}));
|
|
2717
|
+
}
|
|
2718
|
+
/**
|
|
2719
|
+
* Breakdown by mailbox provider (e.g. Google, Microsoft).
|
|
2720
|
+
*
|
|
2721
|
+
* @example By mailbox provider
|
|
2722
|
+
* const { data } = await bird.email.stats.byMailboxProvider({
|
|
2723
|
+
* from: "2026-05-01",
|
|
2724
|
+
* to: "2026-05-31",
|
|
2725
|
+
* limit: 25,
|
|
2726
|
+
* });
|
|
2727
|
+
* for (const row of data) console.log(row.mailbox_provider, row.delivery.delivered);
|
|
2728
|
+
*/
|
|
2729
|
+
byMailboxProvider(query, options) {
|
|
2730
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByMailboxProvider({
|
|
2731
|
+
client: this.client,
|
|
2732
|
+
query,
|
|
2733
|
+
headers,
|
|
2734
|
+
signal
|
|
2735
|
+
}));
|
|
2736
|
+
}
|
|
2737
|
+
/**
|
|
2738
|
+
* Breakdown by mailbox provider and region.
|
|
2739
|
+
*
|
|
2740
|
+
* @example By mailbox provider and region
|
|
2741
|
+
* const { data } = await bird.email.stats.byMailboxProviderRegion({
|
|
2742
|
+
* from: "2026-05-01",
|
|
2743
|
+
* to: "2026-05-31",
|
|
2744
|
+
* limit: 25,
|
|
2745
|
+
* });
|
|
2746
|
+
* for (const row of data) console.log(row.mailbox_provider, row.mailbox_provider_region, row.delivery.delivered);
|
|
2747
|
+
*/
|
|
2748
|
+
byMailboxProviderRegion(query, options) {
|
|
2749
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByMailboxProviderRegion({
|
|
2750
|
+
client: this.client,
|
|
2751
|
+
query,
|
|
2752
|
+
headers,
|
|
2753
|
+
signal
|
|
2754
|
+
}));
|
|
2755
|
+
}
|
|
2756
|
+
/**
|
|
2757
|
+
* Breakdown by template (by `emt_…` ID or name).
|
|
2758
|
+
*
|
|
2759
|
+
* @example By template
|
|
2760
|
+
* const { data } = await bird.email.stats.byTemplate({
|
|
2761
|
+
* from: "2026-05-01",
|
|
2762
|
+
* to: "2026-05-31",
|
|
2763
|
+
* sort: "open_rate",
|
|
2764
|
+
* limit: 25,
|
|
2765
|
+
* });
|
|
2766
|
+
* for (const row of data) console.log(row.template_id, row.engagement.open_rate);
|
|
2767
|
+
*/
|
|
2768
|
+
byTemplate(query, options) {
|
|
2769
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByTemplate({
|
|
2770
|
+
client: this.client,
|
|
2771
|
+
query,
|
|
2772
|
+
headers,
|
|
2773
|
+
signal
|
|
2774
|
+
}));
|
|
2775
|
+
}
|
|
2776
|
+
/**
|
|
2777
|
+
* Breakdown by recipient geographic location.
|
|
2778
|
+
*
|
|
2779
|
+
* @example By location
|
|
2780
|
+
* const { data } = await bird.email.stats.byLocation({
|
|
2781
|
+
* from: "2026-05-01",
|
|
2782
|
+
* to: "2026-05-31",
|
|
2783
|
+
* limit: 25,
|
|
2784
|
+
* });
|
|
2785
|
+
* for (const row of data) console.log(row.country, row.engagement.unique_opens);
|
|
2786
|
+
*/
|
|
2787
|
+
byLocation(query, options) {
|
|
2788
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByLocation({
|
|
2789
|
+
client: this.client,
|
|
2790
|
+
query,
|
|
2791
|
+
headers,
|
|
2792
|
+
signal
|
|
2793
|
+
}));
|
|
2794
|
+
}
|
|
2795
|
+
/**
|
|
2796
|
+
* Breakdown by opening client (the application that opened the message).
|
|
2797
|
+
*
|
|
2798
|
+
* @example By client
|
|
2799
|
+
* const { data } = await bird.email.stats.byClient({
|
|
2800
|
+
* from: "2026-05-01",
|
|
2801
|
+
* to: "2026-05-31",
|
|
2802
|
+
* limit: 25,
|
|
2803
|
+
* });
|
|
2804
|
+
* for (const row of data) console.log(row.email_client, row.engagement.unique_opens);
|
|
2805
|
+
*/
|
|
2806
|
+
byClient(query, options) {
|
|
2807
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByClient({
|
|
2808
|
+
client: this.client,
|
|
2809
|
+
query,
|
|
2810
|
+
headers,
|
|
2811
|
+
signal
|
|
2812
|
+
}));
|
|
2813
|
+
}
|
|
2814
|
+
/**
|
|
2815
|
+
* Breakdown by bounce code — which SMTP/enhanced codes drove bounces.
|
|
2816
|
+
*
|
|
2817
|
+
* @example By bounce code
|
|
2818
|
+
* const { data } = await bird.email.stats.byBounceCode({
|
|
2819
|
+
* from: "2026-05-01",
|
|
2820
|
+
* to: "2026-05-31",
|
|
2821
|
+
* sort: "bounced",
|
|
2822
|
+
* limit: 25,
|
|
2823
|
+
* });
|
|
2824
|
+
* for (const row of data) console.log(row.smtp_error_code, row.bounced);
|
|
2825
|
+
*/
|
|
2826
|
+
byBounceCode(query, options) {
|
|
2827
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByBounceCode({
|
|
2828
|
+
client: this.client,
|
|
2829
|
+
query,
|
|
2830
|
+
headers,
|
|
2831
|
+
signal
|
|
2832
|
+
}));
|
|
2833
|
+
}
|
|
2834
|
+
/**
|
|
2835
|
+
* Breakdown by complaint type.
|
|
2836
|
+
*
|
|
2837
|
+
* @example By complaint type
|
|
2838
|
+
* const { data } = await bird.email.stats.byComplaintType({ from: "2026-05-01", to: "2026-05-31" });
|
|
2839
|
+
* for (const row of data) console.log(row.feedback_type, row.complained);
|
|
2840
|
+
*/
|
|
2841
|
+
byComplaintType(query, options) {
|
|
2842
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByComplaintType({
|
|
2843
|
+
client: this.client,
|
|
2844
|
+
query,
|
|
2845
|
+
headers,
|
|
2846
|
+
signal
|
|
2847
|
+
}));
|
|
2848
|
+
}
|
|
2849
|
+
/**
|
|
2850
|
+
* Breakdown by broadcast.
|
|
2851
|
+
*
|
|
2852
|
+
* @example By broadcast
|
|
2853
|
+
* const { data } = await bird.email.stats.byBroadcast({
|
|
2854
|
+
* from: "2026-05-01",
|
|
2855
|
+
* to: "2026-05-31",
|
|
2856
|
+
* sort: "click_rate",
|
|
2857
|
+
* limit: 25,
|
|
2858
|
+
* });
|
|
2859
|
+
* for (const row of data) console.log(row.broadcast_id, row.engagement.click_rate);
|
|
2860
|
+
*/
|
|
2861
|
+
byBroadcast(query, options) {
|
|
2862
|
+
return this.call("GET", options, ({ signal, headers }) => getEmailStatsByBroadcast({
|
|
2863
|
+
client: this.client,
|
|
2864
|
+
query,
|
|
2865
|
+
headers,
|
|
2866
|
+
signal
|
|
2867
|
+
}));
|
|
2868
|
+
}
|
|
2869
|
+
};
|
|
2870
|
+
//#endregion
|
|
2093
2871
|
//#region src/resources/email.ts
|
|
2094
2872
|
var EmailResource = class extends Resource {
|
|
2095
2873
|
#defaults;
|
|
2874
|
+
/** Email statistics — `bird.email.stats.summary(...)`, `.daily(...)`, `.byTag(...)`, … */
|
|
2875
|
+
stats;
|
|
2096
2876
|
constructor(core, client, defaults) {
|
|
2097
2877
|
super(core, client);
|
|
2098
2878
|
this.#defaults = defaults;
|
|
2879
|
+
this.stats = new EmailStatsResource(core, client);
|
|
2099
2880
|
}
|
|
2100
2881
|
/**
|
|
2101
2882
|
* Send an email message. Resolves once the message is accepted for delivery
|
|
@@ -2737,7 +3518,8 @@ var SmsResource = class extends Resource {
|
|
|
2737
3518
|
*
|
|
2738
3519
|
* @example Send free text
|
|
2739
3520
|
* const msg = await bird.sms.send({
|
|
2740
|
-
*
|
|
3521
|
+
* from: "MyBrand",
|
|
3522
|
+
* to: "+14155550100",
|
|
2741
3523
|
* text: "Your verification code is 123456.",
|
|
2742
3524
|
* category: "authentication",
|
|
2743
3525
|
* });
|
|
@@ -2745,7 +3527,7 @@ var SmsResource = class extends Resource {
|
|
|
2745
3527
|
*
|
|
2746
3528
|
* @example Send by template
|
|
2747
3529
|
* await bird.sms.send({
|
|
2748
|
-
* to: "+
|
|
3530
|
+
* to: "+14155550100",
|
|
2749
3531
|
* template: { name: "bird_otp_verification", parameters: { code: "123456" } },
|
|
2750
3532
|
* });
|
|
2751
3533
|
*/
|
|
@@ -3032,19 +3814,19 @@ var WebhooksResource = class {
|
|
|
3032
3814
|
* @example One call verifies the signature and returns the typed event
|
|
3033
3815
|
* // Pass the RAW request body; set the secret via new BirdClient({ webhooks: { secret } }).
|
|
3034
3816
|
* const event = bird.webhooks.unwrap(rawBody, headers);
|
|
3035
|
-
* console.log(event.type); // discriminated union
|
|
3817
|
+
* console.log(event.type); // discriminated union: narrow on event.type
|
|
3036
3818
|
*
|
|
3037
|
-
* @example Verify and dispatch
|
|
3819
|
+
* @example Verify and dispatch: pass the raw request body, never the parsed JSON
|
|
3038
3820
|
* // new BirdClient({ apiKey, webhooks: { secret } })
|
|
3039
3821
|
* try {
|
|
3040
3822
|
* const event = bird.webhooks.unwrap(rawBody, req.headers);
|
|
3041
3823
|
* switch (event.type) {
|
|
3042
3824
|
* case "email.delivered":
|
|
3043
|
-
* markDelivered(event.email_id, event.recipient); // narrowed
|
|
3825
|
+
* markDelivered(event.data.email_id, event.data.recipient); // narrowed by event.type
|
|
3044
3826
|
* break;
|
|
3045
3827
|
* case "email.bounced":
|
|
3046
3828
|
* case "email.complained":
|
|
3047
|
-
* suppress(event.recipient);
|
|
3829
|
+
* suppress(event.data.recipient);
|
|
3048
3830
|
* break;
|
|
3049
3831
|
* default: // unknown future event types — an older SDK won't break on a new one
|
|
3050
3832
|
* }
|
|
@@ -3153,9 +3935,9 @@ var BirdClient = class {
|
|
|
3153
3935
|
this.#headers = {
|
|
3154
3936
|
...opts.defaultHeaders,
|
|
3155
3937
|
Authorization: `Bearer ${opts.apiKey}`,
|
|
3156
|
-
"User-Agent": `bird-sdk-js/0.
|
|
3938
|
+
"User-Agent": `bird-sdk-js/0.10.0`,
|
|
3157
3939
|
"Bird-Surface": "sdk-js",
|
|
3158
|
-
"Bird-Version": "0.
|
|
3940
|
+
"Bird-Version": "0.10.0"
|
|
3159
3941
|
};
|
|
3160
3942
|
const caller = detectCaller();
|
|
3161
3943
|
if (caller) this.#headers["Bird-Caller"] = caller;
|
|
@@ -3265,14 +4047,18 @@ const WebhookEventType = {
|
|
|
3265
4047
|
RealtimeCacheChannels: "realtime.cache_channels",
|
|
3266
4048
|
RealtimeChannelExistence: "realtime.channel_existence",
|
|
3267
4049
|
RealtimeClientEvents: "realtime.client_events",
|
|
4050
|
+
RealtimeConnectionCount: "realtime.connection_count",
|
|
3268
4051
|
RealtimePresence: "realtime.presence",
|
|
3269
|
-
RealtimeSubscriptionCount: "realtime.subscription_count",
|
|
3270
4052
|
SmsAccepted: "sms.accepted",
|
|
3271
4053
|
SmsDelivered: "sms.delivered",
|
|
3272
4054
|
SmsExpired: "sms.expired",
|
|
3273
4055
|
SmsFailed: "sms.failed",
|
|
3274
4056
|
SmsRejected: "sms.rejected",
|
|
3275
4057
|
SmsSent: "sms.sent",
|
|
4058
|
+
SmsTfnVerificationApproved: "sms.tfn_verification.approved",
|
|
4059
|
+
SmsTfnVerificationInfoRequested: "sms.tfn_verification.info_requested",
|
|
4060
|
+
SmsTfnVerificationRejected: "sms.tfn_verification.rejected",
|
|
4061
|
+
SmsTfnVerificationSubmitted: "sms.tfn_verification.submitted",
|
|
3276
4062
|
SmsUndelivered: "sms.undelivered",
|
|
3277
4063
|
VoiceCallAnswered: "voice.call.answered",
|
|
3278
4064
|
VoiceCallEnded: "voice.call.ended",
|