@sentdm/sentdm 0.38.0 → 0.40.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/client.d.mts +4 -2
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +4 -2
  5. package/client.d.ts.map +1 -1
  6. package/client.js +2 -0
  7. package/client.js.map +1 -1
  8. package/client.mjs +2 -0
  9. package/client.mjs.map +1 -1
  10. package/package.json +1 -1
  11. package/resources/conversations.d.mts +71 -3
  12. package/resources/conversations.d.mts.map +1 -1
  13. package/resources/conversations.d.ts +71 -3
  14. package/resources/conversations.d.ts.map +1 -1
  15. package/resources/index.d.mts +1 -1
  16. package/resources/index.d.mts.map +1 -1
  17. package/resources/index.d.ts +1 -1
  18. package/resources/index.d.ts.map +1 -1
  19. package/resources/index.js.map +1 -1
  20. package/resources/index.mjs.map +1 -1
  21. package/resources/messages.d.mts +171 -14
  22. package/resources/messages.d.mts.map +1 -1
  23. package/resources/messages.d.ts +171 -14
  24. package/resources/messages.d.ts.map +1 -1
  25. package/resources/messages.js +21 -3
  26. package/resources/messages.js.map +1 -1
  27. package/resources/messages.mjs +21 -3
  28. package/resources/messages.mjs.map +1 -1
  29. package/resources/templates.d.mts +276 -14
  30. package/resources/templates.d.mts.map +1 -1
  31. package/resources/templates.d.ts +276 -14
  32. package/resources/templates.d.ts.map +1 -1
  33. package/resources/templates.js +28 -2
  34. package/resources/templates.js.map +1 -1
  35. package/resources/templates.mjs +28 -2
  36. package/resources/templates.mjs.map +1 -1
  37. package/resources/webhooks.d.mts +693 -22
  38. package/resources/webhooks.d.mts.map +1 -1
  39. package/resources/webhooks.d.ts +693 -22
  40. package/resources/webhooks.d.ts.map +1 -1
  41. package/src/client.ts +10 -0
  42. package/src/resources/conversations.ts +78 -3
  43. package/src/resources/index.ts +4 -0
  44. package/src/resources/messages.ts +182 -14
  45. package/src/resources/templates.ts +289 -14
  46. package/src/resources/webhooks.ts +764 -22
  47. package/src/version.ts +1 -1
  48. package/version.d.mts +1 -1
  49. package/version.d.ts +1 -1
  50. package/version.js +1 -1
  51. package/version.mjs +1 -1
@@ -164,6 +164,422 @@ export interface APIResponseWebhook {
164
164
  */
165
165
  success?: boolean;
166
166
  }
167
+ /**
168
+ * The envelope Sent POSTs to a subscribed webhook endpoint. Every event shares
169
+ * this shape and varies only in Payload.
170
+ */
171
+ export interface ChannelEvent {
172
+ /**
173
+ * The specific event within the family, for example message.delivered,
174
+ * message.received or contact.opt_out. Absent on events that have no subtype, so
175
+ * treat it as optional.
176
+ */
177
+ event?: string | null;
178
+ /**
179
+ * The event family, for example message, templates or contact. Route on this
180
+ * first, then on event for the specific change.
181
+ */
182
+ field?: string;
183
+ /**
184
+ * Body of a channel event: where one of the customer's channels stands in
185
+ * provisioning and compliance. Delivered when a milestone moves — a registration
186
+ * filed, a verdict returned, a resubmission asked for, a sender gone live — so a
187
+ * customer's own onboarding UI does not have to poll GET /v3/channels.
188
+ *
189
+ * The subject is one item, never the account. A customer's "SMS channel" has no
190
+ * status; a market does. Country, NumberType and SenderValue name which one, so a
191
+ * customer terminating only to Kosovo never receives an event about US 10DLC.
192
+ *
193
+ * Status is the stable half of the contract. It is the same four-value set GET
194
+ * /v3/channels publishes, computed through the same code, so an event and a read
195
+ * of the same market cannot disagree. A subscriber that reads nothing but the
196
+ * status and the subject fields is a correct subscriber. The sub-type on the
197
+ * envelope names the specific milestone and is additive — that vocabulary comes
198
+ * from registries and carriers, which are parties Sent does not control.
199
+ *
200
+ * Status means provisioning and compliance are complete, not that a send will
201
+ * succeed right now. An account can be suspended, or a destination blocked by a
202
+ * routing rule, without either showing up here. Those are separate surfaces and
203
+ * deliberately not modelled on this payload.
204
+ */
205
+ payload?: ChannelEventPayload | null;
206
+ /**
207
+ * The event-specific body.
208
+ */
209
+ request_id?: string | null;
210
+ /**
211
+ * When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
212
+ * time, not the time the underlying change happened. Use the timestamp inside the
213
+ * payload for the latter.
214
+ */
215
+ timestamp?: string;
216
+ }
217
+ /**
218
+ * Body of a channel event: where one of the customer's channels stands in
219
+ * provisioning and compliance. Delivered when a milestone moves — a registration
220
+ * filed, a verdict returned, a resubmission asked for, a sender gone live — so a
221
+ * customer's own onboarding UI does not have to poll GET /v3/channels.
222
+ *
223
+ * The subject is one item, never the account. A customer's "SMS channel" has no
224
+ * status; a market does. Country, NumberType and SenderValue name which one, so a
225
+ * customer terminating only to Kosovo never receives an event about US 10DLC.
226
+ *
227
+ * Status is the stable half of the contract. It is the same four-value set GET
228
+ * /v3/channels publishes, computed through the same code, so an event and a read
229
+ * of the same market cannot disagree. A subscriber that reads nothing but the
230
+ * status and the subject fields is a correct subscriber. The sub-type on the
231
+ * envelope names the specific milestone and is additive — that vocabulary comes
232
+ * from registries and carriers, which are parties Sent does not control.
233
+ *
234
+ * Status means provisioning and compliance are complete, not that a send will
235
+ * succeed right now. An account can be suspended, or a destination blocked by a
236
+ * routing rule, without either showing up here. Those are separate surfaces and
237
+ * deliberately not modelled on this payload.
238
+ */
239
+ export interface ChannelEventPayload {
240
+ /**
241
+ * The market's destination country as an ISO 3166-1 alpha-2 code, for example XK.
242
+ * Always present, and the property that identifies this payload among the
243
+ * delivered envelopes — see DeliveredWebhookEvents. Every event in this family
244
+ * reports one market, and a market has a country.
245
+ */
246
+ country: string;
247
+ /**
248
+ * The account whose market this is, named as on every other family. When an
249
+ * organization receives an event for one of its sender profiles this is the
250
+ * profile, so a reseller compares it with its own id and anything different is one
251
+ * of its profiles. Matches customer_id on GET /v3/channels and the sender
252
+ * profile's id. Together with channel, country, and number_type, it identifies the
253
+ * market.
254
+ */
255
+ account_id?: string;
256
+ /**
257
+ * The channel this market belongs to: sms, whatsapp, or rcs. Never sent — that
258
+ * value belongs to message events, where it names the smart-routing brand rather
259
+ * than a channel that can be provisioned.
260
+ */
261
+ channel?: string;
262
+ /**
263
+ * What a market has been given: the identity it registers under, its programme,
264
+ * and any documents attached.
265
+ *
266
+ * What it does not carry is what the market asks for. That is the subject of GET
267
+ * /v3/compliance/requirements, and it is the same answer for every caller — a
268
+ * description of what a compliance regime wants, not a record of one customer's
269
+ * progress through it. It was reported here as well for a while, which put the
270
+ * same array in six response shapes and left a caller deciding which of two
271
+ * sources to believe.
272
+ *
273
+ * Present on a list read for markets that register (carrying brand and campaign),
274
+ * but with documents absent — documents are not fetched for a list, because a
275
+ * catalog lookup and a document read per market would multiply across a page.
276
+ * Absent documents is distinct from an empty list: absent says they were not
277
+ * fetched; empty says the market has been given none. The parent object is null
278
+ * only when the market registers with nobody and compliance was not computed —
279
+ * nothing to show at all.
280
+ */
281
+ compliance?: ChannelEventPayload.Compliance | null;
282
+ /**
283
+ * The kind of sender the market uses, for example TEN_DLC, LOCAL, or ALPHANUMERIC.
284
+ * Omitted when the subject has no sender type of its own.
285
+ */
286
+ number_type?: string | null;
287
+ /**
288
+ * Why the market reached this state, when a reason was given — a correction
289
+ * explained, or a campaign lapse. Free text, passed through from the registry or
290
+ * carrier that wrote it, so treat it as a message to show a human rather than a
291
+ * value to branch on.
292
+ */
293
+ reason?: string | null;
294
+ /**
295
+ * The sender itself — a number in E.164, or an alphanumeric sender ID.
296
+ *
297
+ * Always present, and null until a sender exists. The key is on every delivery so
298
+ * a subscriber reads one shape rather than branching on whether the field arrived
299
+ * — the same choice template_id makes on the message payload.
300
+ *
301
+ * It can carry a value at any point in the lifecycle, not only once the market is
302
+ * live: a number ordered and not yet active at the carrier is already known during
303
+ * PROVISIONING, and an alphanumeric sender the customer chose themselves is known
304
+ * before anything is filed. It is null while the market is still waiting on a
305
+ * number, which for a US 10DLC registration is every event up to
306
+ * channel.activated.
307
+ */
308
+ sender_value?: string | null;
309
+ /**
310
+ * Where the market stands: PENDING_REVIEW, ACTION_NEEDED, PROVISIONING, ACTIVE or
311
+ * INACTIVE. PENDING_REVIEW means a registry or a carrier holds it and the wait is
312
+ * theirs; ACTION_NEEDED means it is yours; PROVISIONING means the verdict is in
313
+ * and Sent is acquiring the sender; INACTIVE means it had a working sender and no
314
+ * longer does.
315
+ *
316
+ * Each event name is the transition into one of these, but the two are separate
317
+ * fields and may legitimately differ. A resubmission filed against a market whose
318
+ * sender is already live is channel.submitted carrying ACTIVE: a correction is
319
+ * with the registry and the sender keeps working. Read both.
320
+ */
321
+ status?: string;
322
+ /**
323
+ * When the transition happened, in UTC (yyyy-MM-ddTHH:mm:ssZ).
324
+ */
325
+ updated_at?: string;
326
+ }
327
+ export declare namespace ChannelEventPayload {
328
+ /**
329
+ * What a market has been given: the identity it registers under, its programme,
330
+ * and any documents attached.
331
+ *
332
+ * What it does not carry is what the market asks for. That is the subject of GET
333
+ * /v3/compliance/requirements, and it is the same answer for every caller — a
334
+ * description of what a compliance regime wants, not a record of one customer's
335
+ * progress through it. It was reported here as well for a while, which put the
336
+ * same array in six response shapes and left a caller deciding which of two
337
+ * sources to believe.
338
+ *
339
+ * Present on a list read for markets that register (carrying brand and campaign),
340
+ * but with documents absent — documents are not fetched for a list, because a
341
+ * catalog lookup and a document read per market would multiply across a page.
342
+ * Absent documents is distinct from an empty list: absent says they were not
343
+ * fetched; empty says the market has been given none. The parent object is null
344
+ * only when the market registers with nobody and compliance was not computed —
345
+ * nothing to show at all.
346
+ */
347
+ interface Compliance {
348
+ /**
349
+ * The identity this market registers under, with inherit saying whose it is.
350
+ *
351
+ * Reported here rather than on the profile because it belongs to the registration
352
+ * this market files, and only one market files one. It was a top-level block for a
353
+ * while, which put a per-registration value beside a list of markets and left a
354
+ * caller to work out which market it belonged to.
355
+ *
356
+ * Absent for a market that registers with nobody — such a market asks for no
357
+ * identity, so there is none to report. Absent and null mean different things:
358
+ * absent says this market does not ask, null would say it asks and nothing was
359
+ * supplied.
360
+ *
361
+ * Untyped, like the request side, because its members are declared by the market's
362
+ * own schema rather than by a C# class. A typed pair here would be a second
363
+ * definition of what a market wants, free to drift from the one that validates.
364
+ */
365
+ brand?: {
366
+ [key: string]: unknown;
367
+ } | null;
368
+ /**
369
+ * The programme this market registers, with inherit saying whose it is.
370
+ *
371
+ * One, not a list. TcrCampaigns permits several and an account built on the admin
372
+ * side may hold them, but this surface offers one — which is what lets the
373
+ * market's PATCH be an upsert rather than a collection with an addressable create
374
+ * behind it. An account holding several is reported as its first and refused on
375
+ * write, rather than half-edited.
376
+ *
377
+ * Carries no id. Nothing addresses a campaign, and an undeclared key would be
378
+ * refused if the caller sent this object back — which it is meant to be able to
379
+ * do.
380
+ */
381
+ campaign?: {
382
+ [key: string]: unknown;
383
+ } | null;
384
+ /**
385
+ * What has been supplied for this market.
386
+ *
387
+ * Files, not values — the declared halves above carry the values. A document
388
+ * cannot be a JSON value, so it is sent as multipart on the channel call and
389
+ * reported here as a reference.
390
+ *
391
+ * Absent on a list read, which fetches identity but does not compute compliance
392
+ * documents per market. Absent and empty mean different things: absent says the
393
+ * documents were not fetched; empty says the market has been given none.
394
+ */
395
+ documents?: Array<Compliance.Document> | null;
396
+ }
397
+ namespace Compliance {
398
+ /**
399
+ * A document a market asked for and has been given.
400
+ */
401
+ interface Document {
402
+ /**
403
+ * Identifier of the upload, for fetching it back through the documents endpoints.
404
+ */
405
+ document_id?: string | null;
406
+ file_name?: string | null;
407
+ /**
408
+ * The catalog's name for this document, matching the requirement it satisfies.
409
+ */
410
+ key?: string;
411
+ }
412
+ }
413
+ }
414
+ /**
415
+ * The envelope Sent POSTs to a subscribed webhook endpoint. Every event shares
416
+ * this shape and varies only in Payload.
417
+ */
418
+ export interface ContactEvent {
419
+ /**
420
+ * The specific event within the family, for example message.delivered,
421
+ * message.received or contact.opt_out. Absent on events that have no subtype, so
422
+ * treat it as optional.
423
+ */
424
+ event?: string | null;
425
+ /**
426
+ * The event family, for example message, templates or contact. Route on this
427
+ * first, then on event for the specific change.
428
+ */
429
+ field?: string;
430
+ /**
431
+ * Body of a contact.opt_in, contact.opt_out, contact.help or
432
+ * contact.custom_keyword event. Delivered when a contact signals a consent change,
433
+ * asks for help, or sends one of your own auto-reply keywords.
434
+ *
435
+ * These events state the signal outright, so you do not have to recognise keywords
436
+ * in the text of a message.received event. They also cover cases that produce no
437
+ * inbound message at all, such as a network handling an opt-out on your behalf.
438
+ *
439
+ * Two of the four change consent and two do not: contact.help and
440
+ * contact.custom_keyword report the state the contact already had. Read opt_out
441
+ * for the state and the envelope's event for what happened, rather than inferring
442
+ * one from the other.
443
+ *
444
+ * Fields are ordered identity → resulting state → provenance → join keys. The two
445
+ * parties are from and to. Note that the message family has not moved to those
446
+ * names yet — message.received still calls the same two parties inbound_number and
447
+ * outbound_number. Nothing here restates the envelope: which signal occurred is
448
+ * the envelope's event, and when it was emitted is its timestamp. Retries carry
449
+ * the same X-Webhook-Event-ID header, which is what to deduplicate on.
450
+ */
451
+ payload?: ContactEventPayload | null;
452
+ /**
453
+ * The event-specific body.
454
+ */
455
+ request_id?: string | null;
456
+ /**
457
+ * When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
458
+ * time, not the time the underlying change happened. Use the timestamp inside the
459
+ * payload for the latter.
460
+ */
461
+ timestamp?: string;
462
+ }
463
+ /**
464
+ * Body of a contact.opt_in, contact.opt_out, contact.help or
465
+ * contact.custom_keyword event. Delivered when a contact signals a consent change,
466
+ * asks for help, or sends one of your own auto-reply keywords.
467
+ *
468
+ * These events state the signal outright, so you do not have to recognise keywords
469
+ * in the text of a message.received event. They also cover cases that produce no
470
+ * inbound message at all, such as a network handling an opt-out on your behalf.
471
+ *
472
+ * Two of the four change consent and two do not: contact.help and
473
+ * contact.custom_keyword report the state the contact already had. Read opt_out
474
+ * for the state and the envelope's event for what happened, rather than inferring
475
+ * one from the other.
476
+ *
477
+ * Fields are ordered identity → resulting state → provenance → join keys. The two
478
+ * parties are from and to. Note that the message family has not moved to those
479
+ * names yet — message.received still calls the same two parties inbound_number and
480
+ * outbound_number. Nothing here restates the envelope: which signal occurred is
481
+ * the envelope's event, and when it was emitted is its timestamp. Retries carry
482
+ * the same X-Webhook-Event-ID header, which is what to deduplicate on.
483
+ */
484
+ export interface ContactEventPayload {
485
+ /**
486
+ * Whether the contact is opted out after this signal — the state to write to your
487
+ * own record. Same meaning as opt_out on the contact resource. On contact.help and
488
+ * contact.custom_keyword this reports the contact's existing state, which neither
489
+ * changes.
490
+ *
491
+ * Two signals from the same contact can arrive out of order, because each one is
492
+ * queued on its own rather than against the contact. Compare the envelope's
493
+ * timestamp before you overwrite a newer state with an older one. That timestamp
494
+ * is second-precision, so treat two signals stamped in the same second as
495
+ * unordered and read the contact resource to settle them.
496
+ */
497
+ opt_out: boolean;
498
+ /**
499
+ * How the signal reached us. INBOUND_KEYWORD means the contact sent a message
500
+ * whose text matched one of the keywords; PROVIDER_SIGNAL means the network
501
+ * reported it. A provider signal usually carries no message_id or text, so read
502
+ * both for null rather than inferring them from this field.
503
+ */
504
+ source: string;
505
+ /**
506
+ * The account the contact belongs to. Present so one endpoint can serve several
507
+ * accounts.
508
+ */
509
+ account_id?: string;
510
+ /**
511
+ * The RCS agent the signal reached, when it reached one.
512
+ *
513
+ * Omitted entirely on channels that have no agent, rather than sent as null — an
514
+ * SMS or WhatsApp payload does not carry this key at all. On RCS it is the
515
+ * counterpart to To: a contact reaches an agent rather than a number, so exactly
516
+ * one of the two is populated and never both. If you run more than one agent, this
517
+ * is what tells you which of them the contact acted on.
518
+ */
519
+ agent_id?: string | null;
520
+ /**
521
+ * The channel the signal arrived on, for example sms or whatsapp.
522
+ */
523
+ channel?: string;
524
+ /**
525
+ * The contact who raised the signal. Always populated, including for contact.help
526
+ * or contact.custom_keyword from a number you have not messaged before — the
527
+ * contact is created if it does not exist yet, so this identifier is always
528
+ * resolvable against the contacts API.
529
+ */
530
+ contact_id?: string;
531
+ /**
532
+ * The contact's number, in E.164 format with the leading + — who raised the
533
+ * signal. The same party message.received publishes as inbound_number.
534
+ */
535
+ from?: string;
536
+ /**
537
+ * The inbound message that carried the signal, matching message_id on the
538
+ * corresponding message.received event so the two can be joined.
539
+ *
540
+ * Sent as null when the signal did not arrive as a message — for example when a
541
+ * network processed an opt-out on your behalf — and also when the message belongs
542
+ * to a different account than this event, which can happen on a shared WhatsApp
543
+ * number. The field is always present, so read it and check for null rather than
544
+ * checking whether the key exists.
545
+ */
546
+ message_id?: string | null;
547
+ /**
548
+ * The auto-reply template whose keyword the contact matched, joinable against the
549
+ * templates API.
550
+ *
551
+ * This is what identifies which signal arrived on contact.custom_keyword: every
552
+ * custom template reports the same event name, so the event alone cannot tell your
553
+ * booking keyword from your opening-hours one. One template holds as many keywords
554
+ * as you configured, so this is steadier to switch on than text.
555
+ *
556
+ * Populated on the compliance sub-types too, where it names the template that
557
+ * replied. Sent as null when no template was involved — a network-reported opt-out
558
+ * matches no keyword. The field is always present, so read it and check for null.
559
+ */
560
+ template_id?: string | null;
561
+ /**
562
+ * The text the contact sent, for example STOP or UNSUBSCRIBE. Sent as null when
563
+ * the signal did not arrive as text. The field is always present, so read it and
564
+ * check for null rather than checking whether the key exists.
565
+ */
566
+ text?: string | null;
567
+ /**
568
+ * The number of yours that received the signal, in E.164 format with the leading
569
+ * +. Tells a multi-number account which of its senders the contact acted on, which
570
+ * nothing else on this payload answers.
571
+ *
572
+ * This is your number, not the contact's. That is the opposite of what to means on
573
+ * POST /v3/messages, where it is the list of recipients you are sending to. Reply
574
+ * to From, not to this field, or the message goes back to yourself.
575
+ *
576
+ * Sent as null when the signal did not arrive at a number of yours — an RCS signal
577
+ * terminates at an agent rather than a number, and a provider-reported opt-out may
578
+ * name no receiving number at all. The field is always present, so read it and
579
+ * check for null rather than checking whether the key exists.
580
+ */
581
+ to?: string | null;
582
+ }
167
583
  /**
168
584
  * Error information
169
585
  */
@@ -193,14 +609,14 @@ export interface ErrorDetail {
193
609
  */
194
610
  export interface InboundMessageEvent {
195
611
  /**
196
- * The specific event within the family, for example message.delivered or
197
- * message.received. Absent on events that have no subtype, so treat it as
198
- * optional.
612
+ * The specific event within the family, for example message.delivered,
613
+ * message.received or contact.opt_out. Absent on events that have no subtype, so
614
+ * treat it as optional.
199
615
  */
200
616
  event?: string | null;
201
617
  /**
202
- * The event family, for example message or templates. Route on this first, then on
203
- * event for the specific change.
618
+ * The event family, for example message, templates or contact. Route on this
619
+ * first, then on event for the specific change.
204
620
  */
205
621
  field?: string;
206
622
  /**
@@ -208,6 +624,10 @@ export interface InboundMessageEvent {
208
624
  * numbers.
209
625
  */
210
626
  payload?: InboundMessageEventPayload | null;
627
+ /**
628
+ * The event-specific body.
629
+ */
630
+ request_id?: string | null;
211
631
  /**
212
632
  * When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
213
633
  * time, not the time the underlying change happened. Use the timestamp inside the
@@ -262,14 +682,14 @@ export interface InboundMessageEventPayload {
262
682
  */
263
683
  export interface MessageEvent {
264
684
  /**
265
- * The specific event within the family, for example message.delivered or
266
- * message.received. Absent on events that have no subtype, so treat it as
267
- * optional.
685
+ * The specific event within the family, for example message.delivered,
686
+ * message.received or contact.opt_out. Absent on events that have no subtype, so
687
+ * treat it as optional.
268
688
  */
269
689
  event?: string | null;
270
690
  /**
271
- * The event family, for example message or templates. Route on this first, then on
272
- * event for the specific change.
691
+ * The event family, for example message, templates or contact. Route on this
692
+ * first, then on event for the specific change.
273
693
  */
274
694
  field?: string;
275
695
  /**
@@ -278,6 +698,10 @@ export interface MessageEvent {
278
698
  * status.
279
699
  */
280
700
  payload?: MessageEventPayload | null;
701
+ /**
702
+ * The event-specific body.
703
+ */
704
+ request_id?: string | null;
281
705
  /**
282
706
  * When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
283
707
  * time, not the time the underlying change happened. Use the timestamp inside the
@@ -305,6 +729,12 @@ export interface MessageEventPayload {
305
729
  * The agent attributed to the send, when the send was attributed to one.
306
730
  */
307
731
  agent_id?: string | null;
732
+ /**
733
+ * The rendered message body, as plain text. Sent as null when we aren't asserting
734
+ * a body for this event. The field is always present, so read it and check for
735
+ * null rather than checking whether the key exists. Truncated to 3072 characters.
736
+ */
737
+ body?: string | null;
308
738
  /**
309
739
  * The channel the message went out on, for example sms or whatsapp. A message that
310
740
  * falls back to another channel reports the channel actually used.
@@ -319,6 +749,17 @@ export interface MessageEventPayload {
319
749
  * The recipient's number in E.164 format.
320
750
  */
321
751
  outbound_number?: string;
752
+ /**
753
+ * message.scheduled only: why the message is held, either because you scheduled it
754
+ * or because the recipient is inside a protected quiet-hours window. Omitted on
755
+ * every other event.
756
+ */
757
+ schedule_reason?: string | null;
758
+ /**
759
+ * message.scheduled only: when the held message will be released for delivery, in
760
+ * UTC (yyyy-MM-ddTHH:mm:ssZ). Omitted on every other event.
761
+ */
762
+ scheduled_at?: string | null;
322
763
  /**
323
764
  * The template the message was sent from, when it was sent from one.
324
765
  */
@@ -390,14 +831,14 @@ export declare namespace PaginationMeta {
390
831
  */
391
832
  export interface TemplateEvent {
392
833
  /**
393
- * The specific event within the family, for example message.delivered or
394
- * message.received. Absent on events that have no subtype, so treat it as
395
- * optional.
834
+ * The specific event within the family, for example message.delivered,
835
+ * message.received or contact.opt_out. Absent on events that have no subtype, so
836
+ * treat it as optional.
396
837
  */
397
838
  event?: string | null;
398
839
  /**
399
- * The event family, for example message or templates. Route on this first, then on
400
- * event for the specific change.
840
+ * The event family, for example message, templates or contact. Route on this
841
+ * first, then on event for the specific change.
401
842
  */
402
843
  field?: string;
403
844
  /**
@@ -405,6 +846,10 @@ export interface TemplateEvent {
405
846
  * changes, so you can react without polling.
406
847
  */
407
848
  payload?: TemplateEventPayload | null;
849
+ /**
850
+ * The event-specific body.
851
+ */
852
+ request_id?: string | null;
408
853
  /**
409
854
  * When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
410
855
  * time, not the time the underlying change happened. Use the timestamp inside the
@@ -430,14 +875,37 @@ export interface TemplateEventPayload {
430
875
  * The account the template belongs to.
431
876
  */
432
877
  account_id?: string;
878
+ /**
879
+ * Which consent keyword this template answers, when it is one of Sent's
880
+ * auto-replies: OPT_IN, OPT_OUT, HELP, or OTHER for a customer-defined keyword.
881
+ *
882
+ * Omitted for an ordinary template, so its presence is the answer to "is this an
883
+ * auto-reply". Sent creates the three compliance auto-replies at signup and they
884
+ * go through review like any other template, so their events arrive mixed in with
885
+ * the customer's own with nothing else to tell them apart.
886
+ *
887
+ * Named for the reader rather than after Template.OptAction, which it is mapped
888
+ * from. The MCP tool result deliberately keeps OptAction, OptKeywords and IsOpt:
889
+ * it mirrors the internal shape on purpose and publishes the keywords too, so
890
+ * renaming one of the three there would leave a surface half in each vocabulary.
891
+ * Two names for one concept, each consistent within its own surface, chosen over a
892
+ * rename that breaks MCP clients silently.
893
+ */
894
+ auto_reply_action?: string | null;
433
895
  /**
434
896
  * The template's category, for example UTILITY, MARKETING, or AUTHENTICATION.
435
897
  */
436
898
  category?: string;
437
899
  /**
438
- * The channel the template applies to.
900
+ * The channel leg this decision is about, for example whatsapp, sms, or rcs. A
901
+ * template is reviewed per channel and the legs come back independently, so each
902
+ * one reports separately.
903
+ *
904
+ * Omitted when the decision applies to the template as a whole rather than to one
905
+ * leg. That event is the broader news: a template-wide rejection blocks every
906
+ * channel, whatever the individual legs say.
439
907
  */
440
- channel?: string;
908
+ channel?: string | null;
441
909
  /**
442
910
  * The template's language code, for example en_US.
443
911
  */
@@ -531,17 +999,220 @@ export interface WebhookListEventsResponse {
531
999
  error_message?: string | null;
532
1000
  /**
533
1001
  * The exact event body that was delivered, or attempted, for this record. One of
534
- * the three webhook envelopes: a message status change, an inbound message, or a
535
- * template status change. Read field and event to tell which, the same way your
536
- * endpoint does.
1002
+ * the six webhook envelopes:
1003
+ *
1004
+ * message — an outbound message changed status. message with event:
1005
+ * message.received — someone replied to you. templates — a template was approved,
1006
+ * rejected, paused or similar. channel — one of your markets moved in provisioning
1007
+ * or compliance. contact — a consent signal: opt-in, opt-out or help. link — a
1008
+ * tracked short link was clicked or a hosted file downloaded, or one expired or
1009
+ * was revoked.
1010
+ *
1011
+ * Read field and event to tell which, the same way your endpoint does. The two
1012
+ * message envelopes are the reason that is two fields and not one: they share a
1013
+ * field and differ by event.
1014
+ *
1015
+ * Treat the list as open. It has grown twice — channel and then link — and a
1016
+ * handler that rejects an envelope it does not recognise will break on the next
1017
+ * addition rather than ignore it.
537
1018
  */
538
- event_data?: MessageEvent | InboundMessageEvent | TemplateEvent;
1019
+ event_data?: MessageEvent | InboundMessageEvent | TemplateEvent | ChannelEvent | ContactEvent | WebhookListEventsResponse.SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload;
539
1020
  event_type?: string;
540
1021
  http_status_code?: number | null;
541
1022
  processing_completed_at?: string | null;
542
1023
  processing_started_at?: string | null;
543
1024
  response_body?: string | null;
544
1025
  }
1026
+ export declare namespace WebhookListEventsResponse {
1027
+ /**
1028
+ * The envelope Sent POSTs to a subscribed webhook endpoint. Every event shares
1029
+ * this shape and varies only in Payload.
1030
+ */
1031
+ interface SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload {
1032
+ /**
1033
+ * The specific event within the family, for example message.delivered,
1034
+ * message.received or contact.opt_out. Absent on events that have no subtype, so
1035
+ * treat it as optional.
1036
+ */
1037
+ event?: string | null;
1038
+ /**
1039
+ * The event family, for example message, templates or contact. Route on this
1040
+ * first, then on event for the specific change.
1041
+ */
1042
+ field?: string;
1043
+ /**
1044
+ * Body of a link event: something happened to a tracked link Sent published on the
1045
+ * customer's behalf. A link points either at a URL the customer supplied or at a
1046
+ * file Sent hosts for them; LinkKind says which. Delivered when an eligible
1047
+ * request is served, or when a published link reaches the end of its life.
1048
+ *
1049
+ * A click is a request, not a read receipt. link.clicked means the redirect was
1050
+ * served; link.downloaded means bytes went out. Neither proves a person saw
1051
+ * anything — messaging providers and link scanners fetch URLs on their own, which
1052
+ * is what TrafficClass exists to tell apart. Filter on it before reporting a
1053
+ * click-through rate; treat likely_human as a hint, never as delivery
1054
+ * confirmation.
1055
+ *
1056
+ * RecordId identifies the link; the X-Webhook-Event-ID header identifies the
1057
+ * delivery. One link is hit many times, so those are the two keys a subscriber
1058
+ * needs: group by the first, deduplicate on the second — exactly as on every other
1059
+ * family. The payload carries no event identifier of its own, for the same reason
1060
+ * none of the others do.
1061
+ *
1062
+ * Nothing here identifies the visitor. No IP address and no visitor token crosses
1063
+ * this boundary. Country, Device and Browser are coarse buckets derived at the
1064
+ * edge and are absent whenever the request did not supply enough to derive them.
1065
+ */
1066
+ payload?: SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload.Payload | null;
1067
+ /**
1068
+ * The event-specific body.
1069
+ */
1070
+ request_id?: string | null;
1071
+ /**
1072
+ * When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
1073
+ * time, not the time the underlying change happened. Use the timestamp inside the
1074
+ * payload for the latter.
1075
+ */
1076
+ timestamp?: string;
1077
+ }
1078
+ namespace SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload {
1079
+ /**
1080
+ * Body of a link event: something happened to a tracked link Sent published on the
1081
+ * customer's behalf. A link points either at a URL the customer supplied or at a
1082
+ * file Sent hosts for them; LinkKind says which. Delivered when an eligible
1083
+ * request is served, or when a published link reaches the end of its life.
1084
+ *
1085
+ * A click is a request, not a read receipt. link.clicked means the redirect was
1086
+ * served; link.downloaded means bytes went out. Neither proves a person saw
1087
+ * anything — messaging providers and link scanners fetch URLs on their own, which
1088
+ * is what TrafficClass exists to tell apart. Filter on it before reporting a
1089
+ * click-through rate; treat likely_human as a hint, never as delivery
1090
+ * confirmation.
1091
+ *
1092
+ * RecordId identifies the link; the X-Webhook-Event-ID header identifies the
1093
+ * delivery. One link is hit many times, so those are the two keys a subscriber
1094
+ * needs: group by the first, deduplicate on the second — exactly as on every other
1095
+ * family. The payload carries no event identifier of its own, for the same reason
1096
+ * none of the others do.
1097
+ *
1098
+ * Nothing here identifies the visitor. No IP address and no visitor token crosses
1099
+ * this boundary. Country, Device and Browser are coarse buckets derived at the
1100
+ * edge and are absent whenever the request did not supply enough to derive them.
1101
+ */
1102
+ interface Payload {
1103
+ /**
1104
+ * The link's public identifier — the eight-character code in the short URL, for
1105
+ * example A78B2BU0. Unique across both kinds, and never reused, so it is the
1106
+ * stable key to group one link's events by.
1107
+ */
1108
+ record_id: string;
1109
+ /**
1110
+ * Where the request appeared to come from, as an ISO 3166-1 alpha-2 code. Named
1111
+ * separately from the country on a channel event, which is a destination market
1112
+ * the customer registered for — this one is a property of a single visitor and is
1113
+ * absent when the edge could not resolve it.
1114
+ */
1115
+ access_country?: string | null;
1116
+ /**
1117
+ * How the request was served, when the edge recorded it. Free text describing the
1118
+ * outcome — show it to a human rather than branching on it.
1119
+ */
1120
+ access_outcome?: string | null;
1121
+ /**
1122
+ * The requesting browser family, for example chrome or safari, or unknown. Derived
1123
+ * from the user agent.
1124
+ */
1125
+ browser?: string | null;
1126
+ /**
1127
+ * How many bytes were served, for a file access. A ranged request reports the
1128
+ * bytes in that range, not the size of the file, so several accesses of one file
1129
+ * can each report a part.
1130
+ */
1131
+ bytes_served?: number | null;
1132
+ /**
1133
+ * The channel the message carrying this link went out on: sms, whatsapp, or rcs.
1134
+ */
1135
+ channel?: string | null;
1136
+ /**
1137
+ * The organization the link belongs to. Always the parent account, never a sender
1138
+ * profile — read SenderProfileId for that.
1139
+ *
1140
+ * This family publishes the owner as an explicit pair rather than the single
1141
+ * account_id the other families use. The pair says which organization and which
1142
+ * profile without the subscriber deriving either, which is the trade: one more key
1143
+ * against not having to know that account_id silently becomes the profile when one
1144
+ * exists.
1145
+ */
1146
+ customer_id?: string;
1147
+ /**
1148
+ * The requesting device class: mobile, tablet, desktop or unknown. Derived from
1149
+ * the user agent.
1150
+ */
1151
+ device?: string | null;
1152
+ /**
1153
+ * What the link points at: url for a destination the customer supplied, file for
1154
+ * media Sent hosts. Always present, and implied by the event — link.clicked is
1155
+ * always url and link.downloaded always file — but published as its own field so a
1156
+ * subscriber can branch on the kind without parsing the event name, the same
1157
+ * separation the channel family keeps between its event and its status.
1158
+ */
1159
+ link_kind?: string;
1160
+ /**
1161
+ * The message the link was published in.
1162
+ *
1163
+ * The event can arrive before the message is readable through GET /v3/messages: a
1164
+ * provider may fetch a link within milliseconds of the send, and nothing here
1165
+ * waits for the message row. Retry the read rather than treating an unknown id as
1166
+ * an error.
1167
+ */
1168
+ message_id?: string | null;
1169
+ /**
1170
+ * When the access or lifecycle change actually happened, in UTC
1171
+ * (yyyy-MM-ddTHH:mm:ssZ). The envelope's timestamp is when Sent emitted the event;
1172
+ * this is when the thing occurred, and the two differ by the ingest delay.
1173
+ */
1174
+ occurred_at?: string;
1175
+ /**
1176
+ * The caller-supplied label tying this link back to a position in the message, for
1177
+ * example body:0 for the first link in the body. Present when the link was created
1178
+ * with one.
1179
+ */
1180
+ reference_key?: string | null;
1181
+ /**
1182
+ * The host of the page that linked here, when the request supplied one. The host
1183
+ * only — never a full referring URL.
1184
+ */
1185
+ referrer_host?: string | null;
1186
+ /**
1187
+ * The HTTP method of the request that was served, for an access event. Omitted on
1188
+ * link.expired and link.revoked, which describe no request.
1189
+ */
1190
+ request_method?: string | null;
1191
+ /**
1192
+ * The sender profile that owns the link, or null when the organization owns it
1193
+ * directly. Always on the wire so a handler reads one shape rather than branching
1194
+ * on whether the key arrived.
1195
+ *
1196
+ * sender_profile_id, not profile_id: the API already publishes
1197
+ * messaging_profile_id and sending_phone_number_profile_id for provider-side
1198
+ * profiles, which are a different thing entirely. The unqualified name would read
1199
+ * as one of those.
1200
+ */
1201
+ sender_profile_id?: string | null;
1202
+ /**
1203
+ * The HTTP status Sent answered the request with: 302 for a link, 200 or 206 for a
1204
+ * file. Omitted on lifecycle events.
1205
+ */
1206
+ status_code?: number | null;
1207
+ /**
1208
+ * A coarse guess at what made the request: likely_human, provider (a messaging
1209
+ * platform prefetching the link), bot, or unknown. Derived from the user agent, so
1210
+ * it is a hint for filtering noise rather than a fact to bill or report on.
1211
+ */
1212
+ traffic_class?: string | null;
1213
+ }
1214
+ }
1215
+ }
545
1216
  /**
546
1217
  * Standard API response envelope for all v3 endpoints
547
1218
  */
@@ -806,6 +1477,6 @@ export interface WebhookToggleStatusParams {
806
1477
  'x-profile-id'?: string;
807
1478
  }
808
1479
  export declare namespace Webhooks {
809
- export { type APIMeta as APIMeta, type APIResponseWebhook as APIResponseWebhook, type ErrorDetail as ErrorDetail, type InboundMessageEvent as InboundMessageEvent, type InboundMessageEventPayload as InboundMessageEventPayload, type MessageEvent as MessageEvent, type MessageEventPayload as MessageEventPayload, type MutationRequest as MutationRequest, type PaginationMeta as PaginationMeta, type TemplateEvent as TemplateEvent, type TemplateEventPayload as TemplateEventPayload, type WebhookEventType as WebhookEventType, type WebhookResponse as WebhookResponse, type WebhookListEventTypesResponse as WebhookListEventTypesResponse, type WebhookListEventsResponse as WebhookListEventsResponse, type WebhookRotateSecretResponse as WebhookRotateSecretResponse, type WebhookTestResponse as WebhookTestResponse, type WebhookResponsesWebhooksPage as WebhookResponsesWebhooksPage, type WebhookListEventsResponsesWebhookEventsPage as WebhookListEventsResponsesWebhookEventsPage, type WebhookCreateParams as WebhookCreateParams, type WebhookRetrieveParams as WebhookRetrieveParams, type WebhookUpdateParams as WebhookUpdateParams, type WebhookListParams as WebhookListParams, type WebhookDeleteParams as WebhookDeleteParams, type WebhookListEventTypesParams as WebhookListEventTypesParams, type WebhookListEventsParams as WebhookListEventsParams, type WebhookRotateSecretParams as WebhookRotateSecretParams, type WebhookTestParams as WebhookTestParams, type WebhookToggleStatusParams as WebhookToggleStatusParams, };
1480
+ export { type APIMeta as APIMeta, type APIResponseWebhook as APIResponseWebhook, type ChannelEvent as ChannelEvent, type ChannelEventPayload as ChannelEventPayload, type ContactEvent as ContactEvent, type ContactEventPayload as ContactEventPayload, type ErrorDetail as ErrorDetail, type InboundMessageEvent as InboundMessageEvent, type InboundMessageEventPayload as InboundMessageEventPayload, type MessageEvent as MessageEvent, type MessageEventPayload as MessageEventPayload, type MutationRequest as MutationRequest, type PaginationMeta as PaginationMeta, type TemplateEvent as TemplateEvent, type TemplateEventPayload as TemplateEventPayload, type WebhookEventType as WebhookEventType, type WebhookResponse as WebhookResponse, type WebhookListEventTypesResponse as WebhookListEventTypesResponse, type WebhookListEventsResponse as WebhookListEventsResponse, type WebhookRotateSecretResponse as WebhookRotateSecretResponse, type WebhookTestResponse as WebhookTestResponse, type WebhookResponsesWebhooksPage as WebhookResponsesWebhooksPage, type WebhookListEventsResponsesWebhookEventsPage as WebhookListEventsResponsesWebhookEventsPage, type WebhookCreateParams as WebhookCreateParams, type WebhookRetrieveParams as WebhookRetrieveParams, type WebhookUpdateParams as WebhookUpdateParams, type WebhookListParams as WebhookListParams, type WebhookDeleteParams as WebhookDeleteParams, type WebhookListEventTypesParams as WebhookListEventTypesParams, type WebhookListEventsParams as WebhookListEventsParams, type WebhookRotateSecretParams as WebhookRotateSecretParams, type WebhookTestParams as WebhookTestParams, type WebhookToggleStatusParams as WebhookToggleStatusParams, };
810
1481
  }
811
1482
  //# sourceMappingURL=webhooks.d.ts.map