@messagebird/sdk 0.46.0 → 0.48.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
@@ -18,6 +18,12 @@ interface RequestLifecycleOptions {
18
18
  timeout?: number;
19
19
  /** Max retry attempts. Overrides the client default. */
20
20
  maxRetries?: number;
21
+ /**
22
+ * A 3xx this operation answers on success. Set only where the contract is a
23
+ * redirect the caller must take itself, because the target is pre-authorized
24
+ * and must not receive this client's credentials.
25
+ */
26
+ successStatus?: number;
21
27
  }
22
28
  /** The shape a generated hey-api SDK call resolves to. */
23
29
  interface FetchOutcome<T> {
@@ -3500,6 +3506,9 @@ type VerificationChannelEntry = {
3500
3506
  * moved to the next channel.
3501
3507
  * - `channel_disabled`: Sending on the channel is temporarily disabled, so the
3502
3508
  * verification moved to the next channel.
3509
+ * - `channel_restricted`: The channel does not carry passcodes to this
3510
+ * destination country. The verification moves to the next channel enabled
3511
+ * there, or fails when the country has no other.
3503
3512
  * - `delivery_timeout`: No delivery confirmation arrived before the channel's
3504
3513
  * timeout, so the verification moved to the next channel.
3505
3514
  * - `not_billable`: The send could not be charged, so it was never handed to the
@@ -3509,7 +3518,7 @@ type VerificationChannelEntry = {
3509
3518
  * New reasons may be added over time. Treat unrecognized values as reasons added
3510
3519
  * later rather than errors.
3511
3520
  */
3512
- type VerificationAttemptFailureReason$1 = "carrier_rejected" | "hard_bounce" | "soft_bounce" | "undelivered" | "channel_unavailable" | "channel_disabled" | "delivery_timeout" | "not_billable" | (string & {});
3521
+ type VerificationAttemptFailureReason$1 = "carrier_rejected" | "hard_bounce" | "soft_bounce" | "undelivered" | "channel_unavailable" | "channel_disabled" | "channel_restricted" | "delivery_timeout" | "not_billable" | (string & {});
3513
3522
  /**
3514
3523
  * Meta's content classification for a template.
3515
3524
  *
@@ -3932,7 +3941,7 @@ type WhatsAppContactPhone = {
3932
3941
  */
3933
3942
  phone_number?: string;
3934
3943
  /**
3935
- * The label the contact's device attached, for example `CELL`, `Home` or `iPhone`. Free text passed through verbatim: WhatsApp declares no vocabulary here and does not normalize the casing, so neither do we.
3944
+ * The label attached to this value, for example `CELL`, `Home` or `iPhone`. Free text: WhatsApp defines no vocabulary. A label on a received card is lowercased; one this workspace sent reads back exactly as sent.
3936
3945
  *
3937
3946
  */
3938
3947
  type?: string;
@@ -3943,7 +3952,7 @@ type WhatsAppContactPhone = {
3943
3952
  type WhatsAppContactEmail = {
3944
3953
  email?: string;
3945
3954
  /**
3946
- * The label the contact's device attached, for example `Personal` or `Work`. Free text passed through verbatim.
3955
+ * The label attached to this value, for example `CELL`, `Home` or `iPhone`. Free text: WhatsApp defines no vocabulary. A label on a received card is lowercased; one this workspace sent reads back exactly as sent.
3947
3956
  *
3948
3957
  */
3949
3958
  type?: string;
@@ -3958,7 +3967,7 @@ type WhatsAppContactUrl = {
3958
3967
  */
3959
3968
  url?: string;
3960
3969
  /**
3961
- * The label the contact's device attached, for example `Company`. Free text passed through verbatim.
3970
+ * The label attached to this value, for example `CELL`, `Home` or `iPhone`. Free text: WhatsApp defines no vocabulary. A label on a received card is lowercased; one this workspace sent reads back exactly as sent.
3962
3971
  *
3963
3972
  */
3964
3973
  type?: string;
@@ -3978,24 +3987,24 @@ type WhatsAppContactAddress = {
3978
3987
  */
3979
3988
  country_code?: string;
3980
3989
  /**
3981
- * The label the contact's device attached, for example `Home`. Free text passed through verbatim.
3990
+ * The label attached to this value, for example `CELL`, `Home` or `iPhone`. Free text: WhatsApp defines no vocabulary. A label on a received card is lowercased; one this workspace sent reads back exactly as sent.
3982
3991
  *
3983
3992
  */
3984
3993
  type?: string;
3985
3994
  };
3986
3995
  /**
3987
- * A contact card the contact shared, either by tapping a button that asked for their number or by sending a card from their address book. Inbound only.
3996
+ * A contact card on this message: one the contact shared, or one this workspace sent.
3988
3997
  * Nothing here is required. WhatsApp sends the parts the card holds and omits the rest, and a card that arrives with only an `origin` is still meaningful, so an empty card reads back empty rather than being dropped.
3989
3998
  *
3990
3999
  */
3991
4000
  type WhatsAppContactCard = {
3992
4001
  /**
3993
- * Why the card arrived. `contact_request` means the contact tapped a button this workspace sent asking for their number, which is the only signal that the message answers that ask; `other` means they shared a card in the chat. Open enum: treat an unrecognized value as a way of sharing added since.
4002
+ * Why the card arrived. `contact_request` means the contact tapped a button this workspace sent asking for their number, which is the only signal that the message answers that ask; `other` means they shared a card in the chat. Open enum: treat an unrecognized value as a way of sharing added since. Set on a card the contact shared; absent on one this workspace sent.
3994
4003
  *
3995
4004
  */
3996
4005
  origin?: string;
3997
4006
  /**
3998
- * The contact's card in vCard format. WhatsApp sends it on a card shared in the chat and omits it on a button tap, which carries the number alone.
4007
+ * The contact's card in vCard format. WhatsApp sends it on a card shared in the chat and omits it on a button tap, which carries the number alone. Set on a card the contact shared; absent on one this workspace sent.
3999
4008
  *
4000
4009
  */
4001
4010
  vcard?: string;
@@ -4357,7 +4366,7 @@ type WhatsAppMessage = {
4357
4366
  */
4358
4367
  readonly location?: WhatsAppLocation;
4359
4368
  /**
4360
- * Contact cards the contact shared, either by tapping a button that asked for their number or by sending a card from their address book. Inbound only: sending a contact card is not supported.
4369
+ * Contact cards on this message: cards the contact shared, either by tapping a button that asked for their number or by sending one from their address book, or the cards this workspace sent.
4361
4370
  *
4362
4371
  */
4363
4372
  readonly contact_cards?: Array<WhatsAppContactCard>;
@@ -4817,6 +4826,114 @@ type WhatsAppInteractiveSend = ({
4817
4826
  */
4818
4827
  cards?: Array<WhatsAppInteractiveCardSend>;
4819
4828
  };
4829
+ /**
4830
+ * The contact's name. `formatted_name` is what the card shows, and WhatsApp additionally requires at least one of the parts below it, so a card carrying only a formatted name is rejected.
4831
+ *
4832
+ */
4833
+ type WhatsAppContactNameSend = {
4834
+ /**
4835
+ * The whole name, as the card should render it.
4836
+ */
4837
+ formatted_name: string;
4838
+ first_name?: string;
4839
+ middle_name?: string;
4840
+ last_name?: string;
4841
+ prefix?: string;
4842
+ suffix?: string;
4843
+ };
4844
+ /**
4845
+ * Where the contact works, as the card should record it.
4846
+ */
4847
+ type WhatsAppContactOrgSend = {
4848
+ company?: string;
4849
+ department?: string;
4850
+ title?: string;
4851
+ };
4852
+ /**
4853
+ * One phone number to put on a contact card.
4854
+ */
4855
+ type WhatsAppContactPhoneSend = {
4856
+ /**
4857
+ * The number to show. Send it in E.164 to get a card the recipient can message from; any other form still renders, with an invite button.
4858
+ *
4859
+ */
4860
+ phone_number: string;
4861
+ /**
4862
+ * A label for the number, shown beside it. Free text: WhatsApp defines no vocabulary, and the label is sent exactly as written.
4863
+ *
4864
+ */
4865
+ type?: string;
4866
+ };
4867
+ /**
4868
+ * One email address to put on a contact card.
4869
+ */
4870
+ type WhatsAppContactEmailSend = {
4871
+ email: string;
4872
+ /**
4873
+ * A label for the address, shown beside it. Free text, sent exactly as written.
4874
+ *
4875
+ */
4876
+ type?: string;
4877
+ };
4878
+ /**
4879
+ * One website to put on a contact card.
4880
+ */
4881
+ type WhatsAppContactUrlSend = {
4882
+ /**
4883
+ * The address to show. Not validated as a URL, because a card commonly carries a bare domain.
4884
+ *
4885
+ */
4886
+ url: string;
4887
+ /**
4888
+ * A label for the website, shown beside it. Free text, sent exactly as written.
4889
+ *
4890
+ */
4891
+ type?: string;
4892
+ };
4893
+ /**
4894
+ * One postal address to put on a contact card.
4895
+ */
4896
+ type WhatsAppContactAddressSend = {
4897
+ street?: string;
4898
+ city?: string;
4899
+ state?: string;
4900
+ zip?: string;
4901
+ country?: string;
4902
+ /**
4903
+ * The country as it should appear on the address, commonly the ISO two-letter code.
4904
+ */
4905
+ country_code?: string;
4906
+ /**
4907
+ * A label for the address, shown beside it. Free text, sent exactly as written.
4908
+ *
4909
+ */
4910
+ type?: string;
4911
+ };
4912
+ /**
4913
+ * A contact card to send. WhatsApp shows the name on the card and the rest in a profile view the recipient opens from it.
4914
+ * A card carrying a phone number renders buttons that message or save the contact; a card without one can only be added to an address book.
4915
+ *
4916
+ */
4917
+ type WhatsAppContactCardSend = {
4918
+ name: WhatsAppContactNameSend;
4919
+ /**
4920
+ * Where the contact works.
4921
+ */
4922
+ org?: WhatsAppContactOrgSend;
4923
+ /**
4924
+ * The contact's birthday, as `YYYY-MM-DD`. WhatsApp rejects any other shape, and a date no calendar holds is rejected too.
4925
+ *
4926
+ */
4927
+ birthday?: string;
4928
+ /**
4929
+ * The numbers on the card. A number in E.164 renders a button that opens a WhatsApp chat with it; one that is not renders an invite instead.
4930
+ *
4931
+ */
4932
+ phone_numbers?: Array<WhatsAppContactPhoneSend>;
4933
+ emails?: Array<WhatsAppContactEmailSend>;
4934
+ urls?: Array<WhatsAppContactUrlSend>;
4935
+ addresses?: Array<WhatsAppContactAddressSend>;
4936
+ };
4820
4937
  /**
4821
4938
  * A WhatsApp message to send. Carry exactly one kind of content: a request with none returns a `422` `WhatsAppContentRequired`, and one carrying more than one returns a `422` `WhatsAppContentAmbiguous`. The schema does not express that constraint, because which combinations are available depends on the content types your workspace can send.
4822
4939
  *
@@ -4877,6 +4994,11 @@ type WhatsAppMessageSendRequest = {
4877
4994
  *
4878
4995
  */
4879
4996
  interactive?: WhatsAppInteractiveSend;
4997
+ /**
4998
+ * Contact cards to send instead of a template. Up to five: WhatsApp accepts far more, and a message that opens as one name plus a count of the rest is not a card the recipient will read.
4999
+ *
5000
+ */
5001
+ contact_cards?: Array<WhatsAppContactCardSend>;
4880
5002
  /**
4881
5003
  * Quote a message the contact will see above this one, the way replying in the WhatsApp client does. Name a message from the same conversation: one this workspace sent to this recipient, or received from them. Any content quotes, template or free-form. A message this workspace does not hold, or one older than the 15-day window we keep provider ids for, returns a `422` `WhatsAppInReplyToNotFound`. A message that never reached WhatsApp, or one from a different conversation than this send's `to` and `from`, returns a `422` `WhatsAppInReplyToNotQuotable`.
4882
5004
  *
@@ -8850,6 +8972,11 @@ type EventWhatsAppBase = {
8850
8972
  metadata: {
8851
8973
  [key: string]: unknown;
8852
8974
  } | null;
8975
+ /**
8976
+ * The message this one answers. On an outbound message it is the `in_reply_to_message_id` the send request quoted. On an inbound message it is what WhatsApp reports as the reply's target: a tap on a button or a list row, and equally a text or media message the contact sent as a quoted reply. Absent when the message answers nothing, and absent on an inbound message whose target we cannot match to a message we hold, which is the case for one sent before this workspace started recording them or one already past the 15-day window we keep provider ids for.
8977
+ *
8978
+ */
8979
+ in_reply_to_message_id?: WhatsAppMessageId;
8853
8980
  };
8854
8981
  /**
8855
8982
  * Payload of the whatsapp.accepted event.
@@ -8970,6 +9097,11 @@ type EventWhatsAppReceivedData = EventWhatsAppBase & {
8970
9097
  *
8971
9098
  */
8972
9099
  contact_cards?: Array<WhatsAppContactCard>;
9100
+ /**
9101
+ * What the contact tapped, when the message answers an interactive message or a template's quick-reply button.
9102
+ *
9103
+ */
9104
+ interactive_reply?: WhatsAppInteractiveReply;
8973
9105
  /**
8974
9106
  * Set when the contact sent content the API does not model, naming the WhatsApp content type.
8975
9107
  *
@@ -9340,6 +9472,10 @@ type VoiceInboundForwardAs = "dialed_number" | "calling_number";
9340
9472
  * - `caller_id_not_verified`: The number in the `From` header is not a verified
9341
9473
  * caller ID for this workspace. Verify it, or present a number you have
9342
9474
  * already verified.
9475
+ * - `number_ownership_not_verified`: You bought this number, but the country that
9476
+ * issued it has not yet accepted the documents proving your workspace owns it.
9477
+ * Open the number under Numbers and complete its ownership requirements, then
9478
+ * place the call again.
9343
9479
  * - `destination_not_enabled`: You have not turned on calling to this
9344
9480
  * destination country. Enable it in your voice destination settings.
9345
9481
  * - `insufficient_balance`: Your wallet did not cover the call. Top up, or turn
@@ -9362,7 +9498,7 @@ type VoiceInboundForwardAs = "dialed_number" | "calling_number";
9362
9498
  * - `call_not_permitted`: The call could not be priced for your account.
9363
9499
  *
9364
9500
  */
9365
- type VoiceCallRejectionReason = "source_not_allowed" | "caller_id_not_verified" | "routing_not_configured" | "no_route_found" | "destination_blocked" | "destination_not_enabled" | "insufficient_balance" | "daily_spend_exceeded" | "concurrent_calls_exceeded" | "calls_per_second_exceeded" | "call_not_permitted";
9501
+ type VoiceCallRejectionReason = "source_not_allowed" | "caller_id_not_verified" | "routing_not_configured" | "no_route_found" | "destination_blocked" | "destination_not_enabled" | "insufficient_balance" | "daily_spend_exceeded" | "concurrent_calls_exceeded" | "calls_per_second_exceeded" | "call_not_permitted" | "number_ownership_not_verified";
9366
9502
  type VoiceCallInboundRouteReject = {
9367
9503
  /**
9368
9504
  * The number turned the call away. This is where every number starts, so it covers a number nobody has configured as well as one set to reject.
@@ -12877,7 +13013,7 @@ declare abstract class Resource {
12877
13013
  protected readonly client: Client;
12878
13014
  constructor(core: BirdHTTPClient, client: Client);
12879
13015
  /** Run a single typed call through the lifecycle. */
12880
- protected call<T>(method: string, options: RequestOptions | undefined, invoke: (ctx: CallContext) => Promise<FetchOutcome<T>>, schemes?: string[]): APIPromise<T>;
13016
+ protected call<T>(method: string, options: RequestOptions | undefined, invoke: (ctx: CallContext) => Promise<FetchOutcome<T>>, schemes?: string[], successStatus?: number): APIPromise<T>;
12881
13017
  /** Run a cursor-paginated list through the lifecycle (each page retried independently). */
12882
13018
  protected paginated<T>(method: string, options: RequestOptions | undefined, invoke: (ctx: CallContext, cursor: string | undefined) => Promise<FetchOutcome<CursorPage<T>>>, schemes?: string[]): PaginatedPromise<T>;
12883
13019
  }
@@ -14271,16 +14407,52 @@ declare class WhatsappResourceBase extends Resource {
14271
14407
  listEvents(messageId: string, query?: WhatsappListEventsQuery, options?: RequestOptions): APIPromise<WhatsAppEventList>;
14272
14408
  }
14273
14409
  //#endregion
14410
+ //#region src/resources/whatsappMessages.d.ts
14411
+ /**
14412
+ * Media downloaded from a received WhatsApp message. `contentType` is what
14413
+ * storage declared, which is the message's own `mime_type`.
14414
+ */
14415
+ interface WhatsappMedia {
14416
+ data: Uint8Array;
14417
+ contentType: string;
14418
+ contentLength: number;
14419
+ }
14420
+ declare class WhatsappMessagesResource extends Resource {
14421
+ /**
14422
+ * Download the media on a received WhatsApp message — an image, video, audio
14423
+ * clip, sticker or document. `mediaId` is the `id` on the message's content
14424
+ * object, which `bird.whatsapp.get` returns.
14425
+ *
14426
+ * Media is kept for 30 days after the message arrives; after that the message
14427
+ * still lists the media's `mime_type` and `caption`, and this throws. Outbound
14428
+ * messages carry no stored media.
14429
+ *
14430
+ * @example
14431
+ * const media = await bird.whatsapp.messages.media(
14432
+ * "wam_01kya19eknftrs2s6p82asmvnh",
14433
+ * "waf_01kyb2m4xq7whs0d8n3prv6tez",
14434
+ * );
14435
+ * console.log(media.contentType, media.contentLength);
14436
+ */
14437
+ media(messageId: string, mediaId: string, options?: RequestOptions): APIPromise<WhatsappMedia>;
14438
+ }
14439
+ //#endregion
14274
14440
  //#region src/resources/whatsapp.d.ts
14275
14441
  /** Body for `bird.whatsapp.send` — a template send, or one free-form content arm. */
14276
14442
  type WhatsappSendParams = WhatsAppMessageSendRequest;
14277
14443
  declare class WhatsappResource extends WhatsappResourceBase {
14444
+ /** Subresources of one message — `bird.whatsapp.messages.media(...)`. */
14445
+ readonly messages: WhatsappMessagesResource;
14446
+ constructor(core: ConstructorParameters<typeof Resource>[0], client: ConstructorParameters<typeof Resource>[1]);
14278
14447
  /**
14279
14448
  * Send one message, carrying exactly one kind of content: a template, or
14280
14449
  * free-form `text`, `image`, `video`, `audio`, `sticker`, `document`,
14281
- * `location` or `interactive` — the last being the arm that gives the
14282
- * recipient something to tap: reply buttons, a list menu, a link button,
14283
- * media cards, or a request for their location or contact details. Set
14450
+ * `location`, `contact_cards` or `interactive` — the last being the arm that
14451
+ * gives the recipient something to tap: reply buttons, a list menu, a link
14452
+ * button, media cards, or a request for their location or contact details.
14453
+ * `contact_cards` sends up to five contact cards: a card's `name` needs
14454
+ * `formatted_name` plus at least one other part, and a `phone_number` in
14455
+ * E.164 earns the card a button that opens a chat. Set
14284
14456
  * `in_reply_to_message_id` to quote an earlier message from the same
14285
14457
  * conversation. Every send but a Bird-managed
14286
14458
  * template needs `from`, a number this workspace owns. The result is
@@ -15291,6 +15463,7 @@ type TemplateStatusValue = (typeof TemplateStatus)[keyof typeof TemplateStatus];
15291
15463
  declare const VerificationAttemptFailureReason: {
15292
15464
  readonly CarrierRejected: "carrier_rejected";
15293
15465
  readonly ChannelDisabled: "channel_disabled";
15466
+ readonly ChannelRestricted: "channel_restricted";
15294
15467
  readonly ChannelUnavailable: "channel_unavailable";
15295
15468
  readonly DeliveryTimeout: "delivery_timeout";
15296
15469
  readonly HardBounce: "hard_bounce";
@@ -15436,5 +15609,5 @@ declare const WhatsAppTemplateParameterType: {
15436
15609
  /** A known WhatsAppTemplateParameterType value. */
15437
15610
  type WhatsAppTemplateParameterTypeValue = (typeof WhatsAppTemplateParameterType)[keyof typeof WhatsAppTemplateParameterType];
15438
15611
  //#endregion
15439
- export { type APIPromise, type Audience, type AudienceAddContactsParams, type AudienceCreateParams, type AudienceListContactsQuery, type AudienceListQuery, type AudienceMember, type AudienceRemoveContactsParams, type AudienceUpdateParams, BirdAPIError, BirdAuthError, BirdBadRequestError, BirdBillingError, BirdClient, type BirdClientOptions, BirdConflictError, BirdConnectionError, BirdError, BirdInternalError, BirdMisdirectedError, BirdMissingApiKeyError, BirdNotFoundError, BirdNotImplementedError, BirdPayloadTooLargeError, BirdPermissionError, BirdPreconditionError, BirdRateLimitError, type BirdRequest, type BirdResponse, BirdServiceUnavailableError, BirdTimeoutError, BirdValidationError, type BirdWebhookEvent, BirdWebhookVerificationError, type ChannelAuthorization, type Contact, type ContactBatchParams, type ContactCreateParams, type ContactListQuery, type ContactProperty, type ContactPropertyCreateParams, type ContactPropertyListQuery, type ContactPropertyUpdateParams, type ContactUpdateParams, type ContactUpsertResult, type ContactsPreferencesListQuery, type CursorPage, type DnsRecord, type Domain, type DomainCapabilities, type DomainCreateParams, type DomainDkim, type DomainListQuery, type DomainUpdateParams, type EmailChannelDefaults, EmailEventType, type EmailEventTypeValue, type EmailListQuery, type EmailLookup, EmailLookupFlag, type EmailLookupFlagValue, EmailLookupReason, type EmailLookupReasonValue, EmailLookupResult, type EmailLookupResultValue, type EmailMailboxLabelList, type EmailMailboxesCreateParams, type EmailMailboxesListQuery, type EmailMailboxesMessagesCreateParams, type EmailMailboxesReceiveRulesCreateParams, type EmailMailboxesReceiveRulesListQuery, type EmailMailboxesStatsQuery, type EmailMailboxesUpdateParams, type EmailMailboxesUpdateQuery, type EmailMessage, type EmailSendBatchParams, type EmailSendBatchResult, type EmailSendParams, type EmailStatsByBounceCodeQuery, type EmailStatsByBounceCodeResponse, type EmailStatsByBroadcastQuery, type EmailStatsByBroadcastResponse, type EmailStatsByCategoryQuery, type EmailStatsByCategoryResponse, type EmailStatsByClientQuery, type EmailStatsByClientResponse, type EmailStatsByComplaintTypeQuery, type EmailStatsByComplaintTypeResponse, type EmailStatsByLocationQuery, type EmailStatsByLocationResponse, type EmailStatsByMailboxProviderQuery, type EmailStatsByMailboxProviderRegionQuery, type EmailStatsByMailboxProviderRegionResponse, type EmailStatsByMailboxProviderResponse, type EmailStatsByRecipientDomainQuery, type EmailStatsByRecipientDomainResponse, type EmailStatsBySendingDomainQuery, type EmailStatsBySendingDomainResponse, type EmailStatsBySendingIpQuery, type EmailStatsBySendingIpResponse, type EmailStatsByTagQuery, type EmailStatsByTemplateQuery, type EmailStatsByTemplateResponse, type EmailStatsDailyQuery, type EmailStatsHourlyQuery, type EmailStatsResponse, type EmailStatsSummary, type EmailStatsSummaryQuery, type EmailStatsTagsResponse, type EmailThread, type EmailThreadMessage, type EmailThreadMessageAttachmentList, type EmailThreadMessageBody, type EmailThreadsDeleteQuery, type EmailThreadsListQuery, type EmailThreadsMessagesListQuery, type EmailThreadsMessagesReplyParams, type EmailThreadsUpdateParams, type ErrorDetail, type LookupEmailParams, LookupFlag, type LookupFlagValue, type LookupPhoneNumberParams, LookupPropertyStatus, type LookupPropertyStatusValue, type Mailbox, type MailboxStatsResponse, type NextAction, NumberCapability, type NumberCapabilityValue, NumberType, type NumberTypeValue, NumbersOrderStatus, type NumbersOrderStatusValue, type PaginatedPromise, type PhoneNumberLookup, type Preference, PreferenceChannel, type PreferenceChannelValue, type PreferenceCoverage, type PreferenceCreateParams, PreferenceOrigin, type PreferenceOriginValue, type PreferenceStatus, type PreferenceWriteResult, type PreferencesListQuery, type RealtimeBatchPublishResult, type RealtimeChannelGetQuery, type RealtimeChannelInclude, type RealtimeChannelInfo, type RealtimeChannelListItem, type RealtimeChannelListQuery, type RealtimeChannelMember, type RealtimeChannelMembers, type RealtimeChannelsList, type RealtimeOptions, type RealtimePublishBatchParams, type RealtimePublishParams, type RealtimePublishResult, type ReceiveRule, type RequestOptions, SMSErrorCode, type SMSErrorCodeValue, SMSKeywordOperation, type SMSKeywordOperationValue, SMSSuppressionCoverage, type SMSSuppressionCoverageValue, SMSSuppressionEndReason, type SMSSuppressionEndReasonValue, SMSSuppressionOrigin, type SMSSuppressionOriginValue, SMSSuppressionReason, type SMSSuppressionReasonValue, type SafeResult, type SmsEventList, type SmsInboundStatsByCountryResponse, type SmsInboundStatsByNumberResponse, type SmsInboundStatsByOperatorResponse, type SmsInboundStatsResponse, type SmsInboundStatsSummaryResponse, type SmsKeywordRule, type SmsKeywordRuleList, type SmsKeywordRulesCreateParams, type SmsKeywordRulesListQuery, type SmsKeywordRulesUpdateParams, type SmsListEventsQuery, type SmsListQuery, type SmsMessage, type SmsSendBatchParams, type SmsSendBatchResult, type SmsSendParams, type SmsStatsByCarrierQuery, type SmsStatsByCarrierResponse, type SmsStatsByCategoryQuery, type SmsStatsByCategoryResponse, type SmsStatsByCountryQuery, type SmsStatsByCountryResponse, type SmsStatsByErrorCodeQuery, type SmsStatsByErrorCodeResponse, type SmsStatsByOriginatorQuery, type SmsStatsByOriginatorResponse, type SmsStatsByStatusQuery, type SmsStatsByStatusResponse, type SmsStatsDailyQuery, type SmsStatsHourlyQuery, type SmsStatsInboundByCountryQuery, type SmsStatsInboundByNumberQuery, type SmsStatsInboundByOperatorQuery, type SmsStatsInboundDailyQuery, type SmsStatsInboundHourlyQuery, type SmsStatsInboundSummaryQuery, type SmsStatsResponse, type SmsStatsSummary, type SmsStatsSummaryQuery, type SmsSuppression, type SmsSuppressionsAddParams, type SmsSuppressionsListQuery, type SmsTemplate, type SmsTemplateList, type SmsTemplateListQuery, TemplateLanguageStatus, type TemplateLanguageStatusValue, TemplateStatus, type TemplateStatusValue, type Verification, VerificationAttemptFailureReason, type VerificationAttemptFailureReasonValue, VerificationChannel, type VerificationChannelValue, type VerificationCheckResult, VerificationTerminalReason, type VerificationTerminalReasonValue, type VerifyVerificationsCheckParams, type VerifyVerificationsCreateParams, type VerifyVerificationsNextChannelParams, type WebhookAttemptList, type WebhookEndpoint, type WebhookEndpointCreated, WebhookEventType, type WebhookEventTypeValue, type WebhookHeaders, type WebhookOptions, type WebhookRotateSecretResponse, type WebhookTestResponse, type WebhooksAttemptsQuery, type WebhooksCreateParams, type WebhooksListQuery, type WebhooksTestParams, type WebhooksUpdateParams, WhatsAppErrorCode, type WhatsAppErrorCodeValue, type WhatsAppEventList, WhatsAppEventType, type WhatsAppEventTypeValue, WhatsAppInteractiveButtonType, type WhatsAppInteractiveButtonTypeValue, WhatsAppInteractiveHeaderType, type WhatsAppInteractiveHeaderTypeValue, WhatsAppInteractiveReplyType, type WhatsAppInteractiveReplyTypeValue, WhatsAppInteractiveType, type WhatsAppInteractiveTypeValue, type WhatsAppMessage, WhatsAppTemplateCategory, type WhatsAppTemplateCategoryValue, WhatsAppTemplateParameterType, type WhatsAppTemplateParameterTypeValue, type WhatsappListEventsQuery, type WhatsappListQuery, type WhatsappSendParams, type Workspace, baseUrlForRegion, regionFromApiKey };
15612
+ export { type APIPromise, type Audience, type AudienceAddContactsParams, type AudienceCreateParams, type AudienceListContactsQuery, type AudienceListQuery, type AudienceMember, type AudienceRemoveContactsParams, type AudienceUpdateParams, BirdAPIError, BirdAuthError, BirdBadRequestError, BirdBillingError, BirdClient, type BirdClientOptions, BirdConflictError, BirdConnectionError, BirdError, BirdInternalError, BirdMisdirectedError, BirdMissingApiKeyError, BirdNotFoundError, BirdNotImplementedError, BirdPayloadTooLargeError, BirdPermissionError, BirdPreconditionError, BirdRateLimitError, type BirdRequest, type BirdResponse, BirdServiceUnavailableError, BirdTimeoutError, BirdValidationError, type BirdWebhookEvent, BirdWebhookVerificationError, type ChannelAuthorization, type Contact, type ContactBatchParams, type ContactCreateParams, type ContactListQuery, type ContactProperty, type ContactPropertyCreateParams, type ContactPropertyListQuery, type ContactPropertyUpdateParams, type ContactUpdateParams, type ContactUpsertResult, type ContactsPreferencesListQuery, type CursorPage, type DnsRecord, type Domain, type DomainCapabilities, type DomainCreateParams, type DomainDkim, type DomainListQuery, type DomainUpdateParams, type EmailChannelDefaults, EmailEventType, type EmailEventTypeValue, type EmailListQuery, type EmailLookup, EmailLookupFlag, type EmailLookupFlagValue, EmailLookupReason, type EmailLookupReasonValue, EmailLookupResult, type EmailLookupResultValue, type EmailMailboxLabelList, type EmailMailboxesCreateParams, type EmailMailboxesListQuery, type EmailMailboxesMessagesCreateParams, type EmailMailboxesReceiveRulesCreateParams, type EmailMailboxesReceiveRulesListQuery, type EmailMailboxesStatsQuery, type EmailMailboxesUpdateParams, type EmailMailboxesUpdateQuery, type EmailMessage, type EmailSendBatchParams, type EmailSendBatchResult, type EmailSendParams, type EmailStatsByBounceCodeQuery, type EmailStatsByBounceCodeResponse, type EmailStatsByBroadcastQuery, type EmailStatsByBroadcastResponse, type EmailStatsByCategoryQuery, type EmailStatsByCategoryResponse, type EmailStatsByClientQuery, type EmailStatsByClientResponse, type EmailStatsByComplaintTypeQuery, type EmailStatsByComplaintTypeResponse, type EmailStatsByLocationQuery, type EmailStatsByLocationResponse, type EmailStatsByMailboxProviderQuery, type EmailStatsByMailboxProviderRegionQuery, type EmailStatsByMailboxProviderRegionResponse, type EmailStatsByMailboxProviderResponse, type EmailStatsByRecipientDomainQuery, type EmailStatsByRecipientDomainResponse, type EmailStatsBySendingDomainQuery, type EmailStatsBySendingDomainResponse, type EmailStatsBySendingIpQuery, type EmailStatsBySendingIpResponse, type EmailStatsByTagQuery, type EmailStatsByTemplateQuery, type EmailStatsByTemplateResponse, type EmailStatsDailyQuery, type EmailStatsHourlyQuery, type EmailStatsResponse, type EmailStatsSummary, type EmailStatsSummaryQuery, type EmailStatsTagsResponse, type EmailThread, type EmailThreadMessage, type EmailThreadMessageAttachmentList, type EmailThreadMessageBody, type EmailThreadsDeleteQuery, type EmailThreadsListQuery, type EmailThreadsMessagesListQuery, type EmailThreadsMessagesReplyParams, type EmailThreadsUpdateParams, type ErrorDetail, type LookupEmailParams, LookupFlag, type LookupFlagValue, type LookupPhoneNumberParams, LookupPropertyStatus, type LookupPropertyStatusValue, type Mailbox, type MailboxStatsResponse, type NextAction, NumberCapability, type NumberCapabilityValue, NumberType, type NumberTypeValue, NumbersOrderStatus, type NumbersOrderStatusValue, type PaginatedPromise, type PhoneNumberLookup, type Preference, PreferenceChannel, type PreferenceChannelValue, type PreferenceCoverage, type PreferenceCreateParams, PreferenceOrigin, type PreferenceOriginValue, type PreferenceStatus, type PreferenceWriteResult, type PreferencesListQuery, type RealtimeBatchPublishResult, type RealtimeChannelGetQuery, type RealtimeChannelInclude, type RealtimeChannelInfo, type RealtimeChannelListItem, type RealtimeChannelListQuery, type RealtimeChannelMember, type RealtimeChannelMembers, type RealtimeChannelsList, type RealtimeOptions, type RealtimePublishBatchParams, type RealtimePublishParams, type RealtimePublishResult, type ReceiveRule, type RequestOptions, SMSErrorCode, type SMSErrorCodeValue, SMSKeywordOperation, type SMSKeywordOperationValue, SMSSuppressionCoverage, type SMSSuppressionCoverageValue, SMSSuppressionEndReason, type SMSSuppressionEndReasonValue, SMSSuppressionOrigin, type SMSSuppressionOriginValue, SMSSuppressionReason, type SMSSuppressionReasonValue, type SafeResult, type SmsEventList, type SmsInboundStatsByCountryResponse, type SmsInboundStatsByNumberResponse, type SmsInboundStatsByOperatorResponse, type SmsInboundStatsResponse, type SmsInboundStatsSummaryResponse, type SmsKeywordRule, type SmsKeywordRuleList, type SmsKeywordRulesCreateParams, type SmsKeywordRulesListQuery, type SmsKeywordRulesUpdateParams, type SmsListEventsQuery, type SmsListQuery, type SmsMessage, type SmsSendBatchParams, type SmsSendBatchResult, type SmsSendParams, type SmsStatsByCarrierQuery, type SmsStatsByCarrierResponse, type SmsStatsByCategoryQuery, type SmsStatsByCategoryResponse, type SmsStatsByCountryQuery, type SmsStatsByCountryResponse, type SmsStatsByErrorCodeQuery, type SmsStatsByErrorCodeResponse, type SmsStatsByOriginatorQuery, type SmsStatsByOriginatorResponse, type SmsStatsByStatusQuery, type SmsStatsByStatusResponse, type SmsStatsDailyQuery, type SmsStatsHourlyQuery, type SmsStatsInboundByCountryQuery, type SmsStatsInboundByNumberQuery, type SmsStatsInboundByOperatorQuery, type SmsStatsInboundDailyQuery, type SmsStatsInboundHourlyQuery, type SmsStatsInboundSummaryQuery, type SmsStatsResponse, type SmsStatsSummary, type SmsStatsSummaryQuery, type SmsSuppression, type SmsSuppressionsAddParams, type SmsSuppressionsListQuery, type SmsTemplate, type SmsTemplateList, type SmsTemplateListQuery, TemplateLanguageStatus, type TemplateLanguageStatusValue, TemplateStatus, type TemplateStatusValue, type Verification, VerificationAttemptFailureReason, type VerificationAttemptFailureReasonValue, VerificationChannel, type VerificationChannelValue, type VerificationCheckResult, VerificationTerminalReason, type VerificationTerminalReasonValue, type VerifyVerificationsCheckParams, type VerifyVerificationsCreateParams, type VerifyVerificationsNextChannelParams, type WebhookAttemptList, type WebhookEndpoint, type WebhookEndpointCreated, WebhookEventType, type WebhookEventTypeValue, type WebhookHeaders, type WebhookOptions, type WebhookRotateSecretResponse, type WebhookTestResponse, type WebhooksAttemptsQuery, type WebhooksCreateParams, type WebhooksListQuery, type WebhooksTestParams, type WebhooksUpdateParams, WhatsAppErrorCode, type WhatsAppErrorCodeValue, type WhatsAppEventList, WhatsAppEventType, type WhatsAppEventTypeValue, WhatsAppInteractiveButtonType, type WhatsAppInteractiveButtonTypeValue, WhatsAppInteractiveHeaderType, type WhatsAppInteractiveHeaderTypeValue, WhatsAppInteractiveReplyType, type WhatsAppInteractiveReplyTypeValue, WhatsAppInteractiveType, type WhatsAppInteractiveTypeValue, type WhatsAppMessage, WhatsAppTemplateCategory, type WhatsAppTemplateCategoryValue, WhatsAppTemplateParameterType, type WhatsAppTemplateParameterTypeValue, type WhatsappListEventsQuery, type WhatsappListQuery, type WhatsappMedia, type WhatsappSendParams, type Workspace, baseUrlForRegion, regionFromApiKey };
15440
15613
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1089,7 +1089,7 @@ var BirdHTTPClient = class {
1089
1089
  await retryOrThrow(() => new BirdConnectionError("No response received from the server"));
1090
1090
  continue;
1091
1091
  }
1092
- if (res.ok) return {
1092
+ if (res.ok || res.status === options.successStatus) return {
1093
1093
  data: outcome.data,
1094
1094
  response: toBirdResponse(res)
1095
1095
  };
@@ -2975,9 +2975,9 @@ const listWhatsAppMessages = (options) => (options?.client ?? client).get({
2975
2975
  *
2976
2976
  * Sends one WhatsApp message to one recipient. The request carries exactly one
2977
2977
  * kind of content: a message template, or free-form `text`, `image`, `video`,
2978
- * `audio`, `sticker`, `document`, `location` or `interactive`. A request
2979
- * carrying none is rejected with a `422`, and one carrying more than one is
2980
- * too.
2978
+ * `audio`, `sticker`, `document`, `location`, `contact_cards` or
2979
+ * `interactive`. A request carrying none is rejected with a `422`, and one
2980
+ * carrying more than one is too.
2981
2981
  *
2982
2982
  * A **template** is the only content WhatsApp delivers outside an open
2983
2983
  * customer service window, so it is what starts a conversation. Name the
@@ -3010,6 +3010,11 @@ const listWhatsAppMessages = (options) => (options?.client ?? client).get({
3010
3010
  * Interactive content is free-form, so the customer service window and the
3011
3011
  * `from` requirement above both apply.
3012
3012
  *
3013
+ * **Contact cards** share up to five contacts in one message. Each card's
3014
+ * `name` needs `formatted_name` plus at least one other part, and a
3015
+ * `phone_number` in E.164 earns that card a button opening a chat with it.
3016
+ * Contact cards are free-form too, so the same window and `from` rules apply.
3017
+ *
3013
3018
  * Set `in_reply_to_message_id` to quote a message the contact sees above this
3014
3019
  * one, the way replying in the WhatsApp client does. Any content quotes, and
3015
3020
  * the quoted message must be one from this same conversation.
@@ -3086,6 +3091,42 @@ const listWhatsAppMessageEvents = (options) => (options.client ?? client).get({
3086
3091
  ...options
3087
3092
  });
3088
3093
  /**
3094
+ * Get a WhatsApp message's media
3095
+ *
3096
+ * Redirects to a short-lived URL for the media on a received WhatsApp message.
3097
+ * Inbound media is stored because WhatsApp's own URL is not fetchable
3098
+ * without our credentials; this endpoint is what the `url` on the message's
3099
+ * `image`, `video`, `audio`, `sticker` or `document` points at. The bytes
3100
+ * live in object storage and are served straight from there, so they never
3101
+ * transit the API.
3102
+ *
3103
+ * The response is a `302` whose `Location` is that pre-authorized storage URL,
3104
+ * valid for 15 minutes; your client must follow redirects. The `Authorization`
3105
+ * header must be absent from the request that fetches that URL: a client that
3106
+ * attaches credentials centrally, at its transport, interceptor or middleware
3107
+ * layer rather than per request, re-adds the header on every hop including the
3108
+ * redirect, so the storage URL must be fetched with a client that carries
3109
+ * none.
3110
+ *
3111
+ * Media is kept for 30 days after the message is received, and the message
3112
+ * itself is kept longer. A message older than that still lists its media's
3113
+ * `mime_type` and `caption`, and this operation returns `410` once the bytes
3114
+ * have expired. Outbound messages have no media to serve.
3115
+ *
3116
+ */
3117
+ const getWhatsAppMessageMedia = (options) => (options.client ?? client).get({
3118
+ security: [{
3119
+ scheme: "bearer",
3120
+ type: "http"
3121
+ }, {
3122
+ in: "cookie",
3123
+ name: "bird_session",
3124
+ type: "apiKey"
3125
+ }],
3126
+ url: "/v1/whatsapp/messages/{message_id}/media/{media_id}",
3127
+ ...options
3128
+ });
3129
+ /**
3089
3130
  * Get daily sending statistics
3090
3131
  *
3091
3132
  * 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.
@@ -4424,9 +4465,12 @@ var Resource = class {
4424
4465
  this.client = client;
4425
4466
  }
4426
4467
  /** Run a single typed call through the lifecycle. */
4427
- call(method, options, invoke, schemes) {
4468
+ call(method, options, invoke, schemes, successStatus) {
4428
4469
  const credentials = this.core.credentialHeaders(schemes, options?.credentials);
4429
- return apiPromise(this.core.request((ctx) => invoke(callContext(ctx, options, credentials)), lifecycle(method, options)));
4470
+ return apiPromise(this.core.request((ctx) => invoke(callContext(ctx, options, credentials)), {
4471
+ ...lifecycle(method, options),
4472
+ successStatus
4473
+ }));
4430
4474
  }
4431
4475
  /** Run a cursor-paginated list through the lifecycle (each page retried independently). */
4432
4476
  paginated(method, options, invoke, schemes) {
@@ -6649,14 +6693,107 @@ var WhatsappResourceBase = class extends Resource {
6649
6693
  }
6650
6694
  };
6651
6695
  //#endregion
6696
+ //#region src/resources/whatsappMessages.ts
6697
+ var WhatsappMessagesResource = class extends Resource {
6698
+ /**
6699
+ * Download the media on a received WhatsApp message — an image, video, audio
6700
+ * clip, sticker or document. `mediaId` is the `id` on the message's content
6701
+ * object, which `bird.whatsapp.get` returns.
6702
+ *
6703
+ * Media is kept for 30 days after the message arrives; after that the message
6704
+ * still lists the media's `mime_type` and `caption`, and this throws. Outbound
6705
+ * messages carry no stored media.
6706
+ *
6707
+ * @example
6708
+ * const media = await bird.whatsapp.messages.media(
6709
+ * "wam_01kya19eknftrs2s6p82asmvnh",
6710
+ * "waf_01kyb2m4xq7whs0d8n3prv6tez",
6711
+ * );
6712
+ * console.log(media.contentType, media.contentLength);
6713
+ */
6714
+ media(messageId, mediaId, options) {
6715
+ return this.call("GET", options, async ({ signal, headers }) => {
6716
+ const outcome = await getWhatsAppMessageMedia({
6717
+ client: this.client,
6718
+ path: {
6719
+ message_id: messageId,
6720
+ media_id: mediaId
6721
+ },
6722
+ headers,
6723
+ signal,
6724
+ redirect: "manual",
6725
+ parseAs: "arrayBuffer"
6726
+ });
6727
+ const res = outcome.response;
6728
+ if (!res) return outcome;
6729
+ if (res.status !== 302) {
6730
+ if (!res.ok) return outcome;
6731
+ return {
6732
+ data: mediaFrom(res, outcome.data),
6733
+ response: res
6734
+ };
6735
+ }
6736
+ const location = res.headers.get("Location");
6737
+ if (!location) throw new BirdConnectionError("media redirect carried no Location header");
6738
+ const stored = await fetchStorage(this.client.getConfig().fetch ?? fetch, location, signal);
6739
+ return {
6740
+ data: mediaFrom(stored.response, stored.body),
6741
+ response: res
6742
+ };
6743
+ }, void 0, 302);
6744
+ }
6745
+ };
6746
+ /**
6747
+ * The second leg. Not a Bird API request — a different host, a credential of
6748
+ * its own, and an XML error body that is no Bird error envelope — so it runs
6749
+ * outside the request core and its failures surface as connection errors.
6750
+ * Running a storage 403 through the API error mapper would report the caller's
6751
+ * own key as lacking permission, which is not what happened.
6752
+ *
6753
+ * It reuses the client's configured `fetch` (a proxy or edge adapter still
6754
+ * applies) but sends no headers at all, which is what keeps the credential off
6755
+ * the wire.
6756
+ */
6757
+ async function fetchStorage(fetchFn, location, signal) {
6758
+ let response;
6759
+ try {
6760
+ response = await fetchFn(location, { signal });
6761
+ } catch (err) {
6762
+ if (signal.aborted) throw err;
6763
+ throw new BirdConnectionError(`downloading media failed: ${err instanceof Error ? err.message : String(err)} — call media again for a fresh link`);
6764
+ }
6765
+ if (!response.ok) throw new BirdConnectionError(`storage refused the download link (status ${response.status}) — the link expired or was refused; call media again for a fresh link`);
6766
+ return {
6767
+ response,
6768
+ body: await response.arrayBuffer()
6769
+ };
6770
+ }
6771
+ function mediaFrom(response, body) {
6772
+ const data = new Uint8Array(body);
6773
+ return {
6774
+ data,
6775
+ contentType: response.headers.get("Content-Type") ?? "application/octet-stream",
6776
+ contentLength: data.length
6777
+ };
6778
+ }
6779
+ //#endregion
6652
6780
  //#region src/resources/whatsapp.ts
6653
6781
  var WhatsappResource = class extends WhatsappResourceBase {
6782
+ /** Subresources of one message — `bird.whatsapp.messages.media(...)`. */
6783
+ messages;
6784
+ constructor(core, client) {
6785
+ super(core, client);
6786
+ this.messages = new WhatsappMessagesResource(core, client);
6787
+ }
6654
6788
  /**
6655
6789
  * Send one message, carrying exactly one kind of content: a template, or
6656
6790
  * free-form `text`, `image`, `video`, `audio`, `sticker`, `document`,
6657
- * `location` or `interactive` — the last being the arm that gives the
6658
- * recipient something to tap: reply buttons, a list menu, a link button,
6659
- * media cards, or a request for their location or contact details. Set
6791
+ * `location`, `contact_cards` or `interactive` — the last being the arm that
6792
+ * gives the recipient something to tap: reply buttons, a list menu, a link
6793
+ * button, media cards, or a request for their location or contact details.
6794
+ * `contact_cards` sends up to five contact cards: a card's `name` needs
6795
+ * `formatted_name` plus at least one other part, and a `phone_number` in
6796
+ * E.164 earns the card a button that opens a chat. Set
6660
6797
  * `in_reply_to_message_id` to quote an earlier message from the same
6661
6798
  * conversation. Every send but a Bird-managed
6662
6799
  * template needs `from`, a number this workspace owns. The result is
@@ -7790,9 +7927,9 @@ var BirdClient = class {
7790
7927
  this.#headers = {
7791
7928
  ...opts.defaultHeaders,
7792
7929
  ...opts.apiKey ? { Authorization: `Bearer ${opts.apiKey}` } : {},
7793
- "User-Agent": `bird-sdk-js/0.46.0`,
7930
+ "User-Agent": `bird-sdk-js/0.48.0`,
7794
7931
  "Bird-Surface": "sdk-js",
7795
- "Bird-Version": "0.46.0"
7932
+ "Bird-Version": "0.48.0"
7796
7933
  };
7797
7934
  const caller = detectCaller();
7798
7935
  if (caller) this.#headers["Bird-Caller"] = caller;
@@ -8182,6 +8319,7 @@ const TemplateStatus = {
8182
8319
  const VerificationAttemptFailureReason = {
8183
8320
  CarrierRejected: "carrier_rejected",
8184
8321
  ChannelDisabled: "channel_disabled",
8322
+ ChannelRestricted: "channel_restricted",
8185
8323
  ChannelUnavailable: "channel_unavailable",
8186
8324
  DeliveryTimeout: "delivery_timeout",
8187
8325
  HardBounce: "hard_bounce",