@messagebird/sdk 0.12.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -907,7 +907,7 @@ var BirdNotImplementedError = class extends BirdAPIError {
907
907
  Object.setPrototypeOf(this, new.target.prototype);
908
908
  }
909
909
  };
910
- /** 421 — request reached the wrong region (ADR-0036). */
910
+ /** 421 — request reached the wrong region. */
911
911
  var BirdMisdirectedError = class extends BirdAPIError {
912
912
  constructor(fields) {
913
913
  super(fields);
@@ -1183,6 +1183,116 @@ const client = createClient(createConfig());
1183
1183
  //#endregion
1184
1184
  //#region src/generated/sdk.gen.ts
1185
1185
  /**
1186
+ * Publish a Realtime event
1187
+ *
1188
+ * Publishes an event to one or more channels of a Realtime app. Listing several channels broadcasts the event to all of them in one call. Connected clients subscribed to those channels receive it in real time.
1189
+ */
1190
+ const publishRealtimeAppEvent = (options) => (options.client ?? client).post({
1191
+ security: [{
1192
+ scheme: "bearer",
1193
+ type: "http"
1194
+ }, {
1195
+ in: "cookie",
1196
+ name: "bird_session",
1197
+ type: "apiKey"
1198
+ }],
1199
+ url: "/v1/realtime/apps/{realtime_app_id}/events",
1200
+ ...options,
1201
+ headers: {
1202
+ "Content-Type": "application/json",
1203
+ ...options.headers
1204
+ }
1205
+ });
1206
+ /**
1207
+ * Publish a batch of Realtime events
1208
+ *
1209
+ * Publishes up to 10 events (each to one channel) in a single request.
1210
+ */
1211
+ const publishRealtimeAppBatch = (options) => (options.client ?? client).post({
1212
+ security: [{
1213
+ scheme: "bearer",
1214
+ type: "http"
1215
+ }, {
1216
+ in: "cookie",
1217
+ name: "bird_session",
1218
+ type: "apiKey"
1219
+ }],
1220
+ url: "/v1/realtime/apps/{realtime_app_id}/batch-events",
1221
+ ...options,
1222
+ headers: {
1223
+ "Content-Type": "application/json",
1224
+ ...options.headers
1225
+ }
1226
+ });
1227
+ /**
1228
+ * List Realtime channels
1229
+ *
1230
+ * Lists the app's currently occupied channels, optionally filtered by name prefix.
1231
+ */
1232
+ const listRealtimeAppChannels = (options) => (options.client ?? client).get({
1233
+ security: [{
1234
+ scheme: "bearer",
1235
+ type: "http"
1236
+ }, {
1237
+ in: "cookie",
1238
+ name: "bird_session",
1239
+ type: "apiKey"
1240
+ }],
1241
+ url: "/v1/realtime/apps/{realtime_app_id}/channels",
1242
+ ...options
1243
+ });
1244
+ /**
1245
+ * Get a Realtime channel
1246
+ *
1247
+ * Returns a single channel's occupancy and (on request) counts. Channels exist implicitly — a channel appears when the first connection subscribes and vanishes when the last one leaves — so this endpoint reports state, not existence: an unknown or never-used name returns 200 with `occupied: false`, never 404.
1248
+ */
1249
+ const getRealtimeAppChannel = (options) => (options.client ?? client).get({
1250
+ security: [{
1251
+ scheme: "bearer",
1252
+ type: "http"
1253
+ }, {
1254
+ in: "cookie",
1255
+ name: "bird_session",
1256
+ type: "apiKey"
1257
+ }],
1258
+ url: "/v1/realtime/apps/{realtime_app_id}/channels/{channel_name}",
1259
+ ...options
1260
+ });
1261
+ /**
1262
+ * List members on a presence channel
1263
+ *
1264
+ * Lists the member ids currently subscribed to a presence channel. Ids only: `member_info` (the profile data attached by your authorization endpoint) is delivered to subscribed clients over the realtime connection and is not available over REST.
1265
+ */
1266
+ const listRealtimeAppChannelMembers = (options) => (options.client ?? client).get({
1267
+ security: [{
1268
+ scheme: "bearer",
1269
+ type: "http"
1270
+ }, {
1271
+ in: "cookie",
1272
+ name: "bird_session",
1273
+ type: "apiKey"
1274
+ }],
1275
+ url: "/v1/realtime/apps/{realtime_app_id}/channels/{channel_name}/members",
1276
+ ...options
1277
+ });
1278
+ /**
1279
+ * Disconnect a member
1280
+ *
1281
+ * Disconnects all of a member's active connections (e.g. on sign-out or ban).
1282
+ */
1283
+ const disconnectRealtimeAppMember = (options) => (options.client ?? client).post({
1284
+ security: [{
1285
+ scheme: "bearer",
1286
+ type: "http"
1287
+ }, {
1288
+ in: "cookie",
1289
+ name: "bird_session",
1290
+ type: "apiKey"
1291
+ }],
1292
+ url: "/v1/realtime/apps/{realtime_app_id}/members/{member_id}/disconnect",
1293
+ ...options
1294
+ });
1295
+ /**
1186
1296
  * List messages
1187
1297
  *
1188
1298
  * 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.
@@ -1937,8 +2047,7 @@ const listWhatsAppMessages = (options) => (options?.client ?? client).get({
1937
2047
  * placeholders in `components`; Bird selects the sender number from the
1938
2048
  * template's category, so the request carries no sender field. Templates are
1939
2049
  * 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).
2050
+ * with a `422`. Browse your workspace's templates in the Bird dashboard.
1942
2051
  *
1943
2052
  * The `202` response is the accepted message, echoing the resolved template
1944
2053
  * and language; it is not a delivery confirmation. Follow delivery with
@@ -2005,24 +2114,6 @@ const listWhatsAppMessageEvents = (options) => (options.client ?? client).get({
2005
2114
  ...options
2006
2115
  });
2007
2116
  /**
2008
- * List available message templates
2009
- *
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
- *
2012
- */
2013
- const listWhatsAppTemplates = (options) => (options?.client ?? client).get({
2014
- security: [{
2015
- scheme: "bearer",
2016
- type: "http"
2017
- }, {
2018
- in: "cookie",
2019
- name: "bird_session",
2020
- type: "apiKey"
2021
- }],
2022
- url: "/v1/whatsapp/templates",
2023
- ...options
2024
- });
2025
- /**
2026
2117
  * Daily sending statistics
2027
2118
  *
2028
2119
  * 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.
@@ -2986,6 +3077,60 @@ function mergeHeaders(idempotencyKey, extra) {
2986
3077
  };
2987
3078
  }
2988
3079
  //#endregion
3080
+ //#region src/resources/email.gen.ts
3081
+ var EmailResourceBase = class extends Resource {
3082
+ /**
3083
+ * Fetch one email message by id — aggregate delivery status and per-state recipient counts. The message body (html, text) is not returned. Per-recipient delivery statuses and the event log are separate sub-resources: GET /v1/email/messages/{message_id}/recipients and GET /v1/email/messages/{message_id}/events.
3084
+ *
3085
+ * @example
3086
+ * const msg = await bird.email.get("em_abc123");
3087
+ * msg.status; // "accepted" | "processed" | "delivered" | "bounced" | …
3088
+ * msg.delivered_count;
3089
+ * msg.bounced_count;
3090
+ */
3091
+ get(messageId, options) {
3092
+ return this.call("GET", options, ({ signal, headers }) => getEmailMessage({
3093
+ client: this.client,
3094
+ path: { message_id: messageId },
3095
+ headers,
3096
+ signal
3097
+ }));
3098
+ }
3099
+ /**
3100
+ * List sent email messages, newest first, as a cursor page ({data, next_cursor, …}). Pass next_cursor back as starting_after to fetch the next page. Filter by creation time with the half-open range created_after (inclusive) / created_before (exclusive) — e.g. for a single UTC day set created_after to that day at 00:00:00Z and created_before to the next day at 00:00:00Z.
3101
+ *
3102
+ * @example
3103
+ * for await (const message of bird.email.list({ status: "bounced" })) {
3104
+ * console.log(message.id);
3105
+ * }
3106
+ */
3107
+ list(query, options) {
3108
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listEmailMessages({
3109
+ client: this.client,
3110
+ query: {
3111
+ ...query,
3112
+ starting_after: cursor ?? query?.starting_after
3113
+ },
3114
+ headers,
3115
+ signal
3116
+ }));
3117
+ }
3118
+ /**
3119
+ * Cancel a scheduled email before it sends. Only works while the message is still scheduled (status `scheduled`); once it starts sending — or was already canceled — the call returns a conflict error. Canceling does not return consumed scheduled-send quota.
3120
+ *
3121
+ * @example
3122
+ * await bird.email.cancel("em_abc123");
3123
+ */
3124
+ cancel(messageId, options) {
3125
+ return this.call("POST", options, ({ signal, headers }) => cancelEmailMessage({
3126
+ client: this.client,
3127
+ path: { message_id: messageId },
3128
+ headers,
3129
+ signal
3130
+ }));
3131
+ }
3132
+ };
3133
+ //#endregion
2989
3134
  //#region src/resources/emailStats.gen.ts
2990
3135
  var EmailStatsResource = class extends Resource {
2991
3136
  /**
@@ -3281,275 +3426,186 @@ var EmailStatsResource = class extends Resource {
3281
3426
  }
3282
3427
  };
3283
3428
  //#endregion
3284
- //#region src/resources/email.ts
3285
- var EmailResource = class extends Resource {
3286
- #defaults;
3287
- /** Email statistics — `bird.email.stats.summary(...)`, `.daily(...)`, `.byTag(...)`, … */
3288
- stats;
3289
- constructor(core, client, defaults) {
3290
- super(core, client);
3291
- this.#defaults = defaults;
3292
- this.stats = new EmailStatsResource(core, client);
3293
- }
3429
+ //#region src/resources/emailMailboxes.gen.ts
3430
+ var EmailMailboxesResource$1 = class extends Resource {
3294
3431
  /**
3295
- * Send an email message. Resolves once the message is accepted for delivery
3296
- * (the API's 202). Throws on failure — a 422 (unverified sender, all
3297
- * recipients suppressed, validation) is a `BirdValidationError`. Fields set as
3298
- * channel defaults may be omitted (per-send value wins).
3299
- *
3300
- * @example Send a message
3301
- * const msg = await bird.email.send({
3302
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3303
- * to: ["delivered@messagebird.dev"],
3304
- * subject: "Hello from Bird",
3305
- * html: "<p>My first Bird email.</p>",
3306
- * });
3307
- * console.log(msg.id, msg.status); // "em_…", "accepted"
3308
- *
3309
- * @example A richer send — cc/bcc, reply-to, tags, metadata, click-tracking off, and an idempotency key (safe to retry; the server dedupes)
3310
- * await bird.email.send(
3311
- * {
3312
- * from: "hello@acme.com",
3313
- * to: ["a@example.com", "b@example.com"],
3314
- * cc: ["manager@example.com"],
3315
- * reply_to: ["support@acme.com"],
3316
- * subject: "Your March invoice",
3317
- * html: "<p>Attached.</p>",
3318
- * tags: [{ name: "category", value: "billing" }],
3319
- * metadata: { invoice_id: "inv_123" },
3320
- * track_clicks: false,
3321
- * },
3322
- * { idempotencyKey: "invoice-march/cust_1" },
3323
- * );
3324
- *
3325
- * @example Branch on the typed error hierarchy
3326
- * import { BirdRateLimitError, BirdValidationError, BirdAPIError } from "@messagebird/sdk";
3432
+ * List the workspace's mailboxes as a cursor page, newest first. Search addresses and display names with q, or filter by exact address, state, or domain.
3327
3433
  *
3328
- * try {
3329
- * await bird.email.send({
3330
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3331
- * to: ["delivered@messagebird.dev"],
3332
- * subject: "Hello from Bird",
3333
- * html: "<p>My first Bird email.</p>",
3334
- * });
3335
- * } catch (err) {
3336
- * if (err instanceof BirdRateLimitError) console.log(`rate limited — retry in ${err.retryAfter}s`);
3337
- * else if (err instanceof BirdValidationError) console.error(err.details);
3338
- * else if (err instanceof BirdAPIError) console.error(err.code, err.requestId);
3339
- * else throw err;
3434
+ * @example List mailboxes
3435
+ * for await (const mailbox of bird.email.mailboxes.list()) {
3436
+ * console.log(mailbox.address);
3340
3437
  * }
3341
- *
3342
- * @example Errors as values with `.safe()`
3343
- * const { data, error } = await bird.email
3344
- * .send({
3345
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3346
- * to: ["delivered@messagebird.dev"],
3347
- * subject: "Hello from Bird",
3348
- * html: "<p>My first Bird email.</p>",
3349
- * })
3350
- * .safe();
3351
- * if (error) console.error(error.message);
3352
- * else console.log(data.id);
3353
3438
  */
3354
- send(params, options) {
3355
- const body = {
3356
- ...this.#defaults,
3357
- ...params
3358
- };
3359
- return this.call("POST", options, ({ signal, headers }) => createEmailMessage({
3439
+ list(query, options) {
3440
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listMailboxes({
3360
3441
  client: this.client,
3361
- body,
3442
+ query: {
3443
+ ...query,
3444
+ starting_after: cursor ?? query?.starting_after
3445
+ },
3362
3446
  headers,
3363
3447
  signal
3364
3448
  }));
3365
3449
  }
3366
3450
  /**
3367
- * Send a batch of up to 100 independent email messages in one request. The
3368
- * batch is validated as a unit — if any item fails validation (unverified
3369
- * sender, all recipients suppressed, field-level errors) the whole batch is
3370
- * rejected with a `BirdValidationError` and nothing is queued. Resolves with
3371
- * one accepted item per submitted message, in submission order, once the batch
3372
- * is accepted (the API's 202). Channel defaults are applied per item.
3451
+ * Create a mailbox a durable agent identity that owns an email address, groups mail into threads, and remembers conversations for its retention tier.
3373
3452
  *
3374
- * @example Send a batch of messages
3375
- * const batch = await bird.email.sendBatch([
3376
- * {
3377
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3378
- * to: ["alice@example.com"],
3379
- * subject: "Your receipt",
3380
- * html: "<p>Thanks, Alice.</p>",
3381
- * },
3382
- * {
3383
- * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3384
- * to: ["bob@example.com"],
3385
- * subject: "Your receipt",
3386
- * html: "<p>Thanks, Bob.</p>",
3387
- * },
3388
- * ]);
3389
- * for (const item of batch.data) console.log(item.id, item.status);
3453
+ * @example Create a mailbox
3454
+ * const mailbox = await bird.email.mailboxes.create({ display_name: "Support" });
3455
+ * console.log(mailbox.address); // "abc123@inbox.ai"
3390
3456
  */
3391
- sendBatch(params, options) {
3392
- const body = params.map((item) => ({
3393
- ...this.#defaults,
3394
- ...item
3395
- }));
3396
- return this.call("POST", options, ({ signal, headers }) => createEmailMessageBatch({
3457
+ create(params = {}, options) {
3458
+ return this.call("POST", options, ({ signal, headers }) => createMailbox({
3397
3459
  client: this.client,
3398
- body,
3460
+ body: params,
3399
3461
  headers,
3400
3462
  signal
3401
3463
  }));
3402
3464
  }
3403
3465
  /**
3404
- * Fetch a message with aggregate delivery status.
3405
- *
3406
- * @example
3407
- * const msg = await bird.email.get("em_abc123");
3408
- * msg.status; // "accepted" | "processed" | "delivered" | "bounced" | …
3409
- * msg.delivered_count;
3410
- * msg.bounced_count;
3466
+ * @example Get a mailbox
3467
+ * const mailbox = await bird.email.mailboxes.get("mbx_01abc");
3468
+ * console.log(mailbox.state); // "active"
3411
3469
  */
3412
- get(messageId, options) {
3413
- return this.call("GET", options, ({ signal, headers }) => getEmailMessage({
3470
+ get(mailboxId, options) {
3471
+ return this.call("GET", options, ({ signal, headers }) => getMailbox({
3414
3472
  client: this.client,
3415
- path: { message_id: messageId },
3473
+ path: { mailbox_id: mailboxId },
3416
3474
  headers,
3417
3475
  signal
3418
3476
  }));
3419
3477
  }
3420
3478
  /**
3421
- * Cancel a message scheduled with `scheduled_at` before it sends. Only a
3422
- * message that is still scheduled can be canceled; one that already started
3423
- * sending — or was previously canceled — rejects with a conflict error.
3424
- * Canceling does not return consumed scheduled-send quota.
3479
+ * Update a mailbox's display name, reply-to, receive policy, retention tier, contact, or metadata. Lowering the retention tier onto remembered messages older than the new horizon requires confirm=true.
3425
3480
  *
3426
- * @example
3427
- * await bird.email.cancel("em_abc123");
3481
+ * @example Change a mailbox's receive policy
3482
+ * const mailbox = await bird.email.mailboxes.update("mbx_01abc", {
3483
+ * receive_policy: "open",
3484
+ * });
3485
+ * console.log(mailbox.id, mailbox.receive_policy);
3428
3486
  */
3429
- cancel(messageId, options) {
3430
- return this.call("POST", options, ({ signal, headers }) => cancelEmailMessage({
3487
+ update(mailboxId, params = {}, query, options) {
3488
+ return this.call("PATCH", options, ({ signal, headers }) => updateMailbox({
3431
3489
  client: this.client,
3432
- path: { message_id: messageId },
3490
+ path: { mailbox_id: mailboxId },
3491
+ body: params,
3492
+ query,
3433
3493
  headers,
3434
3494
  signal
3435
3495
  }));
3436
3496
  }
3437
3497
  /**
3438
- * List messages, newest first. `await` resolves the first page; `for await`
3439
- * walks every message across all pages.
3498
+ * Delete a mailbox. The address stops receiving immediately and is quarantined; the mailbox and its remembered messages stay restorable for 30 days via the restore endpoint, then are permanently deleted.
3440
3499
  *
3441
- * @example Iterate every message, or take one page
3442
- * for await (const message of bird.email.list({ status: "bounced" })) {
3443
- * console.log(message.id);
3444
- * }
3445
- * const page = await bird.email.list({ limit: 50 }); // page.data, page.next_cursor
3500
+ * @example Delete a mailbox
3501
+ * await bird.email.mailboxes.delete("mbx_01abc");
3446
3502
  */
3447
- list(query, options) {
3448
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listEmailMessages({
3503
+ delete(mailboxId, options) {
3504
+ return this.call("DELETE", options, ({ signal, headers }) => deleteMailbox({
3449
3505
  client: this.client,
3450
- query: {
3451
- ...query,
3452
- starting_after: cursor ?? query?.starting_after
3453
- },
3506
+ path: { mailbox_id: mailboxId },
3454
3507
  headers,
3455
3508
  signal
3456
3509
  }));
3457
3510
  }
3458
- };
3459
- //#endregion
3460
- //#region src/resources/audiences.ts
3461
- var AudiencesResource = class extends Resource {
3462
3511
  /**
3463
- * Create an audience.
3512
+ * Restore a mailbox deleted less than 30 days ago: the address starts receiving again and the remembered messages are back. Past the window the mailbox is permanently deleted and returns 404; a mailbox that is not deleted returns 409.
3464
3513
  *
3465
- * @example Create an audience
3466
- * const audience = await bird.audiences.create({ name: "Newsletter subscribers" });
3467
- * console.log(audience.id); // "aud_…"
3514
+ * @example Restore a deleted mailbox
3515
+ * const mailbox = await bird.email.mailboxes.restore("mbx_01abc");
3516
+ * console.log(mailbox.deleted_at); // null
3468
3517
  */
3469
- create(params, options) {
3470
- return this.call("POST", options, ({ signal, headers }) => createAudience({
3518
+ restore(mailboxId, options) {
3519
+ return this.call("POST", options, ({ signal, headers }) => restoreMailbox({
3471
3520
  client: this.client,
3472
- body: params,
3521
+ path: { mailbox_id: mailboxId },
3473
3522
  headers,
3474
3523
  signal
3475
3524
  }));
3476
3525
  }
3477
3526
  /**
3478
- * List the workspace's audiences, newest first. `await` resolves the first
3479
- * page; `for await` walks every audience across pages.
3527
+ * Reactivate a suspended mailbox so it can send and receive again and its threads become visible. Fails if your plan does not have room for another active mailbox (or another custom inbox.ai handle); delete an active mailbox or upgrade first. A mailbox that is not suspended returns 409.
3480
3528
  *
3481
- * @example
3482
- * for await (const audience of bird.audiences.list()) {
3483
- * console.log(audience.id, audience.name);
3484
- * }
3529
+ * @example Resume a suspended mailbox
3530
+ * const mailbox = await bird.email.mailboxes.resume("mbx_01abc");
3531
+ * console.log(mailbox.state); // "active"
3485
3532
  */
3486
- list(query, options) {
3487
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listAudiences({
3533
+ resume(mailboxId, options) {
3534
+ return this.call("POST", options, ({ signal, headers }) => resumeMailbox({
3488
3535
  client: this.client,
3489
- query: {
3490
- ...query,
3491
- starting_after: cursor ?? query?.starting_after
3492
- },
3536
+ path: { mailbox_id: mailboxId },
3493
3537
  headers,
3494
3538
  signal
3495
3539
  }));
3496
3540
  }
3497
3541
  /**
3498
- * Fetch a single audience by id.
3499
- *
3500
- * @example
3501
- * const audience = await bird.audiences.get("aud_01krdgeqcxet5s7t44vh8rt9mg");
3542
+ * @example Get mailbox stats
3543
+ * const stats = await bird.email.mailboxes.stats("mbx_01abc");
3544
+ * console.log(stats.summary?.sends_accepted);
3502
3545
  */
3503
- get(audienceId, options) {
3504
- return this.call("GET", options, ({ signal, headers }) => getAudience({
3546
+ stats(mailboxId, query, options) {
3547
+ return this.call("GET", options, ({ signal, headers }) => getMailboxStats({
3505
3548
  client: this.client,
3506
- path: { audience_id: audienceId },
3549
+ path: { mailbox_id: mailboxId },
3550
+ query,
3507
3551
  headers,
3508
3552
  signal
3509
3553
  }));
3510
3554
  }
3511
3555
  /**
3512
- * Update an audience. Only the fields you send change.
3556
+ * List the labels available in a mailbox: the built-in system labels (inbox, archive, spam, blocked, sent, trash, unread) plus every custom label in use.
3513
3557
  *
3514
- * @example
3515
- * await bird.audiences.update("aud_01krdgeqcxet5s7t44vh8rt9mg", { name: "Renamed" });
3558
+ * @example List a mailbox's labels
3559
+ * const labels = await bird.email.mailboxes.labels("mbx_01abc");
3560
+ * console.log(labels.data.map((label) => label.name));
3516
3561
  */
3517
- update(audienceId, params, options) {
3518
- return this.call("PATCH", options, ({ signal, headers }) => updateAudience({
3562
+ labels(mailboxId, options) {
3563
+ return this.call("GET", options, ({ signal, headers }) => listMailboxLabels({
3519
3564
  client: this.client,
3520
- path: { audience_id: audienceId },
3521
- body: params,
3565
+ path: { mailbox_id: mailboxId },
3522
3566
  headers,
3523
3567
  signal
3524
3568
  }));
3525
3569
  }
3570
+ };
3571
+ //#endregion
3572
+ //#region src/resources/emailMailboxesMessages.ts
3573
+ var EmailMailboxesMessagesResource = class extends Resource {
3526
3574
  /**
3527
- * Delete an audience. Its contacts are unaffected.
3575
+ * Send a new email from this mailbox, starting a new conversation.
3528
3576
  *
3529
- * @example
3530
- * await bird.audiences.delete("aud_01krdgeqcxet5s7t44vh8rt9mg");
3577
+ * @example Send from a mailbox
3578
+ * const msg = await bird.email.mailboxes.messages.create("mbx_01abc", {
3579
+ * to: ["customer@example.com"],
3580
+ * subject: "Hello",
3581
+ * text: "Hi there!",
3582
+ * });
3531
3583
  */
3532
- delete(audienceId, options) {
3533
- return this.call("DELETE", options, ({ signal, headers }) => deleteAudience({
3584
+ create(mailboxId, params, options) {
3585
+ return this.call("POST", options, ({ signal, headers }) => createMailboxMessage({
3534
3586
  client: this.client,
3535
- path: { audience_id: audienceId },
3587
+ path: { mailbox_id: mailboxId },
3588
+ body: params,
3536
3589
  headers,
3537
3590
  signal
3538
3591
  }));
3539
3592
  }
3593
+ };
3594
+ //#endregion
3595
+ //#region src/resources/emailMailboxesReceiveRules.gen.ts
3596
+ var EmailMailboxesReceiveRulesResource = class extends Resource {
3540
3597
  /**
3541
- * List the contacts in an audience, newest first. `await` resolves the first
3542
- * page; `for await` walks every member across pages.
3598
+ * List a mailbox's allow/block receive rules as a cursor page, oldest first. Filter by action.
3543
3599
  *
3544
- * @example
3545
- * for await (const member of bird.audiences.listContacts("aud_01krdgeqcxet5s7t44vh8rt9mg")) {
3546
- * console.log(member.contact.id, member.joined_at);
3600
+ * @example List a mailbox's receive rules
3601
+ * for await (const rule of bird.email.mailboxes.receiveRules.list("mbx_01abc")) {
3602
+ * console.log(rule.action, rule.entry);
3547
3603
  * }
3548
3604
  */
3549
- listContacts(audienceId, query, options) {
3550
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listAudienceContacts({
3605
+ list(mailboxId, query, options) {
3606
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listMailboxReceiveRules({
3551
3607
  client: this.client,
3552
- path: { audience_id: audienceId },
3608
+ path: { mailbox_id: mailboxId },
3553
3609
  query: {
3554
3610
  ...query,
3555
3611
  starting_after: cursor ?? query?.starting_after
@@ -3559,51 +3615,36 @@ var AudiencesResource = class extends Resource {
3559
3615
  }));
3560
3616
  }
3561
3617
  /**
3562
- * Add contacts to an audience by id.
3563
- *
3564
- * @example
3565
- * await bird.audiences.addContacts("aud_01krdgeqcxet5s7t44vh8rt9mg", {
3566
- * contact_ids: ["con_1", "con_2"],
3567
- * });
3568
- */
3569
- addContacts(audienceId, params, options) {
3570
- return this.call("POST", options, ({ signal, headers }) => assignAudienceContacts({
3571
- client: this.client,
3572
- path: { audience_id: audienceId },
3573
- body: params,
3574
- headers,
3575
- signal
3576
- }));
3577
- }
3578
- /**
3579
- * Remove a set of contacts from an audience.
3618
+ * Add an allow or block rule for a sender address or domain to a mailbox. Block always wins; up to 200 rules per mailbox.
3580
3619
  *
3581
- * @example
3582
- * await bird.audiences.removeContacts("aud_01krdgeqcxet5s7t44vh8rt9mg", {
3583
- * contact_ids: ["con_1", "con_2"],
3620
+ * @example Block a domain
3621
+ * const rule = await bird.email.mailboxes.receiveRules.create("mbx_01abc", {
3622
+ * action: "block",
3623
+ * entry: "spam.example.com",
3584
3624
  * });
3625
+ * console.log(rule.id);
3585
3626
  */
3586
- removeContacts(audienceId, params, options) {
3587
- return this.call("POST", options, ({ signal, headers }) => unassignAudienceContacts({
3627
+ create(mailboxId, params, options) {
3628
+ return this.call("POST", options, ({ signal, headers }) => createMailboxReceiveRule({
3588
3629
  client: this.client,
3589
- path: { audience_id: audienceId },
3630
+ path: { mailbox_id: mailboxId },
3590
3631
  body: params,
3591
3632
  headers,
3592
3633
  signal
3593
3634
  }));
3594
3635
  }
3595
3636
  /**
3596
- * Remove a single contact from an audience.
3637
+ * Remove a receive rule from a mailbox. Delete-and-recreate is how an entry's action is flipped.
3597
3638
  *
3598
- * @example
3599
- * await bird.audiences.removeContact("aud_01krdgeqcxet5s7t44vh8rt9mg", "con_1");
3639
+ * @example Delete a rule
3640
+ * await bird.email.mailboxes.receiveRules.delete("mbx_01abc", "erl_01xyz");
3600
3641
  */
3601
- removeContact(audienceId, contactId, options) {
3602
- return this.call("DELETE", options, ({ signal, headers }) => unassignAudienceContact({
3642
+ delete(mailboxId, ruleId, options) {
3643
+ return this.call("DELETE", options, ({ signal, headers }) => deleteMailboxReceiveRule({
3603
3644
  client: this.client,
3604
3645
  path: {
3605
- audience_id: audienceId,
3606
- contact_id: contactId
3646
+ mailbox_id: mailboxId,
3647
+ rule_id: ruleId
3607
3648
  },
3608
3649
  headers,
3609
3650
  signal
@@ -3611,35 +3652,31 @@ var AudiencesResource = class extends Resource {
3611
3652
  }
3612
3653
  };
3613
3654
  //#endregion
3614
- //#region src/resources/domains.ts
3615
- var DomainsResource = class extends Resource {
3616
- /**
3617
- * Register a sending domain. Returns it in `pending` with the `dns_records`
3618
- * to publish at your DNS provider; call `verify` once they are in place.
3619
- *
3620
- * @example Register a sending domain
3621
- * const domain = await bird.domains.create({ domain: "mail.acme.com" });
3622
- * console.log(domain.id, domain.status); // "dom_…", "pending"
3623
- */
3624
- create(params, options) {
3625
- return this.call("POST", options, ({ signal, headers }) => createDomain({
3626
- client: this.client,
3627
- body: params,
3628
- headers,
3629
- signal
3630
- }));
3655
+ //#region src/resources/emailMailboxes.ts
3656
+ var EmailMailboxesResource = class extends EmailMailboxesResource$1 {
3657
+ /** Messages sent from the mailbox's own address — `bird.email.mailboxes.messages.create(...)`. */
3658
+ messages;
3659
+ /** Per-sender allow/block rules `bird.email.mailboxes.receiveRules.create(...)`, `.list(...)`, `.delete(...)`. */
3660
+ receiveRules;
3661
+ constructor(...args) {
3662
+ super(...args);
3663
+ this.messages = new EmailMailboxesMessagesResource(...args);
3664
+ this.receiveRules = new EmailMailboxesReceiveRulesResource(...args);
3631
3665
  }
3666
+ };
3667
+ //#endregion
3668
+ //#region src/resources/emailThreads.gen.ts
3669
+ var EmailThreadsResource$1 = class extends Resource {
3632
3670
  /**
3633
- * List the workspace's sending domains, newest first. `await` resolves the
3634
- * first page; `for await` walks every domain across pages.
3671
+ * List mailbox conversations as a cursor page, most recently active first. `label` selects the view — inbox (default), archive, spam, blocked, or a custom label. Filter by mailbox, contact, participant address, or subject substring.
3635
3672
  *
3636
- * @example
3637
- * for await (const domain of bird.domains.list()) {
3638
- * console.log(domain.id, domain.status);
3673
+ * @example List conversation threads
3674
+ * for await (const thread of bird.email.threads.list({ mailbox_id: "mbx_01abc" })) {
3675
+ * console.log(thread.id, thread.subject);
3639
3676
  * }
3640
3677
  */
3641
3678
  list(query, options) {
3642
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listDomains({
3679
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listEmailThreads({
3643
3680
  client: this.client,
3644
3681
  query: {
3645
3682
  ...query,
@@ -3650,87 +3687,69 @@ var DomainsResource = class extends Resource {
3650
3687
  }));
3651
3688
  }
3652
3689
  /**
3653
- * Fetch a single sending domain by id, with its DNS records and their
3654
- * per-record verification state.
3690
+ * Get one conversation: participants, counts, labels, read state. Fetch its messages with the thread messages endpoint.
3655
3691
  *
3656
- * @example
3657
- * const domain = await bird.domains.get("dom_01krdgeqcxet5s7t44vh8rt9mg");
3692
+ * @example Get a thread
3693
+ * const thread = await bird.email.threads.get("thr_01abc");
3694
+ * console.log(thread.subject);
3658
3695
  */
3659
- get(domainId, options) {
3660
- return this.call("GET", options, ({ signal, headers }) => getDomain({
3696
+ get(threadId, options) {
3697
+ return this.call("GET", options, ({ signal, headers }) => getEmailThread({
3661
3698
  client: this.client,
3662
- path: { domain_id: domainId },
3699
+ path: { thread_id: threadId },
3663
3700
  headers,
3664
3701
  signal
3665
3702
  }));
3666
3703
  }
3667
3704
  /**
3668
- * Update a sending domain. Only the fields you send change; `settings` apply
3669
- * immediately, while `return_path`/`tracking`/`dkim` changes are staged until
3670
- * their new DNS records verify.
3705
+ * Add or remove labels on a conversation adding `spam` files it as spam, adding `archive` clears it out of the inbox, adding `inbox` brings it back — or link/unlink a contact.
3671
3706
  *
3672
- * @example
3673
- * await bird.domains.update("dom_01krdgeqcxet5s7t44vh8rt9mg", {
3674
- * settings: { click_tracking: true, open_tracking: true },
3675
- * tracking: { name: "links" },
3707
+ * @example Apply label changes to a thread
3708
+ * const thread = await bird.email.threads.update("thr_01abc", {
3709
+ * labels: { add: ["archive"] },
3676
3710
  * });
3711
+ * console.log(thread.id);
3677
3712
  */
3678
- update(domainId, params, options) {
3679
- return this.call("PATCH", options, ({ signal, headers }) => updateDomain({
3713
+ update(threadId, params = {}, options) {
3714
+ return this.call("PATCH", options, ({ signal, headers }) => updateEmailThread({
3680
3715
  client: this.client,
3681
- path: { domain_id: domainId },
3716
+ path: { thread_id: threadId },
3682
3717
  body: params,
3683
3718
  headers,
3684
3719
  signal
3685
3720
  }));
3686
3721
  }
3687
3722
  /**
3688
- * Delete a sending domain. Mail already accepted still sends; you can no
3689
- * longer send new mail from it.
3690
- *
3691
- * @example
3692
- * await bird.domains.delete("dom_01krdgeqcxet5s7t44vh8rt9mg");
3693
- */
3694
- delete(domainId, options) {
3695
- return this.call("DELETE", options, ({ signal, headers }) => deleteDomain({
3696
- client: this.client,
3697
- path: { domain_id: domainId },
3698
- headers,
3699
- signal
3700
- }));
3701
- }
3702
- /**
3703
- * Trigger a fresh DNS check and return the refreshed domain with per-record
3704
- * results. Safe to repeat while waiting for DNS to propagate.
3723
+ * Move a conversation and all its messages to trash (purged after 30 days), or delete permanently with ?permanent=true.
3705
3724
  *
3706
- * @example
3707
- * const domain = await bird.domains.verify("dom_01krdgeqcxet5s7t44vh8rt9mg");
3708
- * console.log(domain.status); // "verified" once DNS is in place
3725
+ * @example Delete a thread
3726
+ * await bird.email.threads.delete("thr_01abc", { permanent: true });
3709
3727
  */
3710
- verify(domainId, options) {
3711
- return this.call("POST", options, ({ signal, headers }) => verifyDomain({
3728
+ delete(threadId, query, options) {
3729
+ return this.call("DELETE", options, ({ signal, headers }) => deleteEmailThread({
3712
3730
  client: this.client,
3713
- path: { domain_id: domainId },
3731
+ path: { thread_id: threadId },
3732
+ query,
3714
3733
  headers,
3715
3734
  signal
3716
3735
  }));
3717
3736
  }
3718
3737
  };
3719
3738
  //#endregion
3720
- //#region src/resources/contactProperties.gen.ts
3721
- var ContactPropertiesResourceBase = class extends Resource {
3739
+ //#region src/resources/emailThreadsMessages.gen.ts
3740
+ var EmailThreadsMessagesResource = class extends Resource {
3722
3741
  /**
3723
- * List the workspace's contact properties as a cursor page, newest first. Archived properties are included, marked by their archived flag.
3742
+ * List the messages in a conversation newest first, both directions. Page older messages with starting_after, and pass include=extracted_text to inline each message's durable plain text.
3724
3743
  *
3725
- * @example Iterate every contact property, or take one page
3726
- * for await (const prop of bird.contactProperties.list()) {
3727
- * console.log(prop.key, prop.type);
3744
+ * @example List a thread's messages
3745
+ * for await (const msg of bird.email.threads.messages.list("thr_01abc")) {
3746
+ * console.log(msg.id, msg.direction);
3728
3747
  * }
3729
- * const page = await bird.contactProperties.list({ limit: 50 }); // page.data, page.next_cursor
3730
3748
  */
3731
- list(query, options) {
3732
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listContactProperties({
3749
+ list(threadId, query, options) {
3750
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listEmailThreadMessages({
3733
3751
  client: this.client,
3752
+ path: { thread_id: threadId },
3734
3753
  query: {
3735
3754
  ...query,
3736
3755
  starting_after: cursor ?? query?.starting_after
@@ -3740,99 +3759,231 @@ var ContactPropertiesResourceBase = class extends Resource {
3740
3759
  }));
3741
3760
  }
3742
3761
  /**
3743
- * Get a single contact property by ID: key, type, fallback value, and archived state.
3762
+ * Get one conversation message with its extracted plain text readable for the mailbox's full retention period, no MIME parsing needed.
3744
3763
  *
3745
- * @example Fetch a contact property by id
3746
- * const prop = await bird.contactProperties.get("cp_01krdgeqcxet5s7t44vh8rt9mg");
3747
- * console.log(prop.key, prop.type);
3764
+ * @example Get a message
3765
+ * const msg = await bird.email.threads.messages.get("thr_01abc", "rem_01xyz");
3766
+ * console.log(msg.direction); // "inbound"
3748
3767
  */
3749
- get(propertyId, options) {
3750
- return this.call("GET", options, ({ signal, headers }) => getContactProperty({
3768
+ get(threadId, messageId, options) {
3769
+ return this.call("GET", options, ({ signal, headers }) => getEmailThreadMessage({
3751
3770
  client: this.client,
3752
- path: { property_id: propertyId },
3771
+ path: {
3772
+ thread_id: threadId,
3773
+ message_id: messageId
3774
+ },
3753
3775
  headers,
3754
3776
  signal
3755
3777
  }));
3756
3778
  }
3757
3779
  /**
3758
- * Archive a contact property: the key is rejected in new contact writes and stops rendering in templates, while stored values remain readable. The key stays reserved and counts toward the 200-property limit; reverse with `contact_properties.unarchive`.
3780
+ * Get the original rendered HTML and plain-text body of a conversation message. Available 30 days; after that use the message's extracted_text.
3759
3781
  *
3760
- * @example Archive a property, retiring the field without deleting its data
3761
- * const prop = await bird.contactProperties.archive("cp_01krdgeqcxet5s7t44vh8rt9mg");
3762
- * console.log(prop.key, prop.archived);
3782
+ * @example Get a message body
3783
+ * const body = await bird.email.threads.messages.body("thr_01abc", "rem_01xyz");
3784
+ * console.log(body.text);
3763
3785
  */
3764
- archive(propertyId, options) {
3765
- return this.call("POST", options, ({ signal, headers }) => archiveContactProperty({
3786
+ body(threadId, messageId, options) {
3787
+ return this.call("GET", options, ({ signal, headers }) => getEmailThreadMessageBody({
3766
3788
  client: this.client,
3767
- path: { property_id: propertyId },
3789
+ path: {
3790
+ thread_id: threadId,
3791
+ message_id: messageId
3792
+ },
3768
3793
  headers,
3769
3794
  signal
3770
3795
  }));
3771
3796
  }
3772
3797
  /**
3773
- * Reactivate an archived contact property so its key is accepted in contact writes and renders in templates again. Fails with a conflict if the property is not archived.
3798
+ * Reply to a specific conversation message from the mailbox's own address. To reply to a conversation, target its newest received message. Recipients, subject, and threading headers are derived automatically.
3774
3799
  *
3775
- * @example Restore an archived property
3776
- * await bird.contactProperties.unarchive("cp_01krdgeqcxet5s7t44vh8rt9mg");
3777
- */
3778
- unarchive(propertyId, options) {
3779
- return this.call("POST", options, ({ signal, headers }) => unarchiveContactProperty({
3800
+ * @example Reply to a message
3801
+ * const reply = await bird.email.threads.messages.reply("thr_01abc", "rem_01xyz", {
3802
+ * text: "Thanks for reaching out!",
3803
+ * });
3804
+ * console.log(reply.id);
3805
+ */
3806
+ reply(threadId, messageId, params = {}, options) {
3807
+ return this.call("POST", options, ({ signal, headers }) => replyEmailThreadMessage({
3780
3808
  client: this.client,
3781
- path: { property_id: propertyId },
3809
+ path: {
3810
+ thread_id: threadId,
3811
+ message_id: messageId
3812
+ },
3813
+ body: params,
3814
+ headers,
3815
+ signal
3816
+ }));
3817
+ }
3818
+ /**
3819
+ * List the attachments on a conversation message. Bytes are downloadable for 30 days; the metadata also rides the message's attachment_manifest durably.
3820
+ *
3821
+ * @example List a message's attachments
3822
+ * const atts = await bird.email.threads.messages.attachments("thr_01abc", "rem_01xyz");
3823
+ * console.log(atts.data.map((a) => a.filename));
3824
+ */
3825
+ attachments(threadId, messageId, options) {
3826
+ return this.call("GET", options, ({ signal, headers }) => listEmailThreadMessageAttachments({
3827
+ client: this.client,
3828
+ path: {
3829
+ thread_id: threadId,
3830
+ message_id: messageId
3831
+ },
3782
3832
  headers,
3783
3833
  signal
3784
3834
  }));
3785
3835
  }
3786
3836
  };
3787
3837
  //#endregion
3788
- //#region src/resources/contactProperties.ts
3789
- var ContactPropertiesResource = class extends ContactPropertiesResourceBase {
3838
+ //#region src/resources/emailThreads.ts
3839
+ var EmailThreadsResource = class extends EmailThreadsResource$1 {
3840
+ /** Messages in a conversation — `bird.email.threads.messages.list(...)`, `.reply(...)`, … */
3841
+ messages;
3842
+ constructor(...args) {
3843
+ super(...args);
3844
+ this.messages = new EmailThreadsMessagesResource(...args);
3845
+ }
3846
+ };
3847
+ //#endregion
3848
+ //#region src/resources/email.ts
3849
+ var EmailResource = class extends EmailResourceBase {
3850
+ #defaults;
3851
+ /** Email statistics — `bird.email.stats.summary(...)`, `.daily(...)`, `.byTag(...)`, … */
3852
+ stats;
3853
+ /** Durable agent mailboxes — `bird.email.mailboxes.list(...)`, `.create(...)`, … */
3854
+ mailboxes;
3855
+ /** Conversations across every mailbox — `bird.email.threads.list(...)`, `.get(...)`, … */
3856
+ threads;
3857
+ constructor(core, client, defaults) {
3858
+ super(core, client);
3859
+ this.#defaults = defaults;
3860
+ this.stats = new EmailStatsResource(core, client);
3861
+ this.mailboxes = new EmailMailboxesResource(core, client);
3862
+ this.threads = new EmailThreadsResource(core, client);
3863
+ }
3790
3864
  /**
3791
- * Define a contact property. The `key` must be unique in the workspace and is
3792
- * how contacts reference the field in their `data`.
3865
+ * Send an email message. Resolves once the message is accepted for delivery
3866
+ * (the API's 202). Throws on failure a 422 (unverified sender, all
3867
+ * recipients suppressed, validation) is a `BirdValidationError`. Fields set as
3868
+ * channel defaults may be omitted (per-send value wins).
3793
3869
  *
3794
- * @example
3795
- * const prop = await bird.contactProperties.create({ key: "plan", type: "string" });
3796
- * console.log(prop.id); // "cp_…"
3870
+ * @example Send a message
3871
+ * const msg = await bird.email.send({
3872
+ * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3873
+ * to: ["delivered@messagebird.dev"],
3874
+ * subject: "Hello from Bird",
3875
+ * html: "<p>My first Bird email.</p>",
3876
+ * });
3877
+ * console.log(msg.id, msg.status); // "em_…", "accepted"
3878
+ *
3879
+ * @example A richer send — cc/bcc, reply-to, tags, metadata, click-tracking off, and an idempotency key (safe to retry; the server dedupes)
3880
+ * await bird.email.send(
3881
+ * {
3882
+ * from: "hello@acme.com",
3883
+ * to: ["a@example.com", "b@example.com"],
3884
+ * cc: ["manager@example.com"],
3885
+ * reply_to: ["support@acme.com"],
3886
+ * subject: "Your March invoice",
3887
+ * html: "<p>Attached.</p>",
3888
+ * tags: [{ name: "category", value: "billing" }],
3889
+ * metadata: { invoice_id: "inv_123" },
3890
+ * track_clicks: false,
3891
+ * },
3892
+ * { idempotencyKey: "invoice-march/cust_1" },
3893
+ * );
3894
+ *
3895
+ * @example Branch on the typed error hierarchy
3896
+ * import { BirdRateLimitError, BirdValidationError, BirdAPIError } from "@messagebird/sdk";
3897
+ *
3898
+ * try {
3899
+ * await bird.email.send({
3900
+ * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3901
+ * to: ["delivered@messagebird.dev"],
3902
+ * subject: "Hello from Bird",
3903
+ * html: "<p>My first Bird email.</p>",
3904
+ * });
3905
+ * } catch (err) {
3906
+ * if (err instanceof BirdRateLimitError) console.log(`rate limited — retry in ${err.retryAfter}s`);
3907
+ * else if (err instanceof BirdValidationError) console.error(err.details);
3908
+ * else if (err instanceof BirdAPIError) console.error(err.code, err.requestId);
3909
+ * else throw err;
3910
+ * }
3911
+ *
3912
+ * @example Errors as values with `.safe()`
3913
+ * const { data, error } = await bird.email
3914
+ * .send({
3915
+ * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3916
+ * to: ["delivered@messagebird.dev"],
3917
+ * subject: "Hello from Bird",
3918
+ * html: "<p>My first Bird email.</p>",
3919
+ * })
3920
+ * .safe();
3921
+ * if (error) console.error(error.message);
3922
+ * else console.log(data.id);
3797
3923
  */
3798
- create(params, options) {
3799
- return this.call("POST", options, ({ signal, headers }) => createContactProperty({
3924
+ send(params, options) {
3925
+ const body = {
3926
+ ...this.#defaults,
3927
+ ...params
3928
+ };
3929
+ return this.call("POST", options, ({ signal, headers }) => createEmailMessage({
3800
3930
  client: this.client,
3801
- body: params,
3931
+ body,
3802
3932
  headers,
3803
3933
  signal
3804
3934
  }));
3805
3935
  }
3806
3936
  /**
3807
- * Update a contact property. Only the fields you send change.
3937
+ * Send a batch of up to 100 independent email messages in one request. The
3938
+ * batch is validated as a unit — if any item fails validation (unverified
3939
+ * sender, all recipients suppressed, field-level errors) the whole batch is
3940
+ * rejected with a `BirdValidationError` and nothing is queued. Resolves with
3941
+ * one accepted item per submitted message, in submission order, once the batch
3942
+ * is accepted (the API's 202). Channel defaults are applied per item.
3808
3943
  *
3809
- * @example
3810
- * await bird.contactProperties.update("cp_01krdgeqcxet5s7t44vh8rt9mg", { fallback_value: "free" });
3944
+ * @example Send a batch of messages
3945
+ * const batch = await bird.email.sendBatch([
3946
+ * {
3947
+ * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3948
+ * to: ["alice@example.com"],
3949
+ * subject: "Your receipt",
3950
+ * html: "<p>Thanks, Alice.</p>",
3951
+ * },
3952
+ * {
3953
+ * from: { email: "onboarding@messagebird.dev", name: "Bird" },
3954
+ * to: ["bob@example.com"],
3955
+ * subject: "Your receipt",
3956
+ * html: "<p>Thanks, Bob.</p>",
3957
+ * },
3958
+ * ]);
3959
+ * for (const item of batch.data) console.log(item.id, item.status);
3811
3960
  */
3812
- update(propertyId, params, options) {
3813
- return this.call("PATCH", options, ({ signal, headers }) => updateContactProperty({
3961
+ sendBatch(params, options) {
3962
+ const body = params.map((item) => ({
3963
+ ...this.#defaults,
3964
+ ...item
3965
+ }));
3966
+ return this.call("POST", options, ({ signal, headers }) => createEmailMessageBatch({
3814
3967
  client: this.client,
3815
- path: { property_id: propertyId },
3816
- body: params,
3968
+ body,
3817
3969
  headers,
3818
3970
  signal
3819
3971
  }));
3820
3972
  }
3821
3973
  };
3822
3974
  //#endregion
3823
- //#region src/resources/contacts.gen.ts
3824
- var ContactsResourceBase = class extends Resource {
3975
+ //#region src/resources/audiences.gen.ts
3976
+ var AudiencesResource = class extends Resource {
3825
3977
  /**
3826
- * List the workspace's contacts as a cursor page, newest first. Look one up by exact email or external_id, or search by email substring.
3978
+ * List the workspace's audiences as a cursor page, newest first. Filter by name substring with `q`.
3827
3979
  *
3828
- * @example Iterate every contact, or take one page
3829
- * for await (const contact of bird.contacts.list({ q: "acme.com" })) {
3830
- * console.log(contact.id, contact.email);
3980
+ * @example Iterate every audience, or take one page
3981
+ * for await (const audience of bird.audiences.list()) {
3982
+ * console.log(audience.id, audience.name);
3831
3983
  * }
3832
- * const page = await bird.contacts.list({ limit: 50 }); // page.data, page.next_cursor
3833
3984
  */
3834
3985
  list(query, options) {
3835
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listContacts({
3986
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listAudiences({
3836
3987
  client: this.client,
3837
3988
  query: {
3838
3989
  ...query,
@@ -3843,32 +3994,29 @@ var ContactsResourceBase = class extends Resource {
3843
3994
  }));
3844
3995
  }
3845
3996
  /**
3846
- * Get a single contact by ID (`con_`-prefixed). Look up an ID by exact email or external_id with `contacts.list`.
3997
+ * Get a single audience by ID: name, description, and type. Members are listed separately with `audiences.list_contacts`.
3847
3998
  *
3848
- * @example Fetch a contact by id
3849
- * const contact = await bird.contacts.get("con_01krdgeqcxet5s7t44vh8rt9mg");
3850
- * console.log(contact.email, contact.first_name);
3999
+ * @example Fetch an audience by id
4000
+ * const audience = await bird.audiences.get("adn_01krdgeqcxet5s7t44vh8rt9mg");
4001
+ * console.log(audience.name);
3851
4002
  */
3852
- get(contactId, options) {
3853
- return this.call("GET", options, ({ signal, headers }) => getContact({
4003
+ get(audienceId, options) {
4004
+ return this.call("GET", options, ({ signal, headers }) => getAudience({
3854
4005
  client: this.client,
3855
- path: { contact_id: contactId },
4006
+ path: { audience_id: audienceId },
3856
4007
  headers,
3857
4008
  signal
3858
4009
  }));
3859
4010
  }
3860
4011
  /**
3861
- * Create a contact by email address in the workspace. Fails with a conflict if the email or external_id is already used by another contact. For bulk import or create-or-update semantics use `contacts.batch`.
4012
+ * Create an audience in the workspace. New audiences start empty; add contacts with `audiences.add_contacts` or `contacts.batch`. Only static audiences can be created today.
3862
4013
  *
3863
- * @example Create a contact
3864
- * const contact = await bird.contacts.create({
3865
- * email: "jane@acme.com",
3866
- * first_name: "Jane",
3867
- * });
3868
- * console.log(contact.id); // "con_…"
4014
+ * @example Create an audience
4015
+ * const audience = await bird.audiences.create({ name: "Newsletter subscribers" });
4016
+ * console.log(audience.id); // "adn_…"
3869
4017
  */
3870
4018
  create(params, options) {
3871
- return this.call("POST", options, ({ signal, headers }) => createContact({
4019
+ return this.call("POST", options, ({ signal, headers }) => createAudience({
3872
4020
  client: this.client,
3873
4021
  body: params,
3874
4022
  headers,
@@ -3876,135 +4024,122 @@ var ContactsResourceBase = class extends Resource {
3876
4024
  }));
3877
4025
  }
3878
4026
  /**
3879
- * Delete a contact and remove it from every audience it belongs to. Suppression records for the address are unaffected.
4027
+ * Update an audience's name or description. Omitted fields are unchanged; a null description clears it.
3880
4028
  *
3881
- * @example Delete a contact by id
3882
- * await bird.contacts.delete("con_01krdgeqcxet5s7t44vh8rt9mg");
4029
+ * @example Rename an audience
4030
+ * await bird.audiences.update("adn_01krdgeqcxet5s7t44vh8rt9mg", { name: "Renamed" });
3883
4031
  */
3884
- delete(contactId, options) {
3885
- return this.call("DELETE", options, ({ signal, headers }) => deleteContact({
4032
+ update(audienceId, params = {}, options) {
4033
+ return this.call("PATCH", options, ({ signal, headers }) => updateAudience({
3886
4034
  client: this.client,
3887
- path: { contact_id: contactId },
4035
+ path: { audience_id: audienceId },
4036
+ body: params,
3888
4037
  headers,
3889
4038
  signal
3890
4039
  }));
3891
4040
  }
3892
- };
3893
- //#endregion
3894
- //#region src/resources/contacts.ts
3895
- var ContactsResource = class extends ContactsResourceBase {
3896
4041
  /**
3897
- * Update a contact. Only the fields you send change.
4042
+ * Delete an audience and its memberships; contacts themselves are not deleted. Fails while a broadcast targeting the audience is scheduled, accepted, sending, or canceling.
3898
4043
  *
3899
- * @example
3900
- * const contact = await bird.contacts.update("con_01krdgeqcxet5s7t44vh8rt9mg", {
3901
- * first_name: "Jane",
3902
- * });
4044
+ * @example Delete an audience by id
4045
+ * await bird.audiences.delete("adn_01krdgeqcxet5s7t44vh8rt9mg");
3903
4046
  */
3904
- update(contactId, params, options) {
3905
- return this.call("PATCH", options, ({ signal, headers }) => updateContact({
4047
+ delete(audienceId, options) {
4048
+ return this.call("DELETE", options, ({ signal, headers }) => deleteAudience({
3906
4049
  client: this.client,
3907
- path: { contact_id: contactId },
3908
- body: params,
4050
+ path: { audience_id: audienceId },
3909
4051
  headers,
3910
4052
  signal
3911
4053
  }));
3912
4054
  }
3913
4055
  /**
3914
- * Create or update many contacts in one call, matched by email. Returns a
3915
- * per-contact result.
4056
+ * List the contacts in a static audience by ID, as a cursor page ordered by when each contact joined (most recent first). Each entry pairs the contact with its join time.
3916
4057
  *
3917
- * @example
3918
- * const result = await bird.contacts.batch({
3919
- * contacts: [{ email: "jane@acme.com", first_name: "Jane" }],
3920
- * });
4058
+ * @example Iterate an audience's members
4059
+ * for await (const member of bird.audiences.listContacts("adn_01krdgeqcxet5s7t44vh8rt9mg")) {
4060
+ * console.log(member.contact.id, member.joined_at);
4061
+ * }
3921
4062
  */
3922
- batch(params, options) {
3923
- return this.call("POST", options, ({ signal, headers }) => createContactBatch({
4063
+ listContacts(audienceId, query, options) {
4064
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listAudienceContacts({
3924
4065
  client: this.client,
3925
- body: params,
4066
+ path: { audience_id: audienceId },
4067
+ query: {
4068
+ ...query,
4069
+ starting_after: cursor ?? query?.starting_after
4070
+ },
3926
4071
  headers,
3927
4072
  signal
3928
4073
  }));
3929
4074
  }
3930
- };
3931
- //#endregion
3932
- //#region src/resources/sms.ts
3933
- var SmsResource = class extends Resource {
3934
4075
  /**
3935
- * Send one SMS to a single recipient. Supply either `text` (with a `category`)
3936
- * or a stored `template` (by `id` or `name`, with its `parameters`). The
3937
- * result is `accepted`, not yet delivered — read it back with `get` to confirm.
4076
+ * Add up to 1,000 existing contacts to a static audience by ID. Fails entirely if any contact ID does not exist.
3938
4077
  *
3939
- * @example Send free text
3940
- * const msg = await bird.sms.send({
3941
- * from: "MyBrand",
3942
- * to: "+14155550100",
3943
- * text: "Your verification code is 123456.",
3944
- * category: "authentication",
3945
- * });
3946
- * console.log(msg.id, msg.status);
3947
- *
3948
- * @example Send by template
3949
- * await bird.sms.send({
3950
- * to: "+14155550100",
3951
- * template: { name: "bird_otp_verification", parameters: { code: "123456" } },
4078
+ * @example Add contacts to an audience
4079
+ * await bird.audiences.addContacts("adn_01krdgeqcxet5s7t44vh8rt9mg", {
4080
+ * contact_ids: ["con_01krdgeqcxet5s7t44vh8rt9mg"],
3952
4081
  * });
3953
4082
  */
3954
- send(params, options) {
3955
- return this.call("POST", options, ({ signal, headers }) => createSmsMessage({
4083
+ addContacts(audienceId, params, options) {
4084
+ return this.call("POST", options, ({ signal, headers }) => assignAudienceContacts({
3956
4085
  client: this.client,
4086
+ path: { audience_id: audienceId },
3957
4087
  body: params,
3958
4088
  headers,
3959
4089
  signal
3960
4090
  }));
3961
4091
  }
3962
4092
  /**
3963
- * Send up to 100 independent SMS messages in one call. Each item is a full send
3964
- * (free text or template); all items are validated before any are queued.
4093
+ * Remove up to 1,000 contacts from a static audience by ID. Fails entirely if any contact ID does not exist; contacts are not deleted.
3965
4094
  *
3966
- * @example
3967
- * const result = await bird.sms.sendBatch([
3968
- * { to: "+15551111111", text: "Hi Alice!", category: "marketing" },
3969
- * { to: "+15552222222", text: "Hi Bob!", category: "marketing" },
3970
- * ]);
4095
+ * @example Remove contacts from an audience
4096
+ * await bird.audiences.removeContacts("adn_01krdgeqcxet5s7t44vh8rt9mg", {
4097
+ * contact_ids: ["con_01krdgeqcxet5s7t44vh8rt9mg"],
4098
+ * });
3971
4099
  */
3972
- sendBatch(params, options) {
3973
- return this.call("POST", options, ({ signal, headers }) => createSmsMessageBatch({
4100
+ removeContacts(audienceId, params, options) {
4101
+ return this.call("POST", options, ({ signal, headers }) => unassignAudienceContacts({
3974
4102
  client: this.client,
4103
+ path: { audience_id: audienceId },
3975
4104
  body: params,
3976
4105
  headers,
3977
4106
  signal
3978
4107
  }));
3979
4108
  }
3980
4109
  /**
3981
- * Fetch a single SMS message: its current delivery status, segment breakdown,
3982
- * cost, and failure detail if it failed.
4110
+ * Remove one contact's membership from an audience. The contact itself is not deleted and stays a member of any other audiences.
3983
4111
  *
3984
- * @example
3985
- * const msg = await bird.sms.get("sms_abc123");
3986
- * msg.status; // "accepted" | "delivered" | …
4112
+ * @example Remove one contact's membership
4113
+ * await bird.audiences.removeContact(
4114
+ * "adn_01krdgeqcxet5s7t44vh8rt9mg",
4115
+ * "con_01krdgeqcxet5s7t44vh8rt9mg",
4116
+ * );
3987
4117
  */
3988
- get(messageId, options) {
3989
- return this.call("GET", options, ({ signal, headers }) => getSmsMessage({
4118
+ removeContact(audienceId, contactId, options) {
4119
+ return this.call("DELETE", options, ({ signal, headers }) => unassignAudienceContact({
3990
4120
  client: this.client,
3991
- path: { message_id: messageId },
4121
+ path: {
4122
+ audience_id: audienceId,
4123
+ contact_id: contactId
4124
+ },
3992
4125
  headers,
3993
4126
  signal
3994
4127
  }));
3995
4128
  }
4129
+ };
4130
+ //#endregion
4131
+ //#region src/resources/domains.gen.ts
4132
+ var DomainsResource = class extends Resource {
3996
4133
  /**
3997
- * List SMS messages, newest first. `await` resolves the first page; `for await`
3998
- * walks every message across all pages. Filter by direction, status, category,
3999
- * recipient, sender, or tag.
4134
+ * List the workspace's sending domains with their verification status, as a cursor page.
4000
4135
  *
4001
- * @example
4002
- * for await (const msg of bird.sms.list({ direction: "outbound" })) {
4003
- * console.log(msg.id, msg.status);
4136
+ * @example Iterate every sending domain
4137
+ * for await (const domain of bird.domains.list()) {
4138
+ * console.log(domain.id, domain.status);
4004
4139
  * }
4005
4140
  */
4006
4141
  list(query, options) {
4007
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listSmsMessages({
4142
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listDomains({
4008
4143
  client: this.client,
4009
4144
  query: {
4010
4145
  ...query,
@@ -4014,646 +4149,810 @@ var SmsResource = class extends Resource {
4014
4149
  signal
4015
4150
  }));
4016
4151
  }
4017
- };
4018
- //#endregion
4019
- //#region src/resources/smsTemplates.ts
4020
- var SmsTemplatesResource = class extends Resource {
4021
4152
  /**
4022
- * List the SMS templates available to the workspace Bird's built-in
4023
- * templates plus any the workspace authored. The catalogue is small and
4024
- * returned in full (`.data`); this list is not paginated. Filter by `scope`,
4025
- * `category`, or `language` (a BCP-47 language tag).
4153
+ * Fetch one sending domain: verification status and the DNS records with their individual verification states.
4026
4154
  *
4027
- * @example List the built-in templates
4028
- * const { data } = await bird.smsTemplates.list({ scope: "system" });
4029
- * for (const tpl of data) console.log(tpl.id, tpl.name);
4155
+ * @example Fetch a sending domain by id
4156
+ * const domain = await bird.domains.get("dom_01krdgeqcxet5s7t44vh8rt9mg");
4157
+ * console.log(domain.domain);
4030
4158
  */
4031
- list(query, options) {
4032
- return this.call("GET", options, ({ signal, headers }) => listSmsTemplates({
4159
+ get(domainId, options) {
4160
+ return this.call("GET", options, ({ signal, headers }) => getDomain({
4033
4161
  client: this.client,
4034
- query,
4162
+ path: { domain_id: domainId },
4035
4163
  headers,
4036
4164
  signal
4037
4165
  }));
4038
4166
  }
4039
4167
  /**
4040
- * Fetch a single SMS template by its name or id, including its body and the
4041
- * variables it expects.
4168
+ * Register a new sending domain and get the DNS records to publish. Flow: call this, publish the returned DNS records at your DNS provider, then call email_domains_verify (repeat until status is verified — DNS propagation can take minutes to hours).
4042
4169
  *
4043
- * @example
4044
- * const tpl = await bird.smsTemplates.get("bird_otp_verification");
4045
- * console.log(tpl.body, tpl.variables);
4170
+ * @example Register a sending domain
4171
+ * const domain = await bird.domains.create({ domain: "mail.acme.com" });
4172
+ * console.log(domain.id, domain.status); // "dom_…", "pending"
4046
4173
  */
4047
- get(templateRef, options) {
4048
- return this.call("GET", options, ({ signal, headers }) => getSmsTemplate({
4174
+ create(params, options) {
4175
+ return this.call("POST", options, ({ signal, headers }) => createDomain({
4049
4176
  client: this.client,
4050
- path: { template_ref: templateRef },
4177
+ body: params,
4051
4178
  headers,
4052
4179
  signal
4053
4180
  }));
4054
4181
  }
4055
- };
4056
- //#endregion
4057
- //#region src/resources/whatsapp.ts
4058
- var WhatsappResource = class extends Resource {
4059
4182
  /**
4060
- * Send a template message. Bird selects the sender number from the
4061
- * template's category, so there is no sender field on the request. The
4062
- * result is `accepted`, not yet delivered — read it back with `get` to
4063
- * confirm.
4183
+ * Trigger a DNS verification check for a sending domain and return the refreshed domain with per-record results. Safe to repeat while waiting for DNS propagation.
4064
4184
  *
4065
- * @example
4066
- * const msg = await bird.whatsapp.send({
4067
- * to: "+15551234567",
4068
- * template: {
4069
- * name: "bird_otp",
4070
- * components: [
4071
- * { type: "body", parameters: [{ type: "text", text: "123456" }] },
4072
- * ],
4073
- * },
4185
+ * @example Re-run the DNS verification check
4186
+ * const domain = await bird.domains.verify("dom_01krdgeqcxet5s7t44vh8rt9mg");
4187
+ * console.log(domain.status); // "verified" once DNS is in place
4188
+ */
4189
+ verify(domainId, options) {
4190
+ return this.call("POST", options, ({ signal, headers }) => verifyDomain({
4191
+ client: this.client,
4192
+ path: { domain_id: domainId },
4193
+ headers,
4194
+ signal
4195
+ }));
4196
+ }
4197
+ /**
4198
+ * Update a sending domain's tracking and inbound configuration. Tracking: toggle click_tracking and open_tracking (applied immediately to new sends), and set, change, or remove the tracking domain (the name part only — Bird appends the sending domain). Enabling either toggle with no tracking domain configured returns 409; removing the tracking domain while either toggle is still on also returns 409. Tracking-domain changes on a verified domain are staged behind DNS verification, so the current config keeps serving until the new records verify. Inbound receiving: set inbound.enabled to start or stop receiving mail for the domain. Enabling requires the domain's DKIM to be verified first (a fresh enable on an unverified domain returns 422), and a domain already receiving inbound for another organization returns 422. The MX records to publish are always listed in dns_records regardless, so enabling — not merely publishing them — is what turns receiving on.
4199
+ *
4200
+ * @example Enable tracking on a domain
4201
+ * await bird.domains.update("dom_01krdgeqcxet5s7t44vh8rt9mg", {
4202
+ * settings: { click_tracking: true, open_tracking: true },
4203
+ * tracking: { name: "links" },
4074
4204
  * });
4075
- * console.log(msg.id, msg.status);
4076
4205
  */
4077
- send(params, options) {
4078
- return this.call("POST", options, ({ signal, headers }) => sendWhatsAppMessage({
4206
+ update(domainId, params = {}, options) {
4207
+ return this.call("PATCH", options, ({ signal, headers }) => updateDomain({
4079
4208
  client: this.client,
4209
+ path: { domain_id: domainId },
4080
4210
  body: params,
4081
4211
  headers,
4082
4212
  signal
4083
4213
  }));
4084
4214
  }
4085
4215
  /**
4086
- * Fetch a single WhatsApp message: its current delivery status and failure
4087
- * detail if it failed.
4216
+ * Delete a sending domain by id. Revokes its sender authorization: new sends from the domain are rejected afterward, while historical statistics and events for past sends are preserved. Destructive.
4088
4217
  *
4089
- * @example
4090
- * const msg = await bird.whatsapp.get("wa_abc123");
4091
- * msg.status; // "accepted" | "delivered" | …
4218
+ * @example Delete a sending domain by id
4219
+ * await bird.domains.delete("dom_01krdgeqcxet5s7t44vh8rt9mg");
4092
4220
  */
4093
- get(messageId, options) {
4094
- return this.call("GET", options, ({ signal, headers }) => getWhatsAppMessage({
4221
+ delete(domainId, options) {
4222
+ return this.call("DELETE", options, ({ signal, headers }) => deleteDomain({
4223
+ client: this.client,
4224
+ path: { domain_id: domainId },
4225
+ headers,
4226
+ signal
4227
+ }));
4228
+ }
4229
+ };
4230
+ //#endregion
4231
+ //#region src/resources/contactProperties.gen.ts
4232
+ var ContactPropertiesResource = class extends Resource {
4233
+ /**
4234
+ * List the workspace's contact properties as a cursor page, newest first. Archived properties are included, marked by their archived flag.
4235
+ *
4236
+ * @example Iterate every contact property, or take one page
4237
+ * for await (const prop of bird.contactProperties.list()) {
4238
+ * console.log(prop.key, prop.type);
4239
+ * }
4240
+ * const page = await bird.contactProperties.list({ limit: 50 }); // page.data, page.next_cursor
4241
+ */
4242
+ list(query, options) {
4243
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listContactProperties({
4244
+ client: this.client,
4245
+ query: {
4246
+ ...query,
4247
+ starting_after: cursor ?? query?.starting_after
4248
+ },
4249
+ headers,
4250
+ signal
4251
+ }));
4252
+ }
4253
+ /**
4254
+ * Get a single contact property by ID: key, type, fallback value, and archived state.
4255
+ *
4256
+ * @example Fetch a contact property by id
4257
+ * const prop = await bird.contactProperties.get("cp_01krdgeqcxet5s7t44vh8rt9mg");
4258
+ * console.log(prop.key, prop.type);
4259
+ */
4260
+ get(propertyId, options) {
4261
+ return this.call("GET", options, ({ signal, headers }) => getContactProperty({
4262
+ client: this.client,
4263
+ path: { property_id: propertyId },
4264
+ headers,
4265
+ signal
4266
+ }));
4267
+ }
4268
+ /**
4269
+ * Define a custom contact property (key + value type) that becomes available in contact data and as a broadcast template variable. The key and type cannot change after creation; a workspace holds at most 200 properties, archived included.
4270
+ *
4271
+ * @example Define a custom property
4272
+ * const prop = await bird.contactProperties.create({ key: "plan", type: "string" });
4273
+ * console.log(prop.id); // "cp_…"
4274
+ */
4275
+ create(params, options) {
4276
+ return this.call("POST", options, ({ signal, headers }) => createContactProperty({
4095
4277
  client: this.client,
4096
- path: { message_id: messageId },
4278
+ body: params,
4097
4279
  headers,
4098
4280
  signal
4099
4281
  }));
4100
4282
  }
4101
4283
  /**
4102
- * List WhatsApp messages, newest first. `await` resolves the first page;
4103
- * `for await` walks every message across all pages. Filter by status,
4104
- * recipient phone number, or business-scoped user ID.
4284
+ * Update a contact property's fallback value. The key and type are immutable; create a new property instead.
4105
4285
  *
4106
- * @example
4107
- * for await (const msg of bird.whatsapp.list({ status: ["delivered"] })) {
4108
- * console.log(msg.id, msg.status);
4109
- * }
4286
+ * @example Change a property's fallback value
4287
+ * await bird.contactProperties.update("cp_01krdgeqcxet5s7t44vh8rt9mg", { fallback_value: "free" });
4110
4288
  */
4111
- list(query, options) {
4112
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listWhatsAppMessages({
4289
+ update(propertyId, params = {}, options) {
4290
+ return this.call("PATCH", options, ({ signal, headers }) => updateContactProperty({
4113
4291
  client: this.client,
4114
- query: {
4115
- ...query,
4116
- starting_after: cursor ?? query?.starting_after
4117
- },
4292
+ path: { property_id: propertyId },
4293
+ body: params,
4118
4294
  headers,
4119
4295
  signal
4120
4296
  }));
4121
4297
  }
4122
4298
  /**
4123
- * List a WhatsApp message's lifecycle event timeline, in chronological
4124
- * order. The timeline is bounded and returned in full — this list is not
4125
- * paginated.
4299
+ * Archive a contact property: the key is rejected in new contact writes and stops rendering in templates, while stored values remain readable. The key stays reserved and counts toward the 200-property limit; reverse with `contact_properties.unarchive`.
4126
4300
  *
4127
- * @example
4128
- * const { data } = await bird.whatsapp.listEvents("wa_abc123");
4129
- * for (const event of data) console.log(event.type, event.occurred_at);
4301
+ * @example Archive a property, retiring the field without deleting its data
4302
+ * const prop = await bird.contactProperties.archive("cp_01krdgeqcxet5s7t44vh8rt9mg");
4303
+ * console.log(prop.key, prop.archived);
4130
4304
  */
4131
- listEvents(messageId, query, options) {
4132
- return this.call("GET", options, ({ signal, headers }) => listWhatsAppMessageEvents({
4305
+ archive(propertyId, options) {
4306
+ return this.call("POST", options, ({ signal, headers }) => archiveContactProperty({
4133
4307
  client: this.client,
4134
- path: { message_id: messageId },
4135
- query,
4308
+ path: { property_id: propertyId },
4136
4309
  headers,
4137
4310
  signal
4138
4311
  }));
4139
4312
  }
4140
- };
4141
- //#endregion
4142
- //#region src/resources/whatsappTemplates.ts
4143
- var WhatsappTemplatesResource = class extends Resource {
4144
4313
  /**
4145
- * List the WhatsApp message templates available to the workspace Meta's
4146
- * approved templates for this business account. The catalogue is small and
4147
- * returned in full (`.data`); this list is not paginated.
4314
+ * Reactivate an archived contact property so its key is accepted in contact writes and renders in templates again. Fails with a conflict if the property is not archived.
4148
4315
  *
4149
- * @example
4150
- * const { data } = await bird.whatsappTemplates.list();
4151
- * for (const tpl of data) console.log(tpl.name, tpl.status);
4316
+ * @example Restore an archived property
4317
+ * await bird.contactProperties.unarchive("cp_01krdgeqcxet5s7t44vh8rt9mg");
4152
4318
  */
4153
- list(options) {
4154
- return this.call("GET", options, ({ signal, headers }) => listWhatsAppTemplates({
4319
+ unarchive(propertyId, options) {
4320
+ return this.call("POST", options, ({ signal, headers }) => unarchiveContactProperty({
4155
4321
  client: this.client,
4322
+ path: { property_id: propertyId },
4156
4323
  headers,
4157
4324
  signal
4158
4325
  }));
4159
4326
  }
4160
4327
  };
4161
4328
  //#endregion
4162
- //#region src/resources/verify.ts
4163
- var VerificationsResource = class extends Resource {
4329
+ //#region src/resources/contacts.gen.ts
4330
+ var ContactsResource = class extends Resource {
4164
4331
  /**
4165
- * Start a verification and send a one-time passcode to the recipient in `to`
4166
- * (a `phone_number` over SMS, an `email_address` over email, or both). Calling
4167
- * again for the same recipient re-sends the code after the cooldown rather than
4168
- * starting a second verification. The passcode is never returned — submit the
4169
- * recipient's entry with `check`.
4332
+ * List the workspace's contacts as a cursor page, newest first. Look one up by exact email or external_id, or search by email substring.
4170
4333
  *
4171
- * @example Start over SMS
4172
- * const verification = await bird.verify.verifications.create({
4173
- * to: { phone_number: "+15551234567" },
4174
- * });
4175
- * console.log(verification.id, verification.status);
4334
+ * @example Iterate every contact, or take one page
4335
+ * for await (const contact of bird.contacts.list({ q: "acme.com" })) {
4336
+ * console.log(contact.id, contact.email);
4337
+ * }
4338
+ * const page = await bird.contacts.list({ limit: 50 }); // page.data, page.next_cursor
4176
4339
  */
4177
- create(params, options) {
4178
- return this.call("POST", options, ({ signal, headers }) => createVerification({
4340
+ list(query, options) {
4341
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listContacts({
4179
4342
  client: this.client,
4180
- body: params,
4343
+ query: {
4344
+ ...query,
4345
+ starting_after: cursor ?? query?.starting_after
4346
+ },
4181
4347
  headers,
4182
4348
  signal
4183
4349
  }));
4184
4350
  }
4185
4351
  /**
4186
- * Check a passcode the recipient submitted. Identify the verification by the same
4187
- * `to` recipient used to start it — no id needed. A wrong or expired code resolves
4188
- * with `success: false` and a `reason`, not an error; a verification already
4189
- * resolved is no longer checkable and returns a 404 error.
4352
+ * Get a single contact by ID (`con_`-prefixed). Look up an ID by exact email or external_id with `contacts.list`.
4190
4353
  *
4191
- * @example
4192
- * const result = await bird.verify.verifications.check({
4193
- * to: { phone_number: "+15551234567" },
4194
- * code: "123456",
4195
- * });
4196
- * console.log(result.success);
4354
+ * @example Fetch a contact by id
4355
+ * const contact = await bird.contacts.get("con_01krdgeqcxet5s7t44vh8rt9mg");
4356
+ * console.log(contact.email, contact.first_name);
4197
4357
  */
4198
- check(params, options) {
4199
- return this.call("POST", options, ({ signal, headers }) => createVerificationCheck({
4358
+ get(contactId, options) {
4359
+ return this.call("GET", options, ({ signal, headers }) => getContact({
4200
4360
  client: this.client,
4201
- body: params,
4361
+ path: { contact_id: contactId },
4202
4362
  headers,
4203
4363
  signal
4204
4364
  }));
4205
4365
  }
4206
- };
4207
- /** The Verify product namespace — holds the `verifications` collection. */
4208
- var VerifyResource = class {
4209
- verifications;
4210
- constructor(...args) {
4211
- this.verifications = new VerificationsResource(...args);
4212
- }
4213
- };
4214
- //#endregion
4215
- //#region src/resources/webhooks.ts
4216
- var WebhooksResource = class {
4217
- #secret;
4218
- constructor(config) {
4219
- this.#secret = config?.secret;
4220
- }
4221
- /**
4222
- * Verify a webhook delivery and return the typed event.
4223
- *
4224
- * **Pass the raw request body**, exactly as received — do NOT parse it first.
4225
- * The Standard Webhooks signature is computed over the raw bytes, so parsing
4226
- * and re-serializing before verifying is the classic webhook bug.
4227
- *
4228
- * The secret comes from `webhooks.secret` on the client; pass `{ secret }` to
4229
- * override per call. Throws {@link BirdWebhookVerificationError} on a bad
4230
- * signature, a stale timestamp, or missing/malformed headers. Unknown event
4231
- * types are returned as-is (handle them in a `default` case) so a newer server
4232
- * event can't break an older SDK.
4233
- *
4234
- * @example One call verifies the signature and returns the typed event
4235
- * // Pass the RAW request body; set the secret via new BirdClient({ webhooks: { secret } }).
4236
- * const event = bird.webhooks.unwrap(rawBody, headers);
4237
- * console.log(event.type); // discriminated union: narrow on event.type
4238
- *
4239
- * @example Verify and dispatch: pass the raw request body, never the parsed JSON
4240
- * // new BirdClient({ apiKey, webhooks: { secret } })
4241
- * try {
4242
- * const event = bird.webhooks.unwrap(rawBody, req.headers);
4243
- * switch (event.type) {
4244
- * case "email.delivered":
4245
- * markDelivered(event.data.email_id, event.data.recipient); // narrowed by event.type
4246
- * break;
4247
- * case "email.bounced":
4248
- * case "email.complained":
4249
- * suppress(event.data.recipient);
4250
- * break;
4251
- * default: // unknown future event types — an older SDK won't break on a new one
4252
- * }
4253
- * } catch (err) {
4254
- * if (err instanceof BirdWebhookVerificationError) {
4255
- * // reject with 400 — bad signature, stale timestamp, or missing/malformed headers
4256
- * } else throw err;
4257
- * }
4258
- */
4259
- unwrap(payload, headers, options) {
4260
- const secret = options?.secret ?? this.#secret;
4261
- if (!secret) throw new Error("No webhook secret. Set `webhooks: { secret }` on the client, or pass `{ secret }` to unwrap.");
4262
- const wh = new Webhook(secret);
4263
- let verified;
4264
- try {
4265
- verified = wh.verify(payload, toHeaderRecord(headers));
4266
- } catch (err) {
4267
- throw new BirdWebhookVerificationError(err instanceof Error ? err.message : "Webhook signature verification failed");
4268
- }
4269
- return verified;
4270
- }
4271
- };
4272
- function toHeaderRecord(headers) {
4273
- return headers instanceof Headers ? Object.fromEntries(headers) : headers;
4274
- }
4275
- //#endregion
4276
- //#region src/resources/mailbox.ts
4277
- var MailboxResource = class extends Resource {
4278
4366
  /**
4279
- * Create a mailbox. Omit `local_part` to auto-generate a handle on inbox.ai.
4367
+ * Create a contact by email address in the workspace. Fails with a conflict if the email or external_id is already used by another contact. For bulk import or create-or-update semantics use `contacts.batch`.
4280
4368
  *
4281
- * @example Create a mailbox
4282
- * const mailbox = await bird.mailbox.create({ display_name: "Support" });
4283
- * console.log(mailbox.address); // "abc123@inbox.ai"
4369
+ * @example Create a contact
4370
+ * const contact = await bird.contacts.create({
4371
+ * email: "jane@acme.com",
4372
+ * first_name: "Jane",
4373
+ * });
4374
+ * console.log(contact.id); // "con_…"
4284
4375
  */
4285
4376
  create(params, options) {
4286
- return this.call("POST", options, ({ signal, headers }) => createMailbox({
4377
+ return this.call("POST", options, ({ signal, headers }) => createContact({
4287
4378
  client: this.client,
4288
- body: params ?? {},
4379
+ body: params,
4289
4380
  headers,
4290
4381
  signal
4291
4382
  }));
4292
4383
  }
4293
4384
  /**
4294
- * Get a mailbox by id.
4385
+ * Update a contact's name, external_id, email, or custom data. Only supplied fields change; custom data keys are merged, with null removing a key.
4295
4386
  *
4296
- * @example Get a mailbox
4297
- * const mailbox = await bird.mailbox.get("mbx_01abc");
4298
- * console.log(mailbox.state); // "active"
4387
+ * @example Change a contact's fields
4388
+ * const contact = await bird.contacts.update("con_01krdgeqcxet5s7t44vh8rt9mg", {
4389
+ * first_name: "Jane",
4390
+ * });
4391
+ * console.log(contact.first_name);
4299
4392
  */
4300
- get(mailboxId, options) {
4301
- return this.call("GET", options, ({ signal, headers }) => getMailbox({
4393
+ update(contactId, params = {}, options) {
4394
+ return this.call("PATCH", options, ({ signal, headers }) => updateContact({
4302
4395
  client: this.client,
4303
- path: { mailbox_id: mailboxId },
4396
+ path: { contact_id: contactId },
4397
+ body: params,
4304
4398
  headers,
4305
4399
  signal
4306
4400
  }));
4307
4401
  }
4308
4402
  /**
4309
- * Update a mailbox. Only the fields you provide change.
4403
+ * Delete a contact and remove it from every audience it belongs to. Suppression records for the address are unaffected.
4310
4404
  *
4311
- * @example Update receive policy
4312
- * const mailbox = await bird.mailbox.update("mbx_01abc", { receive_policy: "open" });
4405
+ * @example Delete a contact by id
4406
+ * await bird.contacts.delete("con_01krdgeqcxet5s7t44vh8rt9mg");
4313
4407
  */
4314
- update(mailboxId, params, options) {
4315
- return this.call("PATCH", options, ({ signal, headers }) => updateMailbox({
4408
+ delete(contactId, options) {
4409
+ return this.call("DELETE", options, ({ signal, headers }) => deleteContact({
4316
4410
  client: this.client,
4317
- path: { mailbox_id: mailboxId },
4318
- body: params,
4411
+ path: { contact_id: contactId },
4319
4412
  headers,
4320
4413
  signal
4321
4414
  }));
4322
4415
  }
4323
4416
  /**
4324
- * Soft-delete a mailbox. It can be restored within 30 days.
4417
+ * Create or update up to 1,000 contacts in one request, matched by email address, and optionally add them all to one or more audiences. Per-contact results are returned in submission order.
4325
4418
  *
4326
- * @example Delete a mailbox
4327
- * await bird.mailbox.delete("mbx_01abc");
4419
+ * @example Create or update many contacts at once, matched by email
4420
+ * const result = await bird.contacts.batch({
4421
+ * contacts: [{ email: "jane@acme.com", first_name: "Jane" }],
4422
+ * });
4423
+ * for (const item of result.data) {
4424
+ * console.log(item.email, item.status);
4425
+ * }
4328
4426
  */
4329
- delete(mailboxId, options) {
4330
- return this.call("DELETE", options, ({ signal, headers }) => deleteMailbox({
4427
+ batch(params, options) {
4428
+ return this.call("POST", options, ({ signal, headers }) => createContactBatch({
4331
4429
  client: this.client,
4332
- path: { mailbox_id: mailboxId },
4430
+ body: params,
4333
4431
  headers,
4334
4432
  signal
4335
4433
  }));
4336
4434
  }
4435
+ };
4436
+ //#endregion
4437
+ //#region src/resources/sms.gen.ts
4438
+ var SmsResourceBase = class extends Resource {
4337
4439
  /**
4338
- * Restore a deleted mailbox within its 30-day window.
4440
+ * Get one SMS message by id: its current delivery status, segment breakdown, cost, and failure detail if it failed.
4339
4441
  *
4340
- * @example Restore a mailbox
4341
- * const mailbox = await bird.mailbox.restore("mbx_01abc");
4442
+ * @example Read a message back
4443
+ * const msg = await bird.sms.get("sms_abc123");
4444
+ * msg.status; // "accepted" | "delivered" | …
4342
4445
  */
4343
- restore(mailboxId, options) {
4344
- return this.call("POST", options, ({ signal, headers }) => restoreMailbox({
4446
+ get(messageId, options) {
4447
+ return this.call("GET", options, ({ signal, headers }) => getSmsMessage({
4345
4448
  client: this.client,
4346
- path: { mailbox_id: mailboxId },
4449
+ path: { message_id: messageId },
4347
4450
  headers,
4348
4451
  signal
4349
4452
  }));
4350
4453
  }
4351
4454
  /**
4352
- * Reactivate a suspended mailbox.
4455
+ * List SMS messages, newest first, as a cursor page ({data, next_cursor, …}). Pass next_cursor back as starting_after to fetch the next page. Filter by direction, status, category, recipient, sender, or tag.
4353
4456
  *
4354
- * @example Resume a mailbox
4355
- * const mailbox = await bird.mailbox.resume("mbx_01abc");
4457
+ * @example Iterate outbound messages
4458
+ * for await (const msg of bird.sms.list({ direction: "outbound" })) {
4459
+ * console.log(msg.id, msg.status);
4460
+ * }
4356
4461
  */
4357
- resume(mailboxId, options) {
4358
- return this.call("POST", options, ({ signal, headers }) => resumeMailbox({
4462
+ list(query, options) {
4463
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listSmsMessages({
4359
4464
  client: this.client,
4360
- path: { mailbox_id: mailboxId },
4465
+ query: {
4466
+ ...query,
4467
+ starting_after: cursor ?? query?.starting_after
4468
+ },
4361
4469
  headers,
4362
4470
  signal
4363
4471
  }));
4364
4472
  }
4473
+ };
4474
+ //#endregion
4475
+ //#region src/resources/sms.ts
4476
+ /** Filters and cursor params for `bird.sms.list`. */
4477
+ var SmsResource = class extends SmsResourceBase {
4365
4478
  /**
4366
- * Get email activity statistics for a mailbox.
4479
+ * Send one SMS to a single recipient. Supply either `text` (with a `category`)
4480
+ * or a stored `template` (by `id` or `name`, with its `parameters`). The
4481
+ * result is `accepted`, not yet delivered — read it back with `get` to confirm.
4367
4482
  *
4368
- * @example Get mailbox stats
4369
- * const stats = await bird.mailbox.stats("mbx_01abc");
4370
- * console.log(stats.summary?.sends_accepted);
4483
+ * @example Send free text
4484
+ * const msg = await bird.sms.send({
4485
+ * from: "MyBrand",
4486
+ * to: "+14155550100",
4487
+ * text: "Your verification code is 123456.",
4488
+ * category: "authentication",
4489
+ * });
4490
+ * console.log(msg.id, msg.status);
4491
+ *
4492
+ * @example Send by template
4493
+ * await bird.sms.send({
4494
+ * to: "+14155550100",
4495
+ * template: { name: "bird_otp_verification", parameters: { code: "123456" } },
4496
+ * });
4371
4497
  */
4372
- stats(mailboxId, query, options) {
4373
- return this.call("GET", options, ({ signal, headers }) => getMailboxStats({
4498
+ send(params, options) {
4499
+ return this.call("POST", options, ({ signal, headers }) => createSmsMessage({
4374
4500
  client: this.client,
4375
- path: { mailbox_id: mailboxId },
4376
- query: query ?? {},
4501
+ body: params,
4377
4502
  headers,
4378
4503
  signal
4379
4504
  }));
4380
4505
  }
4381
4506
  /**
4382
- * Send a new email from this mailbox, starting a new conversation.
4507
+ * Send up to 100 independent SMS messages in one call. Each item is a full send
4508
+ * (free text or template); all items are validated before any are queued.
4383
4509
  *
4384
- * @example Send from a mailbox
4385
- * const msg = await bird.mailbox.compose("mbx_01abc", {
4386
- * to: ["customer@example.com"],
4387
- * subject: "Hello",
4388
- * text: "Hi there!",
4389
- * });
4510
+ * @example
4511
+ * const result = await bird.sms.sendBatch([
4512
+ * { to: "+15551111111", text: "Hi Alice!", category: "marketing" },
4513
+ * { to: "+15552222222", text: "Hi Bob!", category: "marketing" },
4514
+ * ]);
4390
4515
  */
4391
- compose(mailboxId, params, options) {
4392
- return this.call("POST", options, ({ signal, headers }) => createMailboxMessage({
4516
+ sendBatch(params, options) {
4517
+ return this.call("POST", options, ({ signal, headers }) => createSmsMessageBatch({
4393
4518
  client: this.client,
4394
- path: { mailbox_id: mailboxId },
4395
4519
  body: params,
4396
4520
  headers,
4397
4521
  signal
4398
4522
  }));
4399
4523
  }
4524
+ };
4525
+ //#endregion
4526
+ //#region src/resources/smsTemplates.gen.ts
4527
+ var SmsTemplatesResource = class extends Resource {
4400
4528
  /**
4401
- * List labels available in a mailbox.
4529
+ * List the SMS templates available to your workspace, including Bird's built-in templates. Filter by scope, category, or language. The catalogue is small and returned in full; this list is not paginated. Use sms_templates_get to read one template's variables before sending with it.
4402
4530
  *
4403
- * @example List labels
4404
- * const labels = await bird.mailbox.labels("mbx_01abc");
4405
- * console.log(labels.data.map(l => l.name));
4531
+ * @example List the built-in templates
4532
+ * const { data } = await bird.smsTemplates.list({ scope: "system" });
4533
+ * for (const tpl of data) console.log(tpl.id, tpl.name);
4406
4534
  */
4407
- labels(mailboxId, options) {
4408
- return this.call("GET", options, ({ signal, headers }) => listMailboxLabels({
4535
+ list(query, options) {
4536
+ return this.call("GET", options, ({ signal, headers }) => listSmsTemplates({
4409
4537
  client: this.client,
4410
- path: { mailbox_id: mailboxId },
4538
+ query,
4411
4539
  headers,
4412
4540
  signal
4413
4541
  }));
4414
4542
  }
4415
4543
  /**
4416
- * List mailboxes in the workspace. `await` resolves the first page;
4417
- * `for await` walks every mailbox.
4544
+ * Get one SMS template by its name or id, including its body and the variables it expects. Fetch it before sms_send to see which parameter keys a template send requires.
4418
4545
  *
4419
- * @example List mailboxes
4420
- * for await (const mailbox of bird.mailbox.list()) {
4421
- * console.log(mailbox.address);
4422
- * }
4546
+ * @example Read one template by name or id
4547
+ * const tpl = await bird.smsTemplates.get("bird_otp_verification");
4548
+ * console.log(tpl.body, tpl.variables);
4423
4549
  */
4424
- list(query, options) {
4425
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listMailboxes({
4550
+ get(templateRef, options) {
4551
+ return this.call("GET", options, ({ signal, headers }) => getSmsTemplate({
4426
4552
  client: this.client,
4427
- query: {
4428
- ...query,
4429
- starting_after: cursor ?? query?.starting_after
4430
- },
4553
+ path: { template_ref: templateRef },
4431
4554
  headers,
4432
4555
  signal
4433
4556
  }));
4434
4557
  }
4435
4558
  };
4436
- var MailboxReceiveRuleResource = class extends Resource {
4559
+ //#endregion
4560
+ //#region src/resources/whatsapp.gen.ts
4561
+ var WhatsappResourceBase = class extends Resource {
4437
4562
  /**
4438
- * Add an allow or block rule to a mailbox. Block rules always win.
4563
+ * Get one WhatsApp message by id: current delivery status, sent/delivered/read timestamps, the template it was sent from, and failure detail if it failed. For the per-event timeline use whatsapp_list_events.
4439
4564
  *
4440
- * @example Block a domain
4441
- * const rule = await bird.mailboxReceiveRule.create("mbx_01abc", {
4442
- * action: "block",
4443
- * entry: "spam.example.com",
4444
- * });
4565
+ * @example Read a message back
4566
+ * const msg = await bird.whatsapp.get("wa_abc123");
4567
+ * msg.status; // "accepted" | "delivered" | …
4445
4568
  */
4446
- create(mailboxId, params, options) {
4447
- return this.call("POST", options, ({ signal, headers }) => createMailboxReceiveRule({
4569
+ get(messageId, options) {
4570
+ return this.call("GET", options, ({ signal, headers }) => getWhatsAppMessage({
4448
4571
  client: this.client,
4449
- path: { mailbox_id: mailboxId },
4450
- body: params,
4572
+ path: { message_id: messageId },
4451
4573
  headers,
4452
4574
  signal
4453
4575
  }));
4454
4576
  }
4455
4577
  /**
4456
- * Remove a receive rule.
4578
+ * List WhatsApp messages, newest first, as a cursor page ({data, next_cursor, …}). Pass next_cursor back as starting_after to fetch the next page. Filter by status, contact phone number, bsuid, or tag. Use whatsapp_get for one message's current state.
4457
4579
  *
4458
- * @example Delete a rule
4459
- * await bird.mailboxReceiveRule.delete("mbx_01abc", "erl_01xyz");
4580
+ * @example Iterate delivered messages
4581
+ * for await (const msg of bird.whatsapp.list({ status: ["delivered"] })) {
4582
+ * console.log(msg.id, msg.status);
4583
+ * }
4460
4584
  */
4461
- delete(mailboxId, ruleId, options) {
4462
- return this.call("DELETE", options, ({ signal, headers }) => deleteMailboxReceiveRule({
4585
+ list(query, options) {
4586
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listWhatsAppMessages({
4463
4587
  client: this.client,
4464
- path: {
4465
- mailbox_id: mailboxId,
4466
- rule_id: ruleId
4588
+ query: {
4589
+ ...query,
4590
+ starting_after: cursor ?? query?.starting_after
4467
4591
  },
4468
4592
  headers,
4469
4593
  signal
4470
4594
  }));
4471
4595
  }
4472
4596
  /**
4473
- * List receive rules for a mailbox.
4597
+ * Get one WhatsApp message's delivery timeline, oldest first: whatsapp.accepted, whatsapp.sent, whatsapp.delivered, whatsapp.read, and whatsapp.failed events, with failure detail on failed events. Not paginated; an unknown message id is a 404. Use whatsapp_get for the condensed current status.
4474
4598
  *
4475
- * @example List rules
4476
- * for await (const rule of bird.mailboxReceiveRule.list("mbx_01abc")) {
4477
- * console.log(rule.action, rule.entry);
4478
- * }
4599
+ * @example Read one message's delivery timeline
4600
+ * const { data } = await bird.whatsapp.listEvents("wa_abc123");
4601
+ * for (const event of data) console.log(event.type, event.occurred_at);
4479
4602
  */
4480
- list(mailboxId, query, options) {
4481
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listMailboxReceiveRules({
4603
+ listEvents(messageId, query, options) {
4604
+ return this.call("GET", options, ({ signal, headers }) => listWhatsAppMessageEvents({
4482
4605
  client: this.client,
4483
- path: { mailbox_id: mailboxId },
4484
- query: {
4485
- ...query,
4486
- starting_after: cursor ?? query?.starting_after
4487
- },
4606
+ path: { message_id: messageId },
4607
+ query,
4488
4608
  headers,
4489
4609
  signal
4490
4610
  }));
4491
4611
  }
4492
4612
  };
4493
4613
  //#endregion
4494
- //#region src/resources/mailboxThread.ts
4495
- var MailboxThreadResource = class extends Resource {
4614
+ //#region src/resources/whatsapp.ts
4615
+ var WhatsappResource = class extends WhatsappResourceBase {
4496
4616
  /**
4497
- * Get a conversation thread.
4617
+ * Send a template message. Bird selects the sender number from the
4618
+ * template's category, so there is no sender field on the request. The
4619
+ * result is `accepted`, not yet delivered — read it back with `get` to
4620
+ * confirm.
4498
4621
  *
4499
- * @example Get a thread
4500
- * const thread = await bird.mailboxThread.get("thr_01abc");
4501
- * console.log(thread.message_count);
4622
+ * @example
4623
+ * const msg = await bird.whatsapp.send({
4624
+ * to: "+15551234567",
4625
+ * template: {
4626
+ * name: "bird_otp",
4627
+ * components: [
4628
+ * { type: "body", parameters: [{ type: "text", text: "123456" }] },
4629
+ * ],
4630
+ * },
4631
+ * });
4632
+ * console.log(msg.id, msg.status);
4502
4633
  */
4503
- get(threadId, options) {
4504
- return this.call("GET", options, ({ signal, headers }) => getEmailThread({
4634
+ send(params, options) {
4635
+ return this.call("POST", options, ({ signal, headers }) => sendWhatsAppMessage({
4505
4636
  client: this.client,
4506
- path: { thread_id: threadId },
4637
+ body: params,
4507
4638
  headers,
4508
4639
  signal
4509
4640
  }));
4510
4641
  }
4642
+ };
4643
+ //#endregion
4644
+ //#region src/resources/verifyVerifications.gen.ts
4645
+ var VerifyVerificationsResource = class extends Resource {
4511
4646
  /**
4512
- * Apply label changes or contact link changes to a thread.
4647
+ * Start a verification: generate a one-time passcode and send it to the recipient in `to` (a phone number over SMS, an email address over email, or both; with both, it is sent over one channel and fails over to the other, not to both at once). Calling again for the same recipient reuses the in-progress verification and sends a fresh code after the resend cooldown; it does not start a second one, so use this both to send and to resend. The passcode is never returned; submit what the recipient enters with verify_verifications_check. SMS delivery draws on the workspace's SMS balance.
4513
4648
  *
4514
- * @example Archive a thread
4515
- * const thread = await bird.mailboxThread.update("thr_01abc", {
4516
- * labels: { add: ["archive"] },
4649
+ * @example Start a verification over SMS
4650
+ * const verification = await bird.verify.verifications.create({
4651
+ * to: { phone_number: "+15551234567" },
4517
4652
  * });
4653
+ * console.log(verification.id, verification.status);
4518
4654
  */
4519
- update(threadId, params, options) {
4520
- return this.call("PATCH", options, ({ signal, headers }) => updateEmailThread({
4655
+ create(params, options) {
4656
+ return this.call("POST", options, ({ signal, headers }) => createVerification({
4521
4657
  client: this.client,
4522
- path: { thread_id: threadId },
4523
4658
  body: params,
4524
4659
  headers,
4525
4660
  signal
4526
4661
  }));
4527
4662
  }
4528
4663
  /**
4529
- * Move a thread to trash. Pass `query.permanent = true` to delete immediately.
4664
+ * Check a passcode a recipient submitted. Identify the verification by the same `to` recipient used to start it; no verification id needed. A wrong or expired code returns HTTP 200 with `success: false` and a `reason` (for example `incorrect_code` or `expired`), not an error. A verification that has already reached a final state is no longer checkable and returns 404, as does a missing verification; malformed input or rate limiting is also an error status.
4530
4665
  *
4531
- * @example Delete a thread
4532
- * await bird.mailboxThread.delete("thr_01abc");
4666
+ * @example Check a submitted passcode
4667
+ * const result = await bird.verify.verifications.check({
4668
+ * to: { phone_number: "+15551234567" },
4669
+ * code: "123456",
4670
+ * });
4671
+ * console.log(result.success);
4533
4672
  */
4534
- delete(threadId, query, options) {
4535
- return this.call("DELETE", options, ({ signal, headers }) => deleteEmailThread({
4673
+ check(params, options) {
4674
+ return this.call("POST", options, ({ signal, headers }) => createVerificationCheck({
4536
4675
  client: this.client,
4537
- path: { thread_id: threadId },
4538
- query,
4676
+ body: params,
4539
4677
  headers,
4540
4678
  signal
4541
4679
  }));
4542
4680
  }
4681
+ };
4682
+ //#endregion
4683
+ //#region src/resources/verify.ts
4684
+ /** The Verify product namespace — holds the `verifications` collection. */
4685
+ var VerifyResource = class {
4686
+ verifications;
4687
+ constructor(...args) {
4688
+ this.verifications = new VerifyVerificationsResource(...args);
4689
+ }
4690
+ };
4691
+ //#endregion
4692
+ //#region src/resources/webhooks.ts
4693
+ var WebhooksResource = class {
4694
+ #secret;
4695
+ constructor(config) {
4696
+ this.#secret = config?.secret;
4697
+ }
4543
4698
  /**
4544
- * List threads across the workspace's mailboxes. `await` resolves the first
4545
- * page; `for await` walks every thread.
4699
+ * Verify a webhook delivery and return the typed event.
4700
+ *
4701
+ * **Pass the raw request body**, exactly as received — do NOT parse it first.
4702
+ * The Standard Webhooks signature is computed over the raw bytes, so parsing
4703
+ * and re-serializing before verifying is the classic webhook bug.
4704
+ *
4705
+ * The secret comes from `webhooks.secret` on the client; pass `{ secret }` to
4706
+ * override per call. Throws {@link BirdWebhookVerificationError} on a bad
4707
+ * signature, a stale timestamp, or missing/malformed headers. Unknown event
4708
+ * types are returned as-is (handle them in a `default` case) so a newer server
4709
+ * event can't break an older SDK.
4710
+ *
4711
+ * @example One call verifies the signature and returns the typed event
4712
+ * // Pass the RAW request body; set the secret via new BirdClient({ webhooks: { secret } }).
4713
+ * const event = bird.webhooks.unwrap(rawBody, headers);
4714
+ * console.log(event.type); // discriminated union: narrow on event.type
4546
4715
  *
4547
- * @example List threads in the inbox
4548
- * for await (const thread of bird.mailboxThread.list()) {
4549
- * console.log(thread.id, thread.message_count);
4716
+ * @example Verify and dispatch: pass the raw request body, never the parsed JSON
4717
+ * // new BirdClient({ apiKey, webhooks: { secret } })
4718
+ * try {
4719
+ * const event = bird.webhooks.unwrap(rawBody, req.headers);
4720
+ * switch (event.type) {
4721
+ * case "email.delivered":
4722
+ * markDelivered(event.data.email_id, event.data.recipient); // narrowed by event.type
4723
+ * break;
4724
+ * case "email.bounced":
4725
+ * case "email.complained":
4726
+ * suppress(event.data.recipient);
4727
+ * break;
4728
+ * default: // unknown future event types — an older SDK won't break on a new one
4729
+ * }
4730
+ * } catch (err) {
4731
+ * if (err instanceof BirdWebhookVerificationError) {
4732
+ * // reject with 400 — bad signature, stale timestamp, or missing/malformed headers
4733
+ * } else throw err;
4550
4734
  * }
4551
4735
  */
4552
- list(query, options) {
4553
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listEmailThreads({
4736
+ unwrap(payload, headers, options) {
4737
+ const secret = options?.secret ?? this.#secret;
4738
+ if (!secret) throw new Error("No webhook secret. Set `webhooks: { secret }` on the client, or pass `{ secret }` to unwrap.");
4739
+ const wh = new Webhook(secret);
4740
+ let verified;
4741
+ try {
4742
+ verified = wh.verify(payload, toHeaderRecord(headers));
4743
+ } catch (err) {
4744
+ throw new BirdWebhookVerificationError(err instanceof Error ? err.message : "Webhook signature verification failed");
4745
+ }
4746
+ return verified;
4747
+ }
4748
+ };
4749
+ function toHeaderRecord(headers) {
4750
+ return headers instanceof Headers ? Object.fromEntries(headers) : headers;
4751
+ }
4752
+ //#endregion
4753
+ //#region src/resources/realtime.ts
4754
+ var RealtimeBase = class extends Resource {
4755
+ #config;
4756
+ constructor(core, client, config) {
4757
+ super(core, client);
4758
+ this.#config = config;
4759
+ }
4760
+ /**
4761
+ * Resolve the app credentials for one call. Called eagerly at the top of each
4762
+ * method so a missing credential throws before the lifecycle starts — never
4763
+ * as a rejected promise after a request is already in flight.
4764
+ */
4765
+ auth(options) {
4766
+ const key = options?.key ?? this.#config?.key;
4767
+ const secret = options?.secret ?? this.#config?.secret;
4768
+ if (!key || !secret) throw new Error("No Realtime app credentials. Set `realtime: { key, secret }` on the client, or pass `{ key, secret }` in the call options.");
4769
+ return {
4770
+ "X-Realtime-Key": key,
4771
+ "X-Realtime-Secret": secret
4772
+ };
4773
+ }
4774
+ };
4775
+ /**
4776
+ * `bird.realtime.channels` — reads the app's live channel state. Channels exist
4777
+ * implicitly: one appears when the first connection subscribes and vanishes when
4778
+ * the last one leaves, so these report occupancy, never existence.
4779
+ */
4780
+ var RealtimeChannelsResource = class extends RealtimeBase {
4781
+ /**
4782
+ * List the app's currently occupied channels, optionally filtered by name
4783
+ * prefix. The Realtime service returns them all in one response — this is a
4784
+ * point read, not a cursor list, so there is nothing to iterate.
4785
+ *
4786
+ * @example List the occupied presence channels with their member counts
4787
+ * const { data } = await bird.realtime.channels.list("rap_01krdgeqcxet5s7t44vh8rt9mg", {
4788
+ * prefix: "presence-",
4789
+ * include: ["member_count"],
4790
+ * });
4791
+ * for (const channel of data) console.log(channel.name, channel.member_count);
4792
+ */
4793
+ list(appId, query, options) {
4794
+ const auth = this.auth(options);
4795
+ return this.call("GET", options, ({ signal, headers }) => listRealtimeAppChannels({
4554
4796
  client: this.client,
4555
- query: {
4556
- ...query,
4557
- starting_after: cursor ?? query?.starting_after
4797
+ path: { realtime_app_id: appId },
4798
+ query,
4799
+ headers: {
4800
+ ...headers,
4801
+ ...auth
4558
4802
  },
4559
- headers,
4560
4803
  signal
4561
4804
  }));
4562
4805
  }
4563
- };
4564
- var MailboxThreadMessageResource = class extends Resource {
4565
4806
  /**
4566
- * Get metadata for a message (not the body; use `body` for that).
4807
+ * Read one channel's state. An unknown or never-used name is not an error —
4808
+ * it resolves with `occupied: false`.
4567
4809
  *
4568
- * @example Get a message
4569
- * const msg = await bird.mailboxThreadMessage.get("thr_01abc", "rem_01xyz");
4570
- * console.log(msg.direction); // "inbound"
4810
+ * @example Check whether anyone is in a channel
4811
+ * const channel = await bird.realtime.channels.get(
4812
+ * "rap_01krdgeqcxet5s7t44vh8rt9mg",
4813
+ * "presence-lobby",
4814
+ * { include: ["member_count"] },
4815
+ * );
4816
+ * console.log(channel.occupied, channel.member_count);
4571
4817
  */
4572
- get(threadId, messageId, options) {
4573
- return this.call("GET", options, ({ signal, headers }) => getEmailThreadMessage({
4818
+ get(appId, channelName, query, options) {
4819
+ const auth = this.auth(options);
4820
+ return this.call("GET", options, ({ signal, headers }) => getRealtimeAppChannel({
4574
4821
  client: this.client,
4575
4822
  path: {
4576
- thread_id: threadId,
4577
- message_id: messageId
4823
+ realtime_app_id: appId,
4824
+ channel_name: channelName
4825
+ },
4826
+ query,
4827
+ headers: {
4828
+ ...headers,
4829
+ ...auth
4578
4830
  },
4579
- headers,
4580
4831
  signal
4581
4832
  }));
4582
4833
  }
4583
4834
  /**
4584
- * Get the parsed HTML and plain-text body of a message.
4835
+ * List the member ids subscribed to a presence channel. Ids only — the
4836
+ * `member_info` your authorization endpoint attaches is delivered to subscribed
4837
+ * clients over the realtime connection and is not available over REST.
4585
4838
  *
4586
- * @example Get message body
4587
- * const body = await bird.mailboxThreadMessage.body("thr_01abc", "rem_01xyz");
4588
- * console.log(body.text);
4839
+ * @example Who is in the lobby
4840
+ * const { members } = await bird.realtime.channels.members(
4841
+ * "rap_01krdgeqcxet5s7t44vh8rt9mg",
4842
+ * "presence-lobby",
4843
+ * );
4844
+ * for (const member of members) console.log(member.member_id);
4589
4845
  */
4590
- body(threadId, messageId, options) {
4591
- return this.call("GET", options, ({ signal, headers }) => getEmailThreadMessageBody({
4846
+ members(appId, channelName, options) {
4847
+ const auth = this.auth(options);
4848
+ return this.call("GET", options, ({ signal, headers }) => listRealtimeAppChannelMembers({
4592
4849
  client: this.client,
4593
4850
  path: {
4594
- thread_id: threadId,
4595
- message_id: messageId
4851
+ realtime_app_id: appId,
4852
+ channel_name: channelName
4853
+ },
4854
+ headers: {
4855
+ ...headers,
4856
+ ...auth
4596
4857
  },
4597
- headers,
4598
4858
  signal
4599
4859
  }));
4600
4860
  }
4861
+ };
4862
+ /** `bird.realtime.members` — acts on a member across all of its connections. */
4863
+ var RealtimeMembersResource = class extends RealtimeBase {
4601
4864
  /**
4602
- * Reply to a message from the mailbox's own address.
4865
+ * Disconnect every active connection a member holds sign-out, ban, or a
4866
+ * revoked session. Resolves once the disconnect is applied; the member may
4867
+ * reconnect immediately unless your authorization endpoint refuses them.
4603
4868
  *
4604
- * @example Reply to a message
4605
- * const reply = await bird.mailboxThreadMessage.reply("thr_01abc", "rem_01xyz", {
4606
- * text: "Thanks for reaching out!",
4607
- * });
4869
+ * @example Kick a member off every connection
4870
+ * await bird.realtime.members.disconnect("rap_01krdgeqcxet5s7t44vh8rt9mg", "user_42");
4608
4871
  */
4609
- reply(threadId, messageId, params, options) {
4610
- return this.call("POST", options, ({ signal, headers }) => replyEmailThreadMessage({
4872
+ disconnect(appId, memberId, options) {
4873
+ const auth = this.auth(options);
4874
+ return this.call("POST", options, ({ signal, headers }) => disconnectRealtimeAppMember({
4611
4875
  client: this.client,
4612
4876
  path: {
4613
- thread_id: threadId,
4614
- message_id: messageId
4877
+ realtime_app_id: appId,
4878
+ member_id: memberId
4879
+ },
4880
+ headers: {
4881
+ ...headers,
4882
+ ...auth
4615
4883
  },
4616
- body: params,
4617
- headers,
4618
4884
  signal
4619
4885
  }));
4620
4886
  }
4887
+ };
4888
+ /**
4889
+ * `bird.realtime` — publish events to a Realtime app's channels and inspect its
4890
+ * live state. Every method needs the app's key/secret pair: set it once as
4891
+ * `realtime: { key, secret }` on the client, or pass `{ key, secret }` in a
4892
+ * call's options to reach a different app. Reached as `bird.realtime.*`.
4893
+ */
4894
+ var RealtimeResource = class extends RealtimeBase {
4895
+ /** Channel state — `bird.realtime.channels.list(...)`, `.get(...)`, `.members(...)`. */
4896
+ channels;
4897
+ /** Members — `bird.realtime.members.disconnect(...)`. */
4898
+ members;
4899
+ constructor(core, client, config) {
4900
+ super(core, client, config);
4901
+ this.channels = new RealtimeChannelsResource(core, client, config);
4902
+ this.members = new RealtimeMembersResource(core, client, config);
4903
+ }
4621
4904
  /**
4622
- * List the attachment manifest for a message.
4905
+ * Publish one event to one or more of the app's channels. Listing several
4906
+ * channels broadcasts the same event to all of them in a single call. Resolves
4907
+ * once the event is accepted — delivery to connected clients is asynchronous.
4623
4908
  *
4624
- * @example List attachments
4625
- * const atts = await bird.mailboxThreadMessage.attachments("thr_01abc", "rem_01xyz");
4626
- * console.log(atts.data.map(a => a.filename));
4909
+ * Pass `exclude_connection_id` to skip the connection that triggered the
4910
+ * change, so the originating client doesn't echo its own update.
4911
+ *
4912
+ * @example Broadcast an event to a channel
4913
+ * const result = await bird.realtime.publish("rap_01krdgeqcxet5s7t44vh8rt9mg", {
4914
+ * event: "order.updated",
4915
+ * channels: ["orders", "presence-lobby"],
4916
+ * data: { order_id: "ord_123", status: "shipped" },
4917
+ * });
4918
+ * console.log(result.data?.length); // one entry per channel
4627
4919
  */
4628
- attachments(threadId, messageId, options) {
4629
- return this.call("GET", options, ({ signal, headers }) => listEmailThreadMessageAttachments({
4920
+ publish(appId, params, options) {
4921
+ const auth = this.auth(options);
4922
+ return this.call("POST", options, ({ signal, headers }) => publishRealtimeAppEvent({
4630
4923
  client: this.client,
4631
- path: {
4632
- thread_id: threadId,
4633
- message_id: messageId
4924
+ path: { realtime_app_id: appId },
4925
+ body: params,
4926
+ headers: {
4927
+ ...headers,
4928
+ ...auth
4634
4929
  },
4635
- headers,
4636
4930
  signal
4637
4931
  }));
4638
4932
  }
4639
4933
  /**
4640
- * List messages in a thread. `await` resolves the first page; `for await`
4641
- * walks every message.
4934
+ * Publish up to 10 events in one request, each to a single channel. Use it to
4935
+ * fan different events out at once; to send the *same* event to many channels,
4936
+ * use `publish` with several `channels` instead.
4642
4937
  *
4643
- * @example List messages
4644
- * for await (const msg of bird.mailboxThreadMessage.list("thr_01abc")) {
4645
- * console.log(msg.id, msg.direction);
4646
- * }
4938
+ * @example Publish two events in one call
4939
+ * await bird.realtime.publishBatch("rap_01krdgeqcxet5s7t44vh8rt9mg", {
4940
+ * events: [
4941
+ * { event: "order.created", channel: "orders", data: { id: 1 } },
4942
+ * { event: "order.updated", channel: "orders", data: { id: 2 } },
4943
+ * ],
4944
+ * });
4647
4945
  */
4648
- list(threadId, query, options) {
4649
- return this.paginated("GET", options, ({ signal, headers }, cursor) => listEmailThreadMessages({
4946
+ publishBatch(appId, params, options) {
4947
+ const auth = this.auth(options);
4948
+ return this.call("POST", options, ({ signal, headers }) => publishRealtimeAppBatch({
4650
4949
  client: this.client,
4651
- path: { thread_id: threadId },
4652
- query: {
4653
- ...query,
4654
- starting_after: cursor ?? query?.starting_after
4950
+ path: { realtime_app_id: appId },
4951
+ body: params,
4952
+ headers: {
4953
+ ...headers,
4954
+ ...auth
4655
4955
  },
4656
- headers,
4657
4956
  signal
4658
4957
  }));
4659
4958
  }
@@ -4720,8 +5019,6 @@ var BirdClient = class {
4720
5019
  smsTemplates;
4721
5020
  /** The WhatsApp channel — `bird.whatsapp.send(...)`, `.get(...)`, `.list(...)`, `.listEvents(...)`. */
4722
5021
  whatsapp;
4723
- /** WhatsApp templates — `bird.whatsappTemplates.list(...)`. */
4724
- whatsappTemplates;
4725
5022
  /** The Verify product — `bird.verify.verifications.create(...)`, `.check(...)`. */
4726
5023
  verify;
4727
5024
  /** Contacts — `bird.contacts.create(...)`, `.list(...)`, `.get(...)`, `.batch(...)`, … */
@@ -4734,14 +5031,8 @@ var BirdClient = class {
4734
5031
  domains;
4735
5032
  /** Webhooks — `bird.webhooks.unwrap(payload, headers)` verifies an inbound delivery. */
4736
5033
  webhooks;
4737
- /** Agent mailboxes — `bird.mailbox.create(...)`, `.compose(...)`, `.list(...)`, … */
4738
- mailbox;
4739
- /** Mailbox receive rules — `bird.mailboxReceiveRule.create(...)`, `.delete(...)`, `.list(...)`. */
4740
- mailboxReceiveRule;
4741
- /** Mailbox threads — `bird.mailboxThread.list(...)`, `.get(...)`, `.update(...)`, `.delete(...)`. */
4742
- mailboxThread;
4743
- /** Thread messages — `bird.mailboxThreadMessage.list(...)`, `.get(...)`, `.reply(...)`, `.body(...)`, … */
4744
- mailboxThreadMessage;
5034
+ /** Realtime — `bird.realtime.publish(...)`, `.channels.list(...)`, `.members.disconnect(...)`, … */
5035
+ realtime;
4745
5036
  constructor(options) {
4746
5037
  const opts = options;
4747
5038
  this.#baseUrl = resolveBaseUrl(opts);
@@ -4749,9 +5040,9 @@ var BirdClient = class {
4749
5040
  this.#headers = {
4750
5041
  ...opts.defaultHeaders,
4751
5042
  Authorization: `Bearer ${opts.apiKey}`,
4752
- "User-Agent": `bird-sdk-js/0.12.2`,
5043
+ "User-Agent": `bird-sdk-js/0.15.0`,
4753
5044
  "Bird-Surface": "sdk-js",
4754
- "Bird-Version": "0.12.2"
5045
+ "Bird-Version": "0.15.0"
4755
5046
  };
4756
5047
  const caller = detectCaller();
4757
5048
  if (caller) this.#headers["Bird-Caller"] = caller;
@@ -4768,17 +5059,13 @@ var BirdClient = class {
4768
5059
  this.sms = new SmsResource(this.core, this.#client);
4769
5060
  this.smsTemplates = new SmsTemplatesResource(this.core, this.#client);
4770
5061
  this.whatsapp = new WhatsappResource(this.core, this.#client);
4771
- this.whatsappTemplates = new WhatsappTemplatesResource(this.core, this.#client);
4772
5062
  this.verify = new VerifyResource(this.core, this.#client);
4773
5063
  this.contacts = new ContactsResource(this.core, this.#client);
4774
5064
  this.audiences = new AudiencesResource(this.core, this.#client);
4775
5065
  this.contactProperties = new ContactPropertiesResource(this.core, this.#client);
4776
5066
  this.domains = new DomainsResource(this.core, this.#client);
4777
5067
  this.webhooks = new WebhooksResource(opts.webhooks);
4778
- this.mailbox = new MailboxResource(this.core, this.#client);
4779
- this.mailboxReceiveRule = new MailboxReceiveRuleResource(this.core, this.#client);
4780
- this.mailboxThread = new MailboxThreadResource(this.core, this.#client);
4781
- this.mailboxThreadMessage = new MailboxThreadMessageResource(this.core, this.#client);
5068
+ this.realtime = new RealtimeResource(this.core, this.#client, opts.realtime);
4782
5069
  }
4783
5070
  /**
4784
5071
  * Escape hatch for endpoints the typed resources don't cover. Runs the full
@@ -4862,11 +5149,6 @@ const WebhookEventType = {
4862
5149
  EmailScheduled: "email.scheduled",
4863
5150
  EmailSuppressionCreated: "email_suppression.created",
4864
5151
  EmailUnsubscribed: "email.unsubscribed",
4865
- RealtimeCacheChannels: "realtime.cache_channels",
4866
- RealtimeChannelExistence: "realtime.channel_existence",
4867
- RealtimeClientEvents: "realtime.client_events",
4868
- RealtimeConnectionCount: "realtime.connection_count",
4869
- RealtimePresence: "realtime.presence",
4870
5152
  SmsAccepted: "sms.accepted",
4871
5153
  SmsDelivered: "sms.delivered",
4872
5154
  SmsExpired: "sms.expired",