@sendly/node 3.29.0 → 3.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -978,6 +978,72 @@ interface UpdateWebhookOptions {
978
978
  /** Custom metadata */
979
979
  metadata?: Record<string, unknown>;
980
980
  }
981
+ /**
982
+ * Options for replaying webhook deliveries
983
+ */
984
+ interface WebhookRedeliverOptions {
985
+ /** Earliest delivery created_at to consider, ISO-8601 (default: now − 24h) */
986
+ since?: string;
987
+ /** Latest delivery created_at to consider, ISO-8601 (default: now) */
988
+ until?: string;
989
+ /** Filter by event type (default: all) */
990
+ eventTypes?: WebhookEventType[];
991
+ /** Replay deliveries in any of these statuses (default: ['failed', 'cancelled']) */
992
+ statuses?: DeliveryStatus[];
993
+ /** Maximum number of deliveries to requeue (default: 1000, max 10000) */
994
+ limit?: number;
995
+ }
996
+ /**
997
+ * Result of replaying webhook deliveries
998
+ */
999
+ interface WebhookRedeliverResult {
1000
+ message: string;
1001
+ /** Number of deliveries that were re-queued */
1002
+ requeued: number;
1003
+ /** Number of deliveries that failed to re-queue */
1004
+ skipped: number;
1005
+ /** True if the matching set was larger than `limit` */
1006
+ truncated: boolean;
1007
+ /** Total number of matching deliveries before the limit was applied */
1008
+ windowSize: number;
1009
+ /** IDs of the new delivery records created by the replay */
1010
+ deliveryIds: string[];
1011
+ since: string;
1012
+ until: string;
1013
+ limit: number;
1014
+ }
1015
+ /**
1016
+ * Options for backfilling missed webhook deliveries from the message log
1017
+ */
1018
+ interface WebhookBackfillOptions {
1019
+ /** Earliest message created_at to consider, ISO-8601 (default: now − 24h) */
1020
+ since?: string;
1021
+ /** Latest message created_at to consider, ISO-8601 (default: now) */
1022
+ until?: string;
1023
+ /** Filter by event type (default: subscribed message events) */
1024
+ eventTypes?: WebhookEventType[];
1025
+ /** Maximum number of events to synthesize (default: 1000, max 10000) */
1026
+ limit?: number;
1027
+ }
1028
+ /**
1029
+ * Result of backfilling missed webhook deliveries
1030
+ */
1031
+ interface WebhookBackfillResult {
1032
+ message: string;
1033
+ /** Number of deliveries synthesized and dispatched */
1034
+ synthesized: number;
1035
+ /** Synthesized count grouped by event type */
1036
+ byType: Record<string, number>;
1037
+ /** True if there were more eligible events than `limit` */
1038
+ truncated: boolean;
1039
+ /** Total number of messages scanned for the window */
1040
+ candidatesScanned: number;
1041
+ /** IDs of the new delivery records */
1042
+ deliveryIds: string[];
1043
+ since: string;
1044
+ until: string;
1045
+ limit: number;
1046
+ }
981
1047
  /**
982
1048
  * A webhook delivery attempt
983
1049
  */
@@ -2651,6 +2717,62 @@ declare class WebhooksResource {
2651
2717
  message: string;
2652
2718
  webhook: Webhook;
2653
2719
  }>;
2720
+ /**
2721
+ * Replay failed or cancelled webhook deliveries from the audit log.
2722
+ *
2723
+ * Use after a customer endpoint has recovered from an outage to re-fire
2724
+ * deliveries that we recorded but couldn't deliver. Each replay creates
2725
+ * a new delivery row preserving the original `event_id` so customers can
2726
+ * dedupe.
2727
+ *
2728
+ * Rejects with HTTP 409 if the circuit is currently open — call
2729
+ * {@link WebhooksResource.resetCircuit} first.
2730
+ *
2731
+ * @param id - Webhook ID
2732
+ * @param options - Window and filter options
2733
+ * @returns Counts of requeued deliveries plus the new delivery IDs
2734
+ *
2735
+ * @example
2736
+ * ```typescript
2737
+ * await sendly.webhooks.resetCircuit('whk_xxx');
2738
+ * const result = await sendly.webhooks.redeliver('whk_xxx', {
2739
+ * since: '2026-05-01T00:00:00Z',
2740
+ * eventTypes: ['message.delivered', 'message.failed'],
2741
+ * limit: 5000,
2742
+ * });
2743
+ * console.log(`Requeued ${result.requeued} deliveries`);
2744
+ * ```
2745
+ */
2746
+ redeliver(id: string, options?: WebhookRedeliverOptions): Promise<WebhookRedeliverResult>;
2747
+ /**
2748
+ * Backfill missed webhook events from the underlying message log.
2749
+ *
2750
+ * Use this when a circuit-breaker outage left events with no audit row
2751
+ * (the case `redeliver` cannot recover). The endpoint scans the
2752
+ * `messages` table for the window and synthesizes a webhook delivery
2753
+ * for any message whose `message.sent` / `message.delivered` /
2754
+ * `message.failed` event has not been successfully delivered yet.
2755
+ *
2756
+ * Synthesized events have fresh IDs — your endpoint should dedupe by
2757
+ * `event.data.object.id` (the message ID).
2758
+ *
2759
+ * Rejects with HTTP 409 if the circuit is currently open — call
2760
+ * {@link WebhooksResource.resetCircuit} first.
2761
+ *
2762
+ * @param id - Webhook ID
2763
+ * @param options - Window and filter options
2764
+ * @returns Counts grouped by event type plus the new delivery IDs
2765
+ *
2766
+ * @example
2767
+ * ```typescript
2768
+ * const result = await sendly.webhooks.backfill('whk_xxx', {
2769
+ * since: '2026-05-01T00:00:00Z',
2770
+ * eventTypes: ['message.delivered', 'message.failed'],
2771
+ * });
2772
+ * console.log(`Synthesized ${result.synthesized} events`, result.byType);
2773
+ * ```
2774
+ */
2775
+ backfill(id: string, options?: WebhookBackfillOptions): Promise<WebhookBackfillResult>;
2654
2776
  /**
2655
2777
  * Rotate the webhook signing secret
2656
2778
  *
package/dist/index.d.ts CHANGED
@@ -978,6 +978,72 @@ interface UpdateWebhookOptions {
978
978
  /** Custom metadata */
979
979
  metadata?: Record<string, unknown>;
980
980
  }
981
+ /**
982
+ * Options for replaying webhook deliveries
983
+ */
984
+ interface WebhookRedeliverOptions {
985
+ /** Earliest delivery created_at to consider, ISO-8601 (default: now − 24h) */
986
+ since?: string;
987
+ /** Latest delivery created_at to consider, ISO-8601 (default: now) */
988
+ until?: string;
989
+ /** Filter by event type (default: all) */
990
+ eventTypes?: WebhookEventType[];
991
+ /** Replay deliveries in any of these statuses (default: ['failed', 'cancelled']) */
992
+ statuses?: DeliveryStatus[];
993
+ /** Maximum number of deliveries to requeue (default: 1000, max 10000) */
994
+ limit?: number;
995
+ }
996
+ /**
997
+ * Result of replaying webhook deliveries
998
+ */
999
+ interface WebhookRedeliverResult {
1000
+ message: string;
1001
+ /** Number of deliveries that were re-queued */
1002
+ requeued: number;
1003
+ /** Number of deliveries that failed to re-queue */
1004
+ skipped: number;
1005
+ /** True if the matching set was larger than `limit` */
1006
+ truncated: boolean;
1007
+ /** Total number of matching deliveries before the limit was applied */
1008
+ windowSize: number;
1009
+ /** IDs of the new delivery records created by the replay */
1010
+ deliveryIds: string[];
1011
+ since: string;
1012
+ until: string;
1013
+ limit: number;
1014
+ }
1015
+ /**
1016
+ * Options for backfilling missed webhook deliveries from the message log
1017
+ */
1018
+ interface WebhookBackfillOptions {
1019
+ /** Earliest message created_at to consider, ISO-8601 (default: now − 24h) */
1020
+ since?: string;
1021
+ /** Latest message created_at to consider, ISO-8601 (default: now) */
1022
+ until?: string;
1023
+ /** Filter by event type (default: subscribed message events) */
1024
+ eventTypes?: WebhookEventType[];
1025
+ /** Maximum number of events to synthesize (default: 1000, max 10000) */
1026
+ limit?: number;
1027
+ }
1028
+ /**
1029
+ * Result of backfilling missed webhook deliveries
1030
+ */
1031
+ interface WebhookBackfillResult {
1032
+ message: string;
1033
+ /** Number of deliveries synthesized and dispatched */
1034
+ synthesized: number;
1035
+ /** Synthesized count grouped by event type */
1036
+ byType: Record<string, number>;
1037
+ /** True if there were more eligible events than `limit` */
1038
+ truncated: boolean;
1039
+ /** Total number of messages scanned for the window */
1040
+ candidatesScanned: number;
1041
+ /** IDs of the new delivery records */
1042
+ deliveryIds: string[];
1043
+ since: string;
1044
+ until: string;
1045
+ limit: number;
1046
+ }
981
1047
  /**
982
1048
  * A webhook delivery attempt
983
1049
  */
@@ -2651,6 +2717,62 @@ declare class WebhooksResource {
2651
2717
  message: string;
2652
2718
  webhook: Webhook;
2653
2719
  }>;
2720
+ /**
2721
+ * Replay failed or cancelled webhook deliveries from the audit log.
2722
+ *
2723
+ * Use after a customer endpoint has recovered from an outage to re-fire
2724
+ * deliveries that we recorded but couldn't deliver. Each replay creates
2725
+ * a new delivery row preserving the original `event_id` so customers can
2726
+ * dedupe.
2727
+ *
2728
+ * Rejects with HTTP 409 if the circuit is currently open — call
2729
+ * {@link WebhooksResource.resetCircuit} first.
2730
+ *
2731
+ * @param id - Webhook ID
2732
+ * @param options - Window and filter options
2733
+ * @returns Counts of requeued deliveries plus the new delivery IDs
2734
+ *
2735
+ * @example
2736
+ * ```typescript
2737
+ * await sendly.webhooks.resetCircuit('whk_xxx');
2738
+ * const result = await sendly.webhooks.redeliver('whk_xxx', {
2739
+ * since: '2026-05-01T00:00:00Z',
2740
+ * eventTypes: ['message.delivered', 'message.failed'],
2741
+ * limit: 5000,
2742
+ * });
2743
+ * console.log(`Requeued ${result.requeued} deliveries`);
2744
+ * ```
2745
+ */
2746
+ redeliver(id: string, options?: WebhookRedeliverOptions): Promise<WebhookRedeliverResult>;
2747
+ /**
2748
+ * Backfill missed webhook events from the underlying message log.
2749
+ *
2750
+ * Use this when a circuit-breaker outage left events with no audit row
2751
+ * (the case `redeliver` cannot recover). The endpoint scans the
2752
+ * `messages` table for the window and synthesizes a webhook delivery
2753
+ * for any message whose `message.sent` / `message.delivered` /
2754
+ * `message.failed` event has not been successfully delivered yet.
2755
+ *
2756
+ * Synthesized events have fresh IDs — your endpoint should dedupe by
2757
+ * `event.data.object.id` (the message ID).
2758
+ *
2759
+ * Rejects with HTTP 409 if the circuit is currently open — call
2760
+ * {@link WebhooksResource.resetCircuit} first.
2761
+ *
2762
+ * @param id - Webhook ID
2763
+ * @param options - Window and filter options
2764
+ * @returns Counts grouped by event type plus the new delivery IDs
2765
+ *
2766
+ * @example
2767
+ * ```typescript
2768
+ * const result = await sendly.webhooks.backfill('whk_xxx', {
2769
+ * since: '2026-05-01T00:00:00Z',
2770
+ * eventTypes: ['message.delivered', 'message.failed'],
2771
+ * });
2772
+ * console.log(`Synthesized ${result.synthesized} events`, result.byType);
2773
+ * ```
2774
+ */
2775
+ backfill(id: string, options?: WebhookBackfillOptions): Promise<WebhookBackfillResult>;
2654
2776
  /**
2655
2777
  * Rotate the webhook signing secret
2656
2778
  *
package/dist/index.js CHANGED
@@ -1316,6 +1316,93 @@ var WebhooksResource = class {
1316
1316
  });
1317
1317
  return transformKeys(response);
1318
1318
  }
1319
+ /**
1320
+ * Replay failed or cancelled webhook deliveries from the audit log.
1321
+ *
1322
+ * Use after a customer endpoint has recovered from an outage to re-fire
1323
+ * deliveries that we recorded but couldn't deliver. Each replay creates
1324
+ * a new delivery row preserving the original `event_id` so customers can
1325
+ * dedupe.
1326
+ *
1327
+ * Rejects with HTTP 409 if the circuit is currently open — call
1328
+ * {@link WebhooksResource.resetCircuit} first.
1329
+ *
1330
+ * @param id - Webhook ID
1331
+ * @param options - Window and filter options
1332
+ * @returns Counts of requeued deliveries plus the new delivery IDs
1333
+ *
1334
+ * @example
1335
+ * ```typescript
1336
+ * await sendly.webhooks.resetCircuit('whk_xxx');
1337
+ * const result = await sendly.webhooks.redeliver('whk_xxx', {
1338
+ * since: '2026-05-01T00:00:00Z',
1339
+ * eventTypes: ['message.delivered', 'message.failed'],
1340
+ * limit: 5000,
1341
+ * });
1342
+ * console.log(`Requeued ${result.requeued} deliveries`);
1343
+ * ```
1344
+ */
1345
+ async redeliver(id, options = {}) {
1346
+ if (!id || !id.startsWith("whk_")) {
1347
+ throw new Error("Invalid webhook ID format");
1348
+ }
1349
+ const body = {};
1350
+ if (options.since !== void 0) body.since = options.since;
1351
+ if (options.until !== void 0) body.until = options.until;
1352
+ if (options.eventTypes !== void 0) body.event_types = options.eventTypes;
1353
+ if (options.statuses !== void 0) body.statuses = options.statuses;
1354
+ if (options.limit !== void 0) body.limit = options.limit;
1355
+ const response = await this.http.request({
1356
+ method: "POST",
1357
+ path: `/webhooks/${encodeURIComponent(id)}/redeliver`,
1358
+ body
1359
+ });
1360
+ return transformKeys(response);
1361
+ }
1362
+ /**
1363
+ * Backfill missed webhook events from the underlying message log.
1364
+ *
1365
+ * Use this when a circuit-breaker outage left events with no audit row
1366
+ * (the case `redeliver` cannot recover). The endpoint scans the
1367
+ * `messages` table for the window and synthesizes a webhook delivery
1368
+ * for any message whose `message.sent` / `message.delivered` /
1369
+ * `message.failed` event has not been successfully delivered yet.
1370
+ *
1371
+ * Synthesized events have fresh IDs — your endpoint should dedupe by
1372
+ * `event.data.object.id` (the message ID).
1373
+ *
1374
+ * Rejects with HTTP 409 if the circuit is currently open — call
1375
+ * {@link WebhooksResource.resetCircuit} first.
1376
+ *
1377
+ * @param id - Webhook ID
1378
+ * @param options - Window and filter options
1379
+ * @returns Counts grouped by event type plus the new delivery IDs
1380
+ *
1381
+ * @example
1382
+ * ```typescript
1383
+ * const result = await sendly.webhooks.backfill('whk_xxx', {
1384
+ * since: '2026-05-01T00:00:00Z',
1385
+ * eventTypes: ['message.delivered', 'message.failed'],
1386
+ * });
1387
+ * console.log(`Synthesized ${result.synthesized} events`, result.byType);
1388
+ * ```
1389
+ */
1390
+ async backfill(id, options = {}) {
1391
+ if (!id || !id.startsWith("whk_")) {
1392
+ throw new Error("Invalid webhook ID format");
1393
+ }
1394
+ const body = {};
1395
+ if (options.since !== void 0) body.since = options.since;
1396
+ if (options.until !== void 0) body.until = options.until;
1397
+ if (options.eventTypes !== void 0) body.event_types = options.eventTypes;
1398
+ if (options.limit !== void 0) body.limit = options.limit;
1399
+ const response = await this.http.request({
1400
+ method: "POST",
1401
+ path: `/webhooks/${encodeURIComponent(id)}/backfill`,
1402
+ body
1403
+ });
1404
+ return transformKeys(response);
1405
+ }
1319
1406
  /**
1320
1407
  * Rotate the webhook signing secret
1321
1408
  *
package/dist/index.mjs CHANGED
@@ -1256,6 +1256,93 @@ var WebhooksResource = class {
1256
1256
  });
1257
1257
  return transformKeys(response);
1258
1258
  }
1259
+ /**
1260
+ * Replay failed or cancelled webhook deliveries from the audit log.
1261
+ *
1262
+ * Use after a customer endpoint has recovered from an outage to re-fire
1263
+ * deliveries that we recorded but couldn't deliver. Each replay creates
1264
+ * a new delivery row preserving the original `event_id` so customers can
1265
+ * dedupe.
1266
+ *
1267
+ * Rejects with HTTP 409 if the circuit is currently open — call
1268
+ * {@link WebhooksResource.resetCircuit} first.
1269
+ *
1270
+ * @param id - Webhook ID
1271
+ * @param options - Window and filter options
1272
+ * @returns Counts of requeued deliveries plus the new delivery IDs
1273
+ *
1274
+ * @example
1275
+ * ```typescript
1276
+ * await sendly.webhooks.resetCircuit('whk_xxx');
1277
+ * const result = await sendly.webhooks.redeliver('whk_xxx', {
1278
+ * since: '2026-05-01T00:00:00Z',
1279
+ * eventTypes: ['message.delivered', 'message.failed'],
1280
+ * limit: 5000,
1281
+ * });
1282
+ * console.log(`Requeued ${result.requeued} deliveries`);
1283
+ * ```
1284
+ */
1285
+ async redeliver(id, options = {}) {
1286
+ if (!id || !id.startsWith("whk_")) {
1287
+ throw new Error("Invalid webhook ID format");
1288
+ }
1289
+ const body = {};
1290
+ if (options.since !== void 0) body.since = options.since;
1291
+ if (options.until !== void 0) body.until = options.until;
1292
+ if (options.eventTypes !== void 0) body.event_types = options.eventTypes;
1293
+ if (options.statuses !== void 0) body.statuses = options.statuses;
1294
+ if (options.limit !== void 0) body.limit = options.limit;
1295
+ const response = await this.http.request({
1296
+ method: "POST",
1297
+ path: `/webhooks/${encodeURIComponent(id)}/redeliver`,
1298
+ body
1299
+ });
1300
+ return transformKeys(response);
1301
+ }
1302
+ /**
1303
+ * Backfill missed webhook events from the underlying message log.
1304
+ *
1305
+ * Use this when a circuit-breaker outage left events with no audit row
1306
+ * (the case `redeliver` cannot recover). The endpoint scans the
1307
+ * `messages` table for the window and synthesizes a webhook delivery
1308
+ * for any message whose `message.sent` / `message.delivered` /
1309
+ * `message.failed` event has not been successfully delivered yet.
1310
+ *
1311
+ * Synthesized events have fresh IDs — your endpoint should dedupe by
1312
+ * `event.data.object.id` (the message ID).
1313
+ *
1314
+ * Rejects with HTTP 409 if the circuit is currently open — call
1315
+ * {@link WebhooksResource.resetCircuit} first.
1316
+ *
1317
+ * @param id - Webhook ID
1318
+ * @param options - Window and filter options
1319
+ * @returns Counts grouped by event type plus the new delivery IDs
1320
+ *
1321
+ * @example
1322
+ * ```typescript
1323
+ * const result = await sendly.webhooks.backfill('whk_xxx', {
1324
+ * since: '2026-05-01T00:00:00Z',
1325
+ * eventTypes: ['message.delivered', 'message.failed'],
1326
+ * });
1327
+ * console.log(`Synthesized ${result.synthesized} events`, result.byType);
1328
+ * ```
1329
+ */
1330
+ async backfill(id, options = {}) {
1331
+ if (!id || !id.startsWith("whk_")) {
1332
+ throw new Error("Invalid webhook ID format");
1333
+ }
1334
+ const body = {};
1335
+ if (options.since !== void 0) body.since = options.since;
1336
+ if (options.until !== void 0) body.until = options.until;
1337
+ if (options.eventTypes !== void 0) body.event_types = options.eventTypes;
1338
+ if (options.limit !== void 0) body.limit = options.limit;
1339
+ const response = await this.http.request({
1340
+ method: "POST",
1341
+ path: `/webhooks/${encodeURIComponent(id)}/backfill`,
1342
+ body
1343
+ });
1344
+ return transformKeys(response);
1345
+ }
1259
1346
  /**
1260
1347
  * Rotate the webhook signing secret
1261
1348
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendly/node",
3
- "version": "3.29.0",
3
+ "version": "3.30.0",
4
4
  "description": "Official Sendly Node.js SDK for SMS messaging",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",