@messagebird/sdk 0.10.1 → 0.12.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
@@ -481,7 +481,7 @@ type EventWhatsAppAccepted = {
481
481
  data: EventWhatsAppAcceptedData;
482
482
  };
483
483
  /**
484
- * Payload of the voice.call.initiated event.
484
+ * Payload of the voice_call.initiated event.
485
485
  */
486
486
  type EventVoiceCallInitiatedData = EventVoiceBase;
487
487
  /**
@@ -523,7 +523,7 @@ type EventVoiceCallInitiated = {
523
523
  /**
524
524
  * Event type.
525
525
  */
526
- type: "voice.call.initiated";
526
+ type: "voice_call.initiated";
527
527
  /**
528
528
  * Time the call was initiated.
529
529
  */
@@ -536,7 +536,7 @@ type EventVoiceCallInitiated = {
536
536
  */
537
537
  type VoiceCallStatus = "answered" | "no_answer" | "busy" | "canceled" | "failed" | "rejected" | "unknown" | "ringing" | "in_progress";
538
538
  /**
539
- * Payload of the voice.call.ended event.
539
+ * Payload of the voice_call.ended event.
540
540
  */
541
541
  type EventVoiceCallEndedData = EventVoiceBase & {
542
542
  status: VoiceCallStatus;
@@ -560,7 +560,7 @@ type EventVoiceCallEnded = {
560
560
  /**
561
561
  * Event type.
562
562
  */
563
- type: "voice.call.ended";
563
+ type: "voice_call.ended";
564
564
  /**
565
565
  * When the call ended (BYE or final non-2xx response).
566
566
  */
@@ -568,7 +568,7 @@ type EventVoiceCallEnded = {
568
568
  data: EventVoiceCallEndedData;
569
569
  };
570
570
  /**
571
- * Payload of the voice.call.answered event.
571
+ * Payload of the voice_call.answered event.
572
572
  */
573
573
  type EventVoiceCallAnsweredData = EventVoiceBase;
574
574
  /**
@@ -578,7 +578,7 @@ type EventVoiceCallAnswered = {
578
578
  /**
579
579
  * Event type.
580
580
  */
581
- type: "voice.call.answered";
581
+ type: "voice_call.answered";
582
582
  /**
583
583
  * Time the call was answered.
584
584
  */
@@ -1818,11 +1818,11 @@ type WebhookEvent = ({
1818
1818
  } & EventSmsTfnVerificationSubmitted) | ({
1819
1819
  type: "sms.undelivered";
1820
1820
  } & EventSmsUndelivered) | ({
1821
- type: "voice.call.answered";
1821
+ type: "voice_call.answered";
1822
1822
  } & EventVoiceCallAnswered) | ({
1823
- type: "voice.call.ended";
1823
+ type: "voice_call.ended";
1824
1824
  } & EventVoiceCallEnded) | ({
1825
- type: "voice.call.initiated";
1825
+ type: "voice_call.initiated";
1826
1826
  } & EventVoiceCallInitiated) | ({
1827
1827
  type: "whatsapp.accepted";
1828
1828
  } & EventWhatsAppAccepted) | ({
@@ -1840,18 +1840,968 @@ type Timestamps = {
1840
1840
  readonly created_at: string;
1841
1841
  readonly updated_at: string;
1842
1842
  };
1843
+ type ListEnvelope = {
1844
+ /**
1845
+ * Cursor for the next page. Pass back as `starting_after` to advance forward. Null when no next page exists.
1846
+ */
1847
+ next_cursor: string | null;
1848
+ /**
1849
+ * Cursor for the previous page. Pass back as `ending_before` to step backward. Null when no previous page exists.
1850
+ */
1851
+ prev_cursor: string | null;
1852
+ /**
1853
+ * Refresh anchor. Pass back as `ending_before` later to fetch items that have appeared since this response. Non-null whenever `data` is non-empty; null only on an empty page. Distinct from `prev_cursor`.
1854
+ */
1855
+ refresh_cursor: string | null;
1856
+ };
1857
+ /**
1858
+ * The labels available in a mailbox.
1859
+ */
1860
+ type EmailMailboxLabelList = {
1861
+ data: Array<EmailMailboxLabel>;
1862
+ };
1863
+ /**
1864
+ * One label available in a mailbox.
1865
+ */
1866
+ type EmailMailboxLabel = {
1867
+ /**
1868
+ * The label name, as it appears on conversations and messages.
1869
+ */
1870
+ readonly name: string;
1871
+ /**
1872
+ * `system` labels are built in and carry state — the placements `inbox`, `archive`, `spam`, `blocked`, and `sent`, plus `trash` and `unread`. `custom` labels are the workspace's own tags.
1873
+ */
1874
+ readonly type: "system" | "custom";
1875
+ };
1876
+ /**
1877
+ * A new message sent from a mailbox, starting a new conversation. Mirrors the plain send request minus `from` — the mailbox is the sender identity — and minus `scheduled_at` (mailbox sends are immediate). Bird mints the RFC 5322 Message-ID so replies thread back to this conversation. At least one of `html` or `text` must be provided.
1878
+ *
1879
+ */
1880
+ type EmailMailboxComposeRequest = {
1881
+ /**
1882
+ * Primary recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@example.com>`), or an object with an optional display name.
1883
+ */
1884
+ to: Array<EmailAddressInput>;
1885
+ /**
1886
+ * CC recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@example.com>`), or an object with an optional display name.
1887
+ */
1888
+ cc?: Array<EmailAddressInput>;
1889
+ /**
1890
+ * BCC recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@example.com>`), or an object with an optional display name.
1891
+ */
1892
+ bcc?: Array<EmailAddressInput>;
1893
+ /**
1894
+ * Message subject line.
1895
+ */
1896
+ subject: string;
1897
+ /**
1898
+ * HTML body. At least one of html or text must be provided.
1899
+ */
1900
+ html?: string;
1901
+ /**
1902
+ * Plain-text body. At least one of html or text must be provided.
1903
+ */
1904
+ text?: string;
1905
+ /**
1906
+ * Reply-To addresses. When omitted, the mailbox's `default_reply_to` applies (replies then come back to the mailbox itself).
1907
+ *
1908
+ */
1909
+ reply_to?: Array<EmailAddressInput>;
1910
+ /**
1911
+ * File attachments. The send is rejected when the estimated generated message size exceeds 20 MB (bodies plus all attachments after base64 encoding). Attachment metadata endures on the message's `attachment_manifest`; the bytes are downloadable for 30 days.
1912
+ *
1913
+ */
1914
+ attachments?: Array<EmailAttachment>;
1915
+ /**
1916
+ * Structured `{name, value}` labels for filtering and analytics on the sent-message log. Cap: 20 tags per send.
1917
+ *
1918
+ */
1919
+ tags?: Array<Tag>;
1920
+ /**
1921
+ * Arbitrary JSON object stored on the send and echoed in webhook payloads. Cap: 2 KB serialized.
1922
+ *
1923
+ */
1924
+ metadata?: {
1925
+ [key: string]: unknown;
1926
+ };
1927
+ /**
1928
+ * Content classification — controls suppression policy. `marketing` blocks on all suppression reasons; `transactional` allows delivery through complaint and unsubscribe suppressions. Default: transactional.
1929
+ *
1930
+ */
1931
+ category?: "marketing" | "transactional";
1932
+ };
1933
+ /**
1934
+ * File attached to an email send. The attachment bytes are passed as base64-encoded `content` directly in the request body (required). The `path` field (provide a URL and Bird fetches the attachment for you) is a preview feature and currently unavailable. Requests are rejected with 422 if `content` is missing — `path` alone does not satisfy the schema. When `path` becomes generally available, the schema will be relaxed so that exactly one of `content` or `path` is required.
1935
+ * Inline images for `<img src="cid:..."/>` references in the HTML body use the `content_id` field together with `content`.
1936
+ * Bird enforces a **20 MB estimated generated message size** cap. The estimate is the HTML and text body plus all attachments and inline images measured after base64 encoding. This is not a raw file-size cap. As a rule of thumb, keep total raw attachment content at or below **15 MB** so the generated message has enough room after encoding and MIME wrapping.
1937
+ * Recipient-side delivery reality: downstream limits vary by product and tenant/server policy. Gmail personal and Outlook.com document 25 MB attachment limits. Exchange Online defaults to 35 MB send / 36 MB receive, but admins can configure limits; on-prem Exchange Server organizational defaults are 10 MB. Sends close to Bird's 20 MB generated-message cap may be accepted by Bird but bounce at the recipient's mail server.
1938
+ * Batch sends can include attachments on individual message objects. Each message still has the 20 MB estimated generated-size cap, and the serialized JSON request body for the whole batch has a hard 20 MB cap. Certain executable / script content types are rejected at validation time.
1939
+ *
1940
+ */
1941
+ type EmailAttachment = {
1942
+ /**
1943
+ * Filename shown to the recipient. Required.
1944
+ */
1945
+ filename: string;
1946
+ /**
1947
+ * Base64-encoded attachment bytes. Required. Counts toward the 20 MB estimated generated message-size cap after encoding and MIME wrapping.
1948
+ *
1949
+ */
1950
+ content: string;
1951
+ /**
1952
+ * Preview feature — provide a URL and Bird fetches the attachment for you. Currently unavailable. Use `content` instead. The schema currently requires `content`, so a request with only `path` is rejected with 422 for missing `content`; a request supplying both `content` and `path` is rejected with 422 `UnsupportedEmailFeature` until this preview ships. When generally available: HTTPS-only, single redirect followed and re-validated, private IP ranges blocked, request timeout enforced, fetched content counts toward the 20 MB estimated generated message-size cap after encoding and MIME wrapping.
1953
+ *
1954
+ */
1955
+ path?: string;
1956
+ /**
1957
+ * MIME type. Inferred from `filename` extension when omitted. Used to enforce the blocklist of disallowed executable / script types.
1958
+ *
1959
+ */
1960
+ content_type?: string;
1961
+ /**
1962
+ * RFC 2392 Content-ID. When set, the attachment is rendered inline and can be referenced from the HTML body as `<img src="cid:{content_id}"/>`. When omitted, the attachment is rendered as a regular file attachment.
1963
+ *
1964
+ */
1965
+ content_id?: string;
1966
+ };
1843
1967
  /**
1844
1968
  * An email address with an optional display name.
1845
1969
  */
1846
1970
  type EmailAddress = {
1847
1971
  /**
1848
- * Email address.
1972
+ * Email address.
1973
+ */
1974
+ email: string;
1975
+ /**
1976
+ * Display name shown alongside the address in mail clients.
1977
+ */
1978
+ name?: string;
1979
+ };
1980
+ /**
1981
+ * A sender or recipient address. Accepts a plain email string (`jane@example.com`), an RFC 5322 mailbox string with an embedded display name (`Jane Doe <jane@example.com>`), or an object carrying the address and an optional display name. All forms can be mixed freely within one request; responses always return the object form.
1982
+ *
1983
+ */
1984
+ type EmailAddressInput = string | EmailAddress;
1985
+ /**
1986
+ * A reply to a conversation message. Recipients are derived from the message being replied to: its Reply-To address when present, otherwise its From address. Set `reply_all` to also include the original To and Cc recipients (minus the mailbox's own address). The subject and threading headers are set automatically. At least one of `html` or `text` must be provided.
1987
+ *
1988
+ */
1989
+ type EmailThreadMessageReplyRequest = {
1990
+ /**
1991
+ * HTML body of the reply. At least one of html or text must be provided.
1992
+ */
1993
+ html?: string;
1994
+ /**
1995
+ * Plain-text body of the reply. At least one of html or text must be provided.
1996
+ */
1997
+ text?: string;
1998
+ /**
1999
+ * Also send the reply to the original To and Cc recipients, minus the mailbox's own address.
2000
+ */
2001
+ reply_all?: boolean;
2002
+ /**
2003
+ * Structured `{name, value}` labels for filtering and analytics on the sent-message log. Cap: 20 tags per send.
2004
+ *
2005
+ */
2006
+ tags?: Array<Tag>;
2007
+ /**
2008
+ * Arbitrary JSON object stored on the send and echoed in webhook payloads. Cap: 2 KB serialized.
2009
+ *
2010
+ */
2011
+ metadata?: {
2012
+ [key: string]: unknown;
2013
+ };
2014
+ /**
2015
+ * Content classification — controls suppression policy. `marketing` blocks on all suppression reasons; `transactional` allows delivery through complaint and unsubscribe suppressions. Default: transactional.
2016
+ *
2017
+ */
2018
+ category?: "marketing" | "transactional";
2019
+ };
2020
+ /**
2021
+ * The attachments on a conversation message.
2022
+ */
2023
+ type EmailThreadMessageAttachmentList = {
2024
+ data: Array<EmailThreadMessageAttachment>;
2025
+ };
2026
+ /**
2027
+ * Attachment metadata on a conversation message. The metadata remains readable for the mailbox's retention period; the attachment bytes are downloadable for 30 days after the message occurred.
2028
+ *
2029
+ */
2030
+ type EmailThreadMessageAttachment = {
2031
+ /**
2032
+ * Attachment ID, used to download the attachment bytes.
2033
+ */
2034
+ readonly id: string;
2035
+ /**
2036
+ * Original filename, or null when the attachment had none.
2037
+ */
2038
+ readonly filename: string | null;
2039
+ /**
2040
+ * MIME content type, or null when it could not be determined.
2041
+ */
2042
+ readonly content_type: string | null;
2043
+ /**
2044
+ * Attachment size in bytes.
2045
+ */
2046
+ readonly size: number;
2047
+ };
2048
+ /**
2049
+ * The original rendered body of a conversation message. Available for 30 days after the message occurred; after that the endpoint returns `410 Gone` while the message's extracted text remains readable on the message itself.
2050
+ *
2051
+ */
2052
+ type EmailThreadMessageBody = {
2053
+ /**
2054
+ * The HTML body of the message, or null when the message had no HTML part.
2055
+ */
2056
+ html: string | null;
2057
+ /**
2058
+ * The plain-text body of the message, or null when the message had no text part.
2059
+ */
2060
+ text: string | null;
2061
+ };
2062
+ type ContactId = string;
2063
+ /**
2064
+ * Label changes to apply. Labels in `add` are applied and labels in `remove` are taken off; other labels are left untouched. Adding a label that is already present, or removing one that is not, has no effect. System labels express state changes: on a conversation, adding `spam` files it as spam, adding `archive` files it away without deleting it, adding `inbox` (or removing `spam` or `archive`) returns it to the inbox, and removing `unread` marks all retained received messages as read in one call; on a message, adding or removing `unread` flips read state, and adding or removing `trash` moves it to or out of the trash. Changes that contradict this model are rejected: adding more than one placement label in one request, adding `blocked` (blocking a sender is a receive-rule decision), removing `inbox` without adding a destination, adding `trash` or `unread` to a conversation (removing `unread` is the mark-all-read shortcut; `trash` uses the DELETE verb), placement labels on a message (move its conversation instead), and `unread` on a sent message. Custom labels are 1-64 characters with no commas, control characters, or leading or trailing whitespace. System label names and a small reserved set (`all`, `archived`, `deleted`, `draft`, `drafts`, `flagged`, `important`, `junk`, `muted`, `none`, `outbox`, `pinned`, `read`, `scheduled`, `snoozed`, `starred`) cannot be used as custom labels, in any casing. A conversation or message carries at most 20 labels, system labels included.
2065
+ *
2066
+ */
2067
+ type EmailLabelsUpdate = {
2068
+ /**
2069
+ * Labels to apply.
2070
+ */
2071
+ add?: Array<string>;
2072
+ /**
2073
+ * Labels to take off.
2074
+ */
2075
+ remove?: Array<string>;
2076
+ };
2077
+ type EmailThreadMessageList = {
2078
+ data: Array<EmailThreadMessage>;
2079
+ } & ListEnvelope;
2080
+ /**
2081
+ * Link to the message's entry in the received-message or sent-message log, which carries delivery analytics such as per-recipient events. Log entries expire 30 days after the message occurred.
2082
+ *
2083
+ */
2084
+ type EmailThreadMessageSource = {
2085
+ /**
2086
+ * API path of the log entry for this message.
2087
+ */
2088
+ readonly resource: string;
2089
+ /**
2090
+ * When the log entry (and the message's original rendered source) expires.
2091
+ */
2092
+ readonly available_until: string;
2093
+ };
2094
+ /**
2095
+ * One recipient's terminal delivery outcome on a sent conversation message, folded into the message's durable memory when the outcome becomes known.
2096
+ *
2097
+ */
2098
+ type EmailThreadMessageRecipient = {
2099
+ /**
2100
+ * Recipient address.
2101
+ */
2102
+ readonly address: string;
2103
+ /**
2104
+ * Terminal outcome: `delivered`, or `failed` (bounce or provider rejection).
2105
+ */
2106
+ readonly status: "delivered" | "failed";
2107
+ };
2108
+ /**
2109
+ * A message in a mailbox conversation, either direction. Message metadata and extracted text remain readable for the mailbox's retention period; the original rendered source (HTML body, raw MIME, attachment bytes) is available through the body, raw, and attachment endpoints for 30 days after the message occurred.
2110
+ *
2111
+ */
2112
+ type EmailThreadMessage = {
2113
+ /**
2114
+ * Message ID. Received messages carry a `rem_` ID, sent messages an `em_` ID — the same IDs used by the received-message and sent-message logs.
2115
+ *
2116
+ */
2117
+ readonly id: string;
2118
+ /**
2119
+ * Direction of the message — `inbound` for a received message, `outbound` for a sent one.
2120
+ */
2121
+ readonly direction: "inbound" | "outbound";
2122
+ /**
2123
+ * Channel this message was carried on. Always `email`.
2124
+ */
2125
+ readonly channel: string;
2126
+ /**
2127
+ * Conversation this message belongs to.
2128
+ */
2129
+ readonly thread_id: ThreadId;
2130
+ /**
2131
+ * Sender address.
2132
+ */
2133
+ readonly from: string;
2134
+ /**
2135
+ * Recipient addresses on the To line.
2136
+ */
2137
+ readonly to: Array<string>;
2138
+ /**
2139
+ * Recipient addresses on the Cc line. Empty when the message had none.
2140
+ */
2141
+ readonly cc: Array<string>;
2142
+ /**
2143
+ * Address the message was actually delivered to, when it differs from the mailbox address (for example mail routed in from another address). Null for sent messages and for mail addressed directly to the mailbox.
2144
+ *
2145
+ */
2146
+ readonly delivered_to: string | null;
2147
+ /**
2148
+ * Message subject. Null when the message had no subject.
2149
+ */
2150
+ readonly subject: string | null;
2151
+ /**
2152
+ * Short plain-text preview of the message body.
2153
+ */
2154
+ readonly preview: string | null;
2155
+ /**
2156
+ * Plain-text content of the message with quoted history stripped — readable for the mailbox's full retention period, both directions. Always present when fetching a single message; on list endpoints it is included only when the request sets `include=extracted_text`. Null when no text could be extracted.
2157
+ *
2158
+ */
2159
+ readonly extracted_text?: string | null;
2160
+ /**
2161
+ * Labels on this message. System labels carry its state: a received message holds exactly one placement label — `inbox` for accepted mail, `archive` when its conversation was filed away, `spam` (failed sender authentication), or `blocked` (rejected by the mailbox's receive policy or rules) — plus `unread` until it is read. `trash` marks a message in the trash, either direction. Custom labels share the same list; a message carries at most 20.
2162
+ *
2163
+ */
2164
+ labels: Array<string>;
2165
+ /**
2166
+ * Folded delivery status of a sent message: `accepted`, `sent` (provider handoff), `delivered` (all attempted recipients delivered), or `failed` (terminal failure). Null for received messages.
2167
+ *
2168
+ */
2169
+ readonly status: string | null;
2170
+ /**
2171
+ * Terminal per-recipient delivery outcomes of a sent message, folded in as they become known — part of the message's durable memory. Null for received messages and before any recipient reaches a terminal state. Per-recipient event detail lives on the sent-message log (`source`) for 30 days.
2172
+ *
2173
+ */
2174
+ readonly recipients: Array<EmailThreadMessageRecipient> | null;
2175
+ /**
2176
+ * Whether the sender of a received message was authenticated. `pass` means the sender's identity was verified; `fail` means it was checked and did not verify; `unknown` means no verdict could be determined and the sender should not be treated as verified. Null for sent messages. Part of the message's durable memory — readable for the mailbox's full retention period, so the verdict survives after the 30-day inbound log has expired.
2177
+ *
2178
+ */
2179
+ readonly authentication: "pass" | "fail" | "unknown" | null;
2180
+ /**
2181
+ * Whether SPF passed for the sender of a received message. Null for sent messages and when no verdict is available. Durable for the mailbox's retention period.
2182
+ *
2183
+ */
2184
+ readonly spf_pass: boolean | null;
2185
+ /**
2186
+ * Whether DKIM passed for the sender of a received message. Null for sent messages and when no verdict is available. Durable for the mailbox's retention period.
2187
+ *
2188
+ */
2189
+ readonly dkim_pass: boolean | null;
2190
+ /**
2191
+ * Whether DMARC passed for the sender of a received message. Null for sent messages and when no verdict is available. Durable for the mailbox's retention period.
2192
+ *
2193
+ */
2194
+ readonly dmarc_pass: boolean | null;
2195
+ /**
2196
+ * When the message will be permanently deleted: the end of the mailbox's retention period, pulled nearer (at most 30 days out) while the message is in the trash. Restore a trashed message before then with `PATCH {"labels": {"remove": ["trash"]}}`.
2197
+ *
2198
+ */
2199
+ readonly purge_at: string;
2200
+ /**
2201
+ * Number of attachments on the message.
2202
+ */
2203
+ readonly attachment_count: number;
2204
+ /**
2205
+ * Attachment metadata (filename, content type, size). Remains readable for the mailbox's retention period even after the attachment bytes themselves have expired.
2206
+ *
2207
+ */
2208
+ readonly attachment_manifest: Array<EmailThreadMessageAttachment>;
2209
+ /**
2210
+ * RFC 5322 References header entries used to thread the conversation.
2211
+ */
2212
+ readonly reference_ids: Array<string>;
2213
+ /**
2214
+ * Contact linked to this message, or null when none is linked.
2215
+ */
2216
+ contact_id: ContactId | null;
2217
+ readonly source: EmailThreadMessageSource;
2218
+ /**
2219
+ * When the message was received or accepted for sending.
2220
+ */
2221
+ readonly occurred_at: string;
2222
+ };
2223
+ /**
2224
+ * Changes to apply to a thread. Omitted fields are left unchanged.
2225
+ */
2226
+ type EmailThreadUpdateRequest = {
2227
+ labels?: EmailLabelsUpdate;
2228
+ /**
2229
+ * Contact to link this conversation to, or null to unlink the current contact.
2230
+ */
2231
+ contact_id?: ContactId | null;
2232
+ };
2233
+ type EmailThreadList = {
2234
+ data: Array<EmailThread>;
2235
+ } & ListEnvelope;
2236
+ /**
2237
+ * Matched search fragments for a thread, one array per field the query matched, with the matched terms wrapped in `**`. A field is present only when the query matched it, so the keys that are present tell you which fields produced the hit. Returned only on thread search results.
2238
+ *
2239
+ */
2240
+ type EmailThreadHighlights = {
2241
+ /**
2242
+ * Matched fragments from the conversation's subject.
2243
+ */
2244
+ subject?: Array<string>;
2245
+ /**
2246
+ * Matched fragments from a message's body text.
2247
+ */
2248
+ text?: Array<string>;
2249
+ };
2250
+ /**
2251
+ * A conversation in a mailbox. Threads group related messages both directions — mail the mailbox received and replies it sent — and carry the conversation-level read state, labels, and participant list. Message counts reflect the messages currently retained under the mailbox's retention period.
2252
+ *
2253
+ */
2254
+ type EmailThread = {
2255
+ /**
2256
+ * Thread ID.
2257
+ */
2258
+ readonly id: ThreadId;
2259
+ /**
2260
+ * Mailbox this conversation belongs to.
2261
+ */
2262
+ readonly mailbox_id: MailboxId;
2263
+ /**
2264
+ * Channel this conversation lives on. Always `email`.
2265
+ */
2266
+ readonly channel: string;
2267
+ /**
2268
+ * Contact linked to this conversation, or null when none is linked.
2269
+ */
2270
+ contact_id: ContactId | null;
2271
+ /**
2272
+ * Subject of the conversation, taken from its first message. Null when that message had no subject.
2273
+ */
2274
+ readonly subject: string | null;
2275
+ /**
2276
+ * Addresses that appear on the retained messages in this conversation, including the mailbox's own address.
2277
+ */
2278
+ readonly participants: Array<string>;
2279
+ /**
2280
+ * Number of retained messages in this conversation, both directions.
2281
+ */
2282
+ readonly message_count: number;
2283
+ /**
2284
+ * Number of retained received messages that are still unread. Spam and blocked mail is not counted.
2285
+ */
2286
+ readonly unread_count: number;
2287
+ /**
2288
+ * When the most recent retained message in this conversation was received or sent.
2289
+ */
2290
+ readonly last_message_at: string;
2291
+ /**
2292
+ * Direction of the most recent message — `inbound` for a received message, `outbound` for a sent one.
2293
+ */
2294
+ readonly last_direction: "inbound" | "outbound";
2295
+ /**
2296
+ * Labels on this conversation. Exactly one system placement label is always present — `inbox`, `archive` (filed away, done for now), `spam` (the opening message failed sender authentication), or `blocked` (rejected by the mailbox's receive policy or rules) — set by the message that started the conversation. Move a conversation by updating its labels: add `spam` to file it as spam, add `archive` to clean it out of the inbox, and add `inbox` — or remove `spam`, `blocked`, or `archive` — to bring it back. An archived conversation returns to the inbox by itself when a new message arrives. Custom labels share the same list; a conversation carries at most 20.
2297
+ *
2298
+ */
2299
+ labels: Array<string>;
2300
+ /**
2301
+ * When the thread was created.
2302
+ */
2303
+ readonly created_at: string;
2304
+ /**
2305
+ * When the thread last changed.
2306
+ */
2307
+ readonly updated_at: string;
2308
+ /**
2309
+ * Matched search fragments, keyed by the field that matched. Returned only by thread search; omitted when listing threads.
2310
+ *
2311
+ */
2312
+ readonly highlights?: EmailThreadHighlights;
2313
+ };
2314
+ /**
2315
+ * Parameters for adding a receive rule to a mailbox.
2316
+ */
2317
+ type ReceiveRuleCreate = {
2318
+ /**
2319
+ * What the rule does when it matches. Block rules always win. To flip an entry's action, delete the existing rule and re-create it.
2320
+ */
2321
+ action: "allow" | "block";
2322
+ /**
2323
+ * The sender address (`alice@example.com`) or domain (`example.com`) to match. Domains also match their subdomains. Stored lowercase.
2324
+ */
2325
+ entry: string;
2326
+ /**
2327
+ * Your own note about why the rule exists.
2328
+ */
2329
+ note?: string;
2330
+ };
2331
+ type ReceiveRuleList = {
2332
+ data: Array<ReceiveRule>;
2333
+ } & ListEnvelope;
2334
+ type ReceiveRuleId = string;
2335
+ /**
2336
+ * An allow or block entry on a mailbox, evaluated when inbound mail arrives. Matching is against the message's envelope sender; domain entries also match subdomains. A given entry can be allow or block, never both.
2337
+ *
2338
+ */
2339
+ type ReceiveRule = {
2340
+ /**
2341
+ * Receive rule ID.
2342
+ */
2343
+ readonly id: ReceiveRuleId;
2344
+ /**
2345
+ * The mailbox the rule applies to.
2346
+ */
2347
+ readonly mailbox_id: MailboxId;
2348
+ /**
2349
+ * What the rule does when it matches. Block rules always win — over allow rules and over the reply admission on allowlist mailboxes.
2350
+ */
2351
+ readonly action: "allow" | "block";
2352
+ /**
2353
+ * The sender address or domain the rule matches. Domains also match their subdomains.
2354
+ */
2355
+ readonly entry: string;
2356
+ /**
2357
+ * Whether the entry is a full address or a domain.
2358
+ */
2359
+ readonly entry_type: "address" | "domain";
2360
+ /**
2361
+ * Your own note about why the rule exists. Null when unset.
2362
+ */
2363
+ readonly note: string | null;
2364
+ /**
2365
+ * When the rule was created.
2366
+ */
2367
+ readonly created_at: string;
2368
+ };
2369
+ /**
2370
+ * A mailbox's sent and received email statistics: a period-wide summary plus a bucketed time series. `period` echoes the range and grain the server computed against; `data` is one row per bucket in chronological order.
2371
+ *
2372
+ */
2373
+ type MailboxStatsResponse = {
2374
+ period: EmailStatsSeriesPeriod;
2375
+ summary: MailboxStatsSummary;
2376
+ /**
2377
+ * One row per bucket in the period, in chronological order. Buckets with no activity are included with zero counts.
2378
+ */
2379
+ readonly data: Array<MailboxStatsPoint>;
2380
+ };
2381
+ /**
2382
+ * Per-mailbox email activity for one time bucket, bucketed by event time. Sent-mail metrics carry the same delivery, engagement, and latency breakdowns as the email stats endpoints; `received` counts mail that arrived at the mailbox. Buckets with no activity are included with zero counts and null latency percentiles.
2383
+ *
2384
+ */
2385
+ type MailboxStatsPoint = {
2386
+ /**
2387
+ * The day (YYYY-MM-DD) or instant (RFC 3339, on the bucket boundary) this point covers, matching the period's grain.
2388
+ */
2389
+ readonly bucket: string;
2390
+ /**
2391
+ * Distinct email messages the mailbox sent that were accepted in this bucket, counted at the message level (one per accepted send regardless of how many recipients it addresses). Every other sent-mail metric in `delivery` and `engagement` is recipient-level or event-level.
2392
+ *
2393
+ */
2394
+ readonly sends_accepted: number;
2395
+ readonly delivery: EmailDeliveryStats;
2396
+ readonly engagement: EmailEngagementStats;
2397
+ readonly latency: EmailLatencyStats;
2398
+ /**
2399
+ * Distinct emails the mailbox received in this bucket.
2400
+ */
2401
+ readonly received: number;
2402
+ };
2403
+ /**
2404
+ * p50, p95, and p99 latency percentiles in milliseconds for one latency family over the bucket. Percentiles are approximate (computed from a high-volume aggregation pipeline). All three are null together when no qualifying event contributed a latency measurement in the bucket.
2405
+ *
2406
+ */
2407
+ type EmailLatencyQuantiles = {
2408
+ /**
2409
+ * Median (50th percentile) latency in milliseconds. Null when no qualifying event contributed a measurement.
2410
+ */
2411
+ readonly p50_ms: number | null;
2412
+ /**
2413
+ * 95th percentile latency in milliseconds. Null when no qualifying event contributed a measurement.
2414
+ */
2415
+ readonly p95_ms: number | null;
2416
+ /**
2417
+ * 99th percentile latency in milliseconds. Null when no qualifying event contributed a measurement.
2418
+ */
2419
+ readonly p99_ms: number | null;
2420
+ };
2421
+ /**
2422
+ * Latency percentiles (p50, p95, p99) in milliseconds for the bucket. On the summary endpoint these are computed across the whole period rather than per bucket. Three families are reported:
2423
+ *
2424
+ * - `processing`: time from accepting the send to handing the message off for delivery, covering internal queue depth and handoff. Measured per processed recipient; null when no recipient in the bucket has reached the processed stage.
2425
+ * - `delivery`: time from handoff to the receiving mail server accepting the message, dominated by recipient-side delivery behaviour. Measured per delivered recipient; null when no deliveries occurred in the bucket.
2426
+ * - `total`: end-to-end time from accepting the send to delivery, the most useful tile for a customer SLO. Measured per delivered recipient; null when no deliveries occurred in the bucket.
2427
+ *
2428
+ * Each family is reported independently and is omitted entirely when no qualifying event contributed a latency measurement in the bucket (including when latency for that stage has not yet been recorded for the workspace), so `processing` can be present while `delivery` and `total` are absent. A client must handle a missing family, and a null p50/p95/p99 within a present family, by rendering a placeholder rather than assuming a number.
2429
+ *
2430
+ */
2431
+ type EmailLatencyStats = {
2432
+ processing?: EmailLatencyQuantiles;
2433
+ delivery?: EmailLatencyQuantiles;
2434
+ total?: EmailLatencyQuantiles;
2435
+ };
2436
+ /**
2437
+ * Engagement counts and rates for the scope of the containing row (a time bucket, a breakdown dimension, or the whole period). `opens`, `opens_non_prefetched` and `clicks` count distinct engagement events (deduplicated occurrences); the `unique_*` fields count distinct recipients; `unsubscribes` counts distinct unsubscribe events. Counts are attributed by event time (not send time), so an open recorded today for a message sent earlier counts in today's row. Counts are deduplicated with a scalable approximate counting method, so very large counts are close estimates rather than exact tallies. Each rate divides the counts in this scope and is null when its denominator is zero.
2438
+ *
2439
+ */
2440
+ type EmailEngagementStats = {
2441
+ /**
2442
+ * Distinct open events, counting repeat opens from the same recipient and opens auto-fetched by inbox privacy features (such as Apple Mail Privacy Protection and the Gmail image proxy).
2443
+ *
2444
+ */
2445
+ readonly opens: number;
2446
+ /**
2447
+ * Distinct open events excluding those auto-fetched by inbox privacy features. Same event-counting semantics as `opens` (repeat opens from the same recipient count separately), with prefetched opens removed.
2448
+ *
2449
+ */
2450
+ readonly opens_non_prefetched: number;
2451
+ /**
2452
+ * Distinct recipients who opened at least once, including opens auto-fetched by inbox privacy features.
2453
+ */
2454
+ readonly unique_opens: number;
2455
+ /**
2456
+ * Distinct recipients who opened at least once, excluding opens auto-fetched by inbox privacy features. This is the numerator used for open rate, so iOS-heavy audiences (Apple Mail Privacy Protection and similar) do not inflate it.
2457
+ *
2458
+ */
2459
+ readonly unique_opens_non_prefetched: number;
2460
+ /**
2461
+ * Distinct click events, counting repeat clicks from the same recipient.
2462
+ */
2463
+ readonly clicks: number;
2464
+ /**
2465
+ * Distinct recipients who clicked at least once.
2466
+ */
2467
+ readonly unique_clicks: number;
2468
+ /**
2469
+ * Distinct unsubscribe events, recorded via the list-unsubscribe header or the footer link.
2470
+ */
2471
+ readonly unsubscribes: number;
2472
+ /**
2473
+ * Distinct non-prefetched openers relative to effectively delivered recipients in the same scope, computed as `unique_opens_non_prefetched / delivery.effective_delivered`; on rows without an `effective_delivered` field (the mailbox-provider breakdowns) the denominator equals `delivery.delivered`. The numerator excludes opens auto-fetched by inbox privacy features. Opens are attributed by event time, so engagement earned by earlier deliveries can push the rate above 1. Null when the denominator is zero.
2474
+ *
2475
+ */
2476
+ readonly open_rate: number | null;
2477
+ /**
2478
+ * Distinct clickers relative to effectively delivered recipients in the same scope, computed as `unique_clicks / delivery.effective_delivered` (`delivery.delivered` on rows without an `effective_delivered` field). Clicks are attributed by event time, so engagement earned by earlier deliveries can push the rate above 1. Null when the denominator is zero.
2479
+ *
2480
+ */
2481
+ readonly click_rate: number | null;
2482
+ /**
2483
+ * Unsubscribe events relative to effectively delivered recipients in the same scope, computed as `unsubscribes / delivery.effective_delivered` (`delivery.delivered` on rows without an `effective_delivered` field). Unsubscribes are attributed by event time, so the rate can exceed 1. Null when the denominator is zero.
2484
+ *
2485
+ */
2486
+ readonly unsubscribe_rate: number | null;
2487
+ };
2488
+ /**
2489
+ * Breakdown of `bounced` by failure type, with each rate as a fraction of `bounced`. Counts are distinct bounced recipients of that type; the five types approximately partition `bounced`, so the five rates sum to roughly 1.0 when `bounced` is non-zero.
2490
+ *
2491
+ */
2492
+ type EmailBounceStatsWithRates = {
2493
+ /**
2494
+ * Distinct recipients with a permanent delivery failure (invalid address or non-existent domain).
2495
+ */
2496
+ readonly hard: number;
2497
+ /**
2498
+ * Distinct recipients with a transient delivery failure (mailbox full or server temporarily unavailable).
2499
+ */
2500
+ readonly soft: number;
2501
+ /**
2502
+ * Distinct recipients bounced by an upstream policy block (relaying denied, blocklisted domain).
2503
+ */
2504
+ readonly admin: number;
2505
+ /**
2506
+ * Distinct recipients bounced because the receiving mail server blocked the sending IP for reputation reasons.
2507
+ */
2508
+ readonly block: number;
2509
+ /**
2510
+ * Distinct recipients bounced where the receiving server's response did not allow precise classification.
2511
+ */
2512
+ readonly undetermined: number;
2513
+ /**
2514
+ * Fraction of bounced recipients that hard bounced, computed as `hard / bounced`. Null when `bounced` is zero.
2515
+ *
2516
+ */
2517
+ readonly hard_rate: number | null;
2518
+ /**
2519
+ * Fraction of bounced recipients that soft bounced, computed as `soft / bounced`. Null when `bounced` is zero.
2520
+ *
2521
+ */
2522
+ readonly soft_rate: number | null;
2523
+ /**
2524
+ * Fraction of bounced recipients that admin bounced, computed as `admin / bounced`. Null when `bounced` is zero.
2525
+ *
2526
+ */
2527
+ readonly admin_rate: number | null;
2528
+ /**
2529
+ * Fraction of bounced recipients that block bounced, computed as `block / bounced`. Null when `bounced` is zero.
2530
+ *
2531
+ */
2532
+ readonly block_rate: number | null;
2533
+ /**
2534
+ * Fraction of bounced recipients with undetermined classification, computed as `undetermined / bounced`. Null when `bounced` is zero.
2535
+ *
2536
+ */
2537
+ readonly undetermined_rate: number | null;
2538
+ };
2539
+ /**
2540
+ * Delivery pipeline counts and rates for the scope of the containing row (a time bucket, a breakdown dimension, or the whole period). Every count is the number of distinct recipients that reached the named lifecycle stage in scope (on the period summary, the sum of the per-bucket distinct counts), attributed by event time (not send time): a recipient delivered on Monday counts in Monday's row, and a recipient who bounced then succeeded on a retry can appear in both `bounced` and `delivered`. Counts are deduplicated with a scalable approximate counting method, so very large counts are close estimates rather than exact tallies. These counts are successive lifecycle stages, not interchangeable categories: `rejected` happens before any send attempt (suppression, policy, generation failure); `deferred` is a temporary in-flight delay still being retried; `bounced` (with its hard/soft/admin/block/undetermined sub-types) is a delivery failure; and `complained` is post-delivery spam feedback. Each rate is a fraction in the range 0 to 1 and is null when its denominator is zero. `accepted` is reported only where it can be attributed (time buckets and the period summary); breakdown rows omit it.
2541
+ *
2542
+ */
2543
+ type EmailDeliveryStats = {
2544
+ /**
2545
+ * Distinct recipients accepted for delivery after suppression filtering. Reported on time buckets and the period summary; omitted on breakdown rows, whose rollups do not carry it.
2546
+ */
2547
+ readonly accepted?: number;
2548
+ /**
2549
+ * Distinct recipients whose message was processed and handed off for delivery.
2550
+ */
2551
+ readonly processed: number;
2552
+ /**
2553
+ * Distinct recipients whose message the receiving mail server accepted.
2554
+ */
2555
+ readonly delivered: number;
2556
+ /**
2557
+ * Distinct recipients whose delivery failed. Approximately the sum of the five `bounces.*` sub-counts (hard, soft, admin, block, undetermined); the totals are computed independently so they may differ slightly at the approximation error.
2558
+ *
2559
+ */
2560
+ readonly bounced: number;
2561
+ readonly bounces: EmailBounceStatsWithRates;
2562
+ /**
2563
+ * Distinct recipients who reported the message as spam via a feedback loop.
2564
+ */
2565
+ readonly complained: number;
2566
+ /**
2567
+ * Distinct recipients whose delivery the receiving server temporarily delayed and is still being retried.
2568
+ *
2569
+ */
2570
+ readonly deferred: number;
2571
+ /**
2572
+ * Distinct recipients rejected before any delivery attempt. Includes recipients on the workspace suppression list, transmissions that could not be completed, message-generation failures, and recipients refused by sending policy. The per-recipient `rejection_reason` field on `GET /v1/email/messages/{message_id}/recipients` surfaces the specific cause.
2573
+ *
2574
+ */
2575
+ readonly rejected: number;
2576
+ /**
2577
+ * Out-of-band bounce events: distinct failure notifications received after the receiving server had initially confirmed delivery. Counted as deduplicated events, not unique recipients.
2578
+ *
2579
+ */
2580
+ readonly oob_bounces: number;
2581
+ /**
2582
+ * Recipients who remain in-inbox in this scope after all bounce signals resolve, computed as `delivered - oob_bounces`. Use this as the base for engagement-rate denominators. Clamped to 0 when `oob_bounces` exceeds `delivered`.
2583
+ */
2584
+ readonly effective_delivered: number;
2585
+ /**
2586
+ * Total recipients in this scope who did not receive the message, computed as `bounced + oob_bounces`.
2587
+ */
2588
+ readonly all_bounces: number;
2589
+ /**
2590
+ * Share of this scope's delivery attempts that resulted in an out-of-band bounce, computed as `oob_bounces / (delivered + bounced)`. Null when there were no attempts.
2591
+ */
2592
+ readonly oob_rate: number | null;
2593
+ /**
2594
+ * Share of this scope's delivery attempts that resulted in a message remaining in-inbox, computed as `effective_delivered / (delivered + bounced)`. Null when there were no attempts.
2595
+ *
2596
+ */
2597
+ readonly delivery_rate: number | null;
2598
+ /**
2599
+ * Share of this scope's delivery attempts that ultimately failed (inband or out-of-band), computed as `all_bounces / (delivered + bounced)`. Because `oob_bounces` counts events rather than recipients, `all_bounces` can exceed the attempt count; the rate is clamped to 1. Null when there were no attempts.
2600
+ *
2601
+ */
2602
+ readonly bounce_rate: number | null;
2603
+ /**
2604
+ * Spam complaints in this scope relative to effectively delivered recipients, computed as `complained / effective_delivered`. Complaints are attributed by event time, so a scope can record more of them than it effectively delivered, pushing the rate above 1. Null when `effective_delivered` is zero.
2605
+ *
2606
+ */
2607
+ readonly complaint_rate: number | null;
2608
+ };
2609
+ /**
2610
+ * Single-row aggregate of the mailbox's email activity across the full requested period. Counts are sums of per-bucket counts across the window; latency percentiles are computed across the whole period rather than summed per bucket. Rates are null when their denominator is zero.
2611
+ *
2612
+ */
2613
+ type MailboxStatsSummary = {
2614
+ /**
2615
+ * Distinct email messages the mailbox sent that were accepted, counted at the message level and summed per bucket across the period.
2616
+ */
2617
+ readonly sends_accepted: number;
2618
+ readonly delivery: EmailDeliveryStats;
2619
+ readonly engagement: EmailEngagementStats;
2620
+ readonly latency: EmailLatencyStats;
2621
+ /**
2622
+ * Distinct emails the mailbox received, summed per bucket across the period.
2623
+ */
2624
+ readonly received: number;
2625
+ };
2626
+ /**
2627
+ * The window and bucket grain the response covers, echoed from the request, plus the freshness boundary the data is current to.
2628
+ *
2629
+ */
2630
+ type EmailStatsSeriesPeriod = {
2631
+ /**
2632
+ * Inclusive start of the window. A calendar day (YYYY-MM-DD, in the requested `timezone`) on the day grain; on the hour grain, an RFC 3339 UTC instant marking the start of the first hour bucket, which falls on a local hour boundary when `timezone` is set.
2633
+ */
2634
+ readonly from: string;
2635
+ /**
2636
+ * Inclusive end of the window. A calendar day (YYYY-MM-DD, in the requested `timezone`) on the day grain; on the hour grain, an RFC 3339 UTC instant marking the start of the last hour bucket, which falls on a local hour boundary when `timezone` is set.
2637
+ */
2638
+ readonly to: string;
2639
+ /**
2640
+ * The bucket grain of the series, either `day` or `hour`.
2641
+ */
2642
+ readonly grain: string;
2643
+ /**
2644
+ * The instant the statistics in this response are current to: events recorded up to roughly this time are reflected, while more recent events may not be yet. Statistics are served from a rolling aggregation that refreshes every few seconds, so a response is near-real-time but not live; use this field to label data freshness rather than assuming the numbers are to-the-second. Null when the freshness boundary is not being reported.
2645
+ *
2646
+ */
2647
+ readonly data_as_of?: string | null;
2648
+ };
2649
+ /**
2650
+ * Fields to update on a mailbox. Omitted fields are unchanged; fields set to null are cleared. The address and domain are immutable.
2651
+ */
2652
+ type MailboxUpdate = {
2653
+ /**
2654
+ * Display name used as the sender name on mail from this mailbox. Null clears it.
2655
+ */
2656
+ display_name?: string | null;
2657
+ /**
2658
+ * Default Reply-To address stamped on mail sent from this mailbox. Null clears it.
2659
+ */
2660
+ default_reply_to?: string | null;
2661
+ /**
2662
+ * Which inbound mail the mailbox accepts.
2663
+ */
2664
+ receive_policy?: "open" | "replies_only" | "allowlist" | "drop";
2665
+ /**
2666
+ * How long the mailbox remembers message metadata and extracted text. Lowering the tier deletes memory older than the new horizon and requires `confirm=true` when messages older than the new horizon would be deleted. Only `30d` is available today; longer tiers (`90d`, `1y`, and beyond) are coming soon.
2667
+ */
2668
+ retention_tier?: "30d";
2669
+ /**
2670
+ * Replaces the mailbox's key/value data. Up to 2 KB; keys starting with `__bird` are reserved.
2671
+ */
2672
+ metadata?: {
2673
+ [key: string]: unknown;
2674
+ };
2675
+ };
2676
+ /**
2677
+ * Parameters for creating a mailbox.
2678
+ */
2679
+ type MailboxCreate = {
2680
+ /**
2681
+ * The local part of the mailbox address (the part before `@`). Letters, digits, dots, underscores, and hyphens; stored lowercase. On the shared `inbox.ai` domain, separators must sit between letters or digits (no leading, trailing, or repeated separators), reserved names such as `postmaster` or `abuse` are unavailable, and choosing your own local part uses one of your plan's custom-handle allowance slots (generated addresses are always available). Omit to have Bird generate a random local part.
2682
+ */
2683
+ local_part?: string;
2684
+ /**
2685
+ * The domain the address lives under. Defaults to `inbox.ai`, Bird's shared mailbox domain, where creating the mailbox claims the address for your organization: first come, first served, and permanently reserved to your organization even after the mailbox is deleted. May instead name one of your own domains that is enabled for receiving email.
2686
+ */
2687
+ domain?: string;
2688
+ /**
2689
+ * Display name used as the sender name on mail from this mailbox.
2690
+ */
2691
+ display_name?: string;
2692
+ /**
2693
+ * Default Reply-To address stamped on mail sent from this mailbox.
2694
+ */
2695
+ default_reply_to?: string;
2696
+ /**
2697
+ * Which inbound mail the mailbox accepts. `open` accepts everything not blocked by a rule; `replies_only` accepts only replies to messages this mailbox has sent (a reply must match a message the mailbox sent, not merely land in an existing thread); `allowlist` accepts only senders matching an allow rule; `drop` stores nothing.
2698
+ */
2699
+ receive_policy?: "open" | "replies_only" | "allowlist" | "drop";
2700
+ /**
2701
+ * How long the mailbox remembers message metadata and extracted text. Original rendered source is always available for 30 days regardless of tier. Only `30d` is available today; longer tiers (`90d`, `1y`, and beyond) are coming soon.
2702
+ */
2703
+ retention_tier?: "30d";
2704
+ /**
2705
+ * Your own key/value data to attach to the mailbox. Up to 2 KB; keys starting with `__bird` are reserved.
2706
+ */
2707
+ metadata?: {
2708
+ [key: string]: unknown;
2709
+ };
2710
+ };
2711
+ type MailboxList = {
2712
+ data: Array<Mailbox>;
2713
+ } & ListEnvelope;
2714
+ type InboundAddressId = string;
2715
+ /**
2716
+ * The principal that owns the mailbox. Always the workspace.
2717
+ */
2718
+ type MailboxOwner = {
2719
+ /**
2720
+ * Owner principal type.
2721
+ */
2722
+ readonly type: "workspace";
2723
+ /**
2724
+ * Owner principal ID.
2725
+ */
2726
+ readonly id: WorkspaceId;
2727
+ };
2728
+ /**
2729
+ * A durable mailbox identity for an agent. A mailbox owns an email address, groups mail into threads, applies receive policy, and remembers message metadata and extracted text for its retention tier. The original rendered source of each message remains available for 30 days.
2730
+ *
2731
+ */
2732
+ type Mailbox = {
2733
+ /**
2734
+ * Mailbox ID.
2735
+ */
2736
+ readonly id: MailboxId;
2737
+ /**
2738
+ * The mailbox's email address. Immutable once created.
1849
2739
  */
1850
- email: string;
2740
+ readonly address: string;
1851
2741
  /**
1852
- * Display name shown alongside the address in mail clients.
2742
+ * Display name used as the sender name on mail from this mailbox. Null when unset.
1853
2743
  */
1854
- name?: string;
2744
+ display_name: string | null;
2745
+ /**
2746
+ * Default Reply-To address stamped on mail sent from this mailbox. Null when unset.
2747
+ */
2748
+ default_reply_to: string | null;
2749
+ /**
2750
+ * Which inbound mail the mailbox accepts. `open` accepts everything not blocked by a rule; `replies_only` accepts only replies to messages this mailbox has sent (a reply must match a message the mailbox sent, not merely land in an existing thread); `allowlist` accepts only senders matching an allow rule (replies to prior outbound are always admitted unless blocked); `drop` stores nothing.
2751
+ */
2752
+ receive_policy: "open" | "replies_only" | "allowlist" | "drop";
2753
+ /**
2754
+ * Lifecycle state. Suspended mailboxes stop emitting events; inbound mail is retained as blocked.
2755
+ */
2756
+ readonly state: "active" | "suspended";
2757
+ /**
2758
+ * The channel this mailbox receives on. Always `email`.
2759
+ */
2760
+ readonly channel: "email";
2761
+ readonly owner: MailboxOwner;
2762
+ /**
2763
+ * The underlying inbound address that receives this mailbox's mail.
2764
+ */
2765
+ readonly inbound_address_id: InboundAddressId;
2766
+ /**
2767
+ * How long the mailbox remembers message metadata and extracted text. Original rendered source (HTML, raw message, attachments) is always available for 30 days regardless of tier. `3y` and `10y` are reserved future tiers.
2768
+ */
2769
+ retention_tier: "30d" | "90d" | "1y";
2770
+ /**
2771
+ * Number of retained messages across all threads.
2772
+ */
2773
+ readonly message_count: number;
2774
+ /**
2775
+ * Number of retained threads.
2776
+ */
2777
+ readonly thread_count: number;
2778
+ /**
2779
+ * Number of threads with unread messages in this mailbox, excluding trash. Null on create/update responses.
2780
+ *
2781
+ */
2782
+ readonly unread_thread_count?: number | null;
2783
+ /**
2784
+ * Your own key/value data attached to the mailbox. Up to 2 KB; keys starting with `__bird` are reserved.
2785
+ */
2786
+ metadata: {
2787
+ [key: string]: unknown;
2788
+ };
2789
+ /**
2790
+ * Whether Bird generated the local part of the address. `false` means a custom handle was chosen at creation; on the shared `inbox.ai` domain a custom handle counts against your plan's custom-handle allowance.
2791
+ */
2792
+ readonly local_part_generated?: boolean;
2793
+ /**
2794
+ * When the mailbox was created.
2795
+ */
2796
+ readonly created_at: string;
2797
+ /**
2798
+ * When the mailbox was last updated.
2799
+ */
2800
+ readonly updated_at: string;
2801
+ /**
2802
+ * When the mailbox was deleted, or null if it is active. A deleted mailbox stops receiving mail immediately but can be restored for 30 days, after which it and its remembered messages are permanently removed.
2803
+ */
2804
+ readonly deleted_at?: string | null;
1855
2805
  };
1856
2806
  /**
1857
2807
  * Partial update. `settings` changes apply immediately. Changes to `return_path`, `tracking`, or `dkim` on a verified capability are staged: the current configuration keeps serving until the new one's DNS records verify, then the change is promoted automatically and the old records are marked `deprecated`. The staged value is visible under `capabilities.*.pending` and can be replaced by submitting another change.
@@ -2138,260 +3088,54 @@ type Domain = {
2138
3088
  * Per-broadcast breakdown for the requested period, ranked by the `sort` metric (default `processed`) descending and capped at the requested `limit` (default 50, max 200).
2139
3089
  */
2140
3090
  type EmailStatsByBroadcastResponse = {
2141
- period: EmailStatsPeriod & unknown;
2142
- /**
2143
- * Broadcast breakdown rows, ranked by the `sort` metric (default `processed`) descending. Empty when no broadcast messages were active in the period.
2144
- */
2145
- readonly data: Array<EmailBroadcastStatsPoint>;
2146
- /**
2147
- * Total number of distinct broadcasts with activity in the period, regardless of `limit`. When it exceeds the number of rows returned, the ranking was capped; raise `limit` (up to 200) or narrow the window to see more.
2148
- *
2149
- */
2150
- readonly total: number;
2151
- };
2152
- /**
2153
- * One point in a breakdown row's trend series: the headline delivery and engagement rates for that row's dimension value over a single day or hour. Returned only when `include_trend=true`; the bucket grain (day or hour) follows the `trend_grain` parameter. Counts and rates are approximate at scale.
2154
- *
2155
- */
2156
- type EmailStatsSeriesPoint = {
2157
- /**
2158
- * The day (YYYY-MM-DD) or hour (ISO 8601, on the hour) this point covers, matching the requested `trend_grain`.
2159
- */
2160
- readonly bucket: string;
2161
- /**
2162
- * Delivered recipients in this bucket.
2163
- */
2164
- readonly delivered: number;
2165
- /**
2166
- * Bounced recipients in this bucket.
2167
- */
2168
- readonly bounced: number;
2169
- /**
2170
- * Delivery rate for this bucket, as a fraction. Null when nothing was delivered or bounced.
2171
- */
2172
- readonly delivery_rate: number | null;
2173
- /**
2174
- * Bounce rate for this bucket, as a fraction. Null when nothing was delivered or bounced.
2175
- */
2176
- readonly bounce_rate: number | null;
2177
- /**
2178
- * Complaint rate for this bucket, as a fraction; event-time attribution can push it above 1 when complaints outrun the bucket's deliveries. Null when nothing was delivered in the bucket. On a sending-IP row complaints are not attributed to the IP, so this reads 0 in buckets that had deliveries and null in buckets that had none.
2179
- */
2180
- readonly complaint_rate: number | null;
2181
- /**
2182
- * Open rate for this bucket, as a fraction; event-time attribution can push it above 1 when opens outrun the bucket's deliveries. Null when nothing was delivered in the bucket. On a sending-IP row engagement is not attributed to the IP, so this reads 0 in buckets that had deliveries and null in buckets that had none.
2183
- */
2184
- readonly open_rate: number | null;
2185
- /**
2186
- * Click rate for this bucket, as a fraction; event-time attribution can push it above 1 when clicks outrun the bucket's deliveries. Null when nothing was delivered in the bucket. On a sending-IP row engagement is not attributed to the IP, so this reads 0 in buckets that had deliveries and null in buckets that had none.
2187
- */
2188
- readonly click_rate: number | null;
2189
- };
2190
- /**
2191
- * p50, p95, and p99 latency percentiles in milliseconds for one latency family over the bucket. Percentiles are approximate (computed from a high-volume aggregation pipeline). All three are null together when no qualifying event contributed a latency measurement in the bucket.
2192
- *
2193
- */
2194
- type EmailLatencyQuantiles = {
2195
- /**
2196
- * Median (50th percentile) latency in milliseconds. Null when no qualifying event contributed a measurement.
2197
- */
2198
- readonly p50_ms: number | null;
2199
- /**
2200
- * 95th percentile latency in milliseconds. Null when no qualifying event contributed a measurement.
2201
- */
2202
- readonly p95_ms: number | null;
2203
- /**
2204
- * 99th percentile latency in milliseconds. Null when no qualifying event contributed a measurement.
2205
- */
2206
- readonly p99_ms: number | null;
2207
- };
2208
- /**
2209
- * Latency percentiles (p50, p95, p99) in milliseconds for the bucket. On the summary endpoint these are computed across the whole period rather than per bucket. Three families are reported:
2210
- *
2211
- * - `processing`: time from accepting the send to handing the message off for delivery, covering internal queue depth and handoff. Measured per processed recipient; null when no recipient in the bucket has reached the processed stage.
2212
- * - `delivery`: time from handoff to the receiving mail server accepting the message, dominated by recipient-side delivery behaviour. Measured per delivered recipient; null when no deliveries occurred in the bucket.
2213
- * - `total`: end-to-end time from accepting the send to delivery, the most useful tile for a customer SLO. Measured per delivered recipient; null when no deliveries occurred in the bucket.
2214
- *
2215
- * Each family is reported independently and is omitted entirely when no qualifying event contributed a latency measurement in the bucket (including when latency for that stage has not yet been recorded for the workspace), so `processing` can be present while `delivery` and `total` are absent. A client must handle a missing family, and a null p50/p95/p99 within a present family, by rendering a placeholder rather than assuming a number.
2216
- *
2217
- */
2218
- type EmailLatencyStats = {
2219
- processing?: EmailLatencyQuantiles;
2220
- delivery?: EmailLatencyQuantiles;
2221
- total?: EmailLatencyQuantiles;
2222
- };
2223
- /**
2224
- * Engagement counts and rates for the scope of the containing row (a time bucket, a breakdown dimension, or the whole period). `opens`, `opens_non_prefetched` and `clicks` count distinct engagement events (deduplicated occurrences); the `unique_*` fields count distinct recipients; `unsubscribes` counts distinct unsubscribe events. Counts are attributed by event time (not send time), so an open recorded today for a message sent earlier counts in today's row. Counts are deduplicated with a scalable approximate counting method, so very large counts are close estimates rather than exact tallies. Each rate divides the counts in this scope and is null when its denominator is zero.
2225
- *
2226
- */
2227
- type EmailEngagementStats = {
2228
- /**
2229
- * Distinct open events, counting repeat opens from the same recipient and opens auto-fetched by inbox privacy features (such as Apple Mail Privacy Protection and the Gmail image proxy).
2230
- *
2231
- */
2232
- readonly opens: number;
2233
- /**
2234
- * Distinct open events excluding those auto-fetched by inbox privacy features. Same event-counting semantics as `opens` (repeat opens from the same recipient count separately), with prefetched opens removed.
2235
- *
2236
- */
2237
- readonly opens_non_prefetched: number;
2238
- /**
2239
- * Distinct recipients who opened at least once, including opens auto-fetched by inbox privacy features.
2240
- */
2241
- readonly unique_opens: number;
2242
- /**
2243
- * Distinct recipients who opened at least once, excluding opens auto-fetched by inbox privacy features. This is the numerator used for open rate, so iOS-heavy audiences (Apple Mail Privacy Protection and similar) do not inflate it.
2244
- *
2245
- */
2246
- readonly unique_opens_non_prefetched: number;
2247
- /**
2248
- * Distinct click events, counting repeat clicks from the same recipient.
2249
- */
2250
- readonly clicks: number;
2251
- /**
2252
- * Distinct recipients who clicked at least once.
2253
- */
2254
- readonly unique_clicks: number;
2255
- /**
2256
- * Distinct unsubscribe events, recorded via the list-unsubscribe header or the footer link.
2257
- */
2258
- readonly unsubscribes: number;
2259
- /**
2260
- * Distinct non-prefetched openers relative to effectively delivered recipients in the same scope, computed as `unique_opens_non_prefetched / delivery.effective_delivered`; on rows without an `effective_delivered` field (the mailbox-provider breakdowns) the denominator equals `delivery.delivered`. The numerator excludes opens auto-fetched by inbox privacy features. Opens are attributed by event time, so engagement earned by earlier deliveries can push the rate above 1. Null when the denominator is zero.
2261
- *
2262
- */
2263
- readonly open_rate: number | null;
2264
- /**
2265
- * Distinct clickers relative to effectively delivered recipients in the same scope, computed as `unique_clicks / delivery.effective_delivered` (`delivery.delivered` on rows without an `effective_delivered` field). Clicks are attributed by event time, so engagement earned by earlier deliveries can push the rate above 1. Null when the denominator is zero.
2266
- *
2267
- */
2268
- readonly click_rate: number | null;
2269
- /**
2270
- * Unsubscribe events relative to effectively delivered recipients in the same scope, computed as `unsubscribes / delivery.effective_delivered` (`delivery.delivered` on rows without an `effective_delivered` field). Unsubscribes are attributed by event time, so the rate can exceed 1. Null when the denominator is zero.
2271
- *
2272
- */
2273
- readonly unsubscribe_rate: number | null;
2274
- };
2275
- /**
2276
- * Breakdown of `bounced` by failure type, with each rate as a fraction of `bounced`. Counts are distinct bounced recipients of that type; the five types approximately partition `bounced`, so the five rates sum to roughly 1.0 when `bounced` is non-zero.
2277
- *
2278
- */
2279
- type EmailBounceStatsWithRates = {
2280
- /**
2281
- * Distinct recipients with a permanent delivery failure (invalid address or non-existent domain).
2282
- */
2283
- readonly hard: number;
2284
- /**
2285
- * Distinct recipients with a transient delivery failure (mailbox full or server temporarily unavailable).
2286
- */
2287
- readonly soft: number;
2288
- /**
2289
- * Distinct recipients bounced by an upstream policy block (relaying denied, blocklisted domain).
2290
- */
2291
- readonly admin: number;
2292
- /**
2293
- * Distinct recipients bounced because the receiving mail server blocked the sending IP for reputation reasons.
2294
- */
2295
- readonly block: number;
2296
- /**
2297
- * Distinct recipients bounced where the receiving server's response did not allow precise classification.
2298
- */
2299
- readonly undetermined: number;
2300
- /**
2301
- * Fraction of bounced recipients that hard bounced, computed as `hard / bounced`. Null when `bounced` is zero.
2302
- *
2303
- */
2304
- readonly hard_rate: number | null;
2305
- /**
2306
- * Fraction of bounced recipients that soft bounced, computed as `soft / bounced`. Null when `bounced` is zero.
2307
- *
2308
- */
2309
- readonly soft_rate: number | null;
2310
- /**
2311
- * Fraction of bounced recipients that admin bounced, computed as `admin / bounced`. Null when `bounced` is zero.
2312
- *
2313
- */
2314
- readonly admin_rate: number | null;
2315
- /**
2316
- * Fraction of bounced recipients that block bounced, computed as `block / bounced`. Null when `bounced` is zero.
2317
- *
2318
- */
2319
- readonly block_rate: number | null;
2320
- /**
2321
- * Fraction of bounced recipients with undetermined classification, computed as `undetermined / bounced`. Null when `bounced` is zero.
2322
- *
2323
- */
2324
- readonly undetermined_rate: number | null;
2325
- };
2326
- /**
2327
- * Delivery pipeline counts and rates for the scope of the containing row (a time bucket, a breakdown dimension, or the whole period). Every count is the number of distinct recipients that reached the named lifecycle stage in scope (on the period summary, the sum of the per-bucket distinct counts), attributed by event time (not send time): a recipient delivered on Monday counts in Monday's row, and a recipient who bounced then succeeded on a retry can appear in both `bounced` and `delivered`. Counts are deduplicated with a scalable approximate counting method, so very large counts are close estimates rather than exact tallies. These counts are successive lifecycle stages, not interchangeable categories: `rejected` happens before any send attempt (suppression, policy, generation failure); `deferred` is a temporary in-flight delay still being retried; `bounced` (with its hard/soft/admin/block/undetermined sub-types) is a delivery failure; and `complained` is post-delivery spam feedback. Each rate is a fraction in the range 0 to 1 and is null when its denominator is zero. `accepted` is reported only where it can be attributed (time buckets and the period summary); breakdown rows omit it.
2328
- *
2329
- */
2330
- type EmailDeliveryStats = {
2331
- /**
2332
- * Distinct recipients accepted for delivery after suppression filtering. Reported on time buckets and the period summary; omitted on breakdown rows, whose rollups do not carry it.
2333
- */
2334
- readonly accepted?: number;
2335
- /**
2336
- * Distinct recipients whose message was processed and handed off for delivery.
2337
- */
2338
- readonly processed: number;
2339
- /**
2340
- * Distinct recipients whose message the receiving mail server accepted.
2341
- */
2342
- readonly delivered: number;
2343
- /**
2344
- * Distinct recipients whose delivery failed. Approximately the sum of the five `bounces.*` sub-counts (hard, soft, admin, block, undetermined); the totals are computed independently so they may differ slightly at the approximation error.
2345
- *
2346
- */
2347
- readonly bounced: number;
2348
- readonly bounces: EmailBounceStatsWithRates;
2349
- /**
2350
- * Distinct recipients who reported the message as spam via a feedback loop.
2351
- */
2352
- readonly complained: number;
2353
- /**
2354
- * Distinct recipients whose delivery the receiving server temporarily delayed and is still being retried.
2355
- *
2356
- */
2357
- readonly deferred: number;
3091
+ period: EmailStatsPeriod & unknown;
2358
3092
  /**
2359
- * Distinct recipients rejected before any delivery attempt. Includes recipients on the workspace suppression list, transmissions that could not be completed, message-generation failures, and recipients refused by sending policy. The per-recipient `rejection_reason` field on `GET /v1/email/messages/{message_id}/recipients` surfaces the specific cause.
2360
- *
3093
+ * Broadcast breakdown rows, ranked by the `sort` metric (default `processed`) descending. Empty when no broadcast messages were active in the period.
2361
3094
  */
2362
- readonly rejected: number;
3095
+ readonly data: Array<EmailBroadcastStatsPoint>;
2363
3096
  /**
2364
- * Out-of-band bounce events: distinct failure notifications received after the receiving server had initially confirmed delivery. Counted as deduplicated events, not unique recipients.
3097
+ * Total number of distinct broadcasts with activity in the period, regardless of `limit`. When it exceeds the number of rows returned, the ranking was capped; raise `limit` (up to 200) or narrow the window to see more.
2365
3098
  *
2366
3099
  */
2367
- readonly oob_bounces: number;
3100
+ readonly total: number;
3101
+ };
3102
+ /**
3103
+ * One point in a breakdown row's trend series: the headline delivery and engagement rates for that row's dimension value over a single day or hour. Returned only when `include_trend=true`; the bucket grain (day or hour) follows the `trend_grain` parameter. Counts and rates are approximate at scale.
3104
+ *
3105
+ */
3106
+ type EmailStatsSeriesPoint = {
2368
3107
  /**
2369
- * Recipients who remain in-inbox in this scope after all bounce signals resolve, computed as `delivered - oob_bounces`. Use this as the base for engagement-rate denominators. Clamped to 0 when `oob_bounces` exceeds `delivered`.
3108
+ * The day (YYYY-MM-DD) or hour (ISO 8601, on the hour) this point covers, matching the requested `trend_grain`.
2370
3109
  */
2371
- readonly effective_delivered: number;
3110
+ readonly bucket: string;
2372
3111
  /**
2373
- * Total recipients in this scope who did not receive the message, computed as `bounced + oob_bounces`.
3112
+ * Delivered recipients in this bucket.
2374
3113
  */
2375
- readonly all_bounces: number;
3114
+ readonly delivered: number;
2376
3115
  /**
2377
- * Share of this scope's delivery attempts that resulted in an out-of-band bounce, computed as `oob_bounces / (delivered + bounced)`. Null when there were no attempts.
3116
+ * Bounced recipients in this bucket.
2378
3117
  */
2379
- readonly oob_rate: number | null;
3118
+ readonly bounced: number;
2380
3119
  /**
2381
- * Share of this scope's delivery attempts that resulted in a message remaining in-inbox, computed as `effective_delivered / (delivered + bounced)`. Null when there were no attempts.
2382
- *
3120
+ * Delivery rate for this bucket, as a fraction. Null when nothing was delivered or bounced.
2383
3121
  */
2384
3122
  readonly delivery_rate: number | null;
2385
3123
  /**
2386
- * Share of this scope's delivery attempts that ultimately failed (inband or out-of-band), computed as `all_bounces / (delivered + bounced)`. Because `oob_bounces` counts events rather than recipients, `all_bounces` can exceed the attempt count; the rate is clamped to 1. Null when there were no attempts.
2387
- *
3124
+ * Bounce rate for this bucket, as a fraction. Null when nothing was delivered or bounced.
2388
3125
  */
2389
3126
  readonly bounce_rate: number | null;
2390
3127
  /**
2391
- * Spam complaints in this scope relative to effectively delivered recipients, computed as `complained / effective_delivered`. Complaints are attributed by event time, so a scope can record more of them than it effectively delivered, pushing the rate above 1. Null when `effective_delivered` is zero.
2392
- *
3128
+ * Complaint rate for this bucket, as a fraction; event-time attribution can push it above 1 when complaints outrun the bucket's deliveries. Null when nothing was delivered in the bucket. On a sending-IP row complaints are not attributed to the IP, so this reads 0 in buckets that had deliveries and null in buckets that had none.
2393
3129
  */
2394
3130
  readonly complaint_rate: number | null;
3131
+ /**
3132
+ * Open rate for this bucket, as a fraction; event-time attribution can push it above 1 when opens outrun the bucket's deliveries. Null when nothing was delivered in the bucket. On a sending-IP row engagement is not attributed to the IP, so this reads 0 in buckets that had deliveries and null in buckets that had none.
3133
+ */
3134
+ readonly open_rate: number | null;
3135
+ /**
3136
+ * Click rate for this bucket, as a fraction; event-time attribution can push it above 1 when clicks outrun the bucket's deliveries. Null when nothing was delivered in the bucket. On a sending-IP row engagement is not attributed to the IP, so this reads 0 in buckets that had deliveries and null in buckets that had none.
3137
+ */
3138
+ readonly click_rate: number | null;
2395
3139
  };
2396
3140
  /**
2397
3141
  * Aggregate delivery, engagement, and latency stats for the messages of a single broadcast over the requested period.
@@ -3131,29 +3875,6 @@ type EmailStatsPoint = {
3131
3875
  readonly engagement: EmailEngagementStats;
3132
3876
  readonly latency: EmailLatencyStats;
3133
3877
  };
3134
- /**
3135
- * The window and bucket grain the response covers, echoed from the request, plus the freshness boundary the data is current to.
3136
- *
3137
- */
3138
- type EmailStatsSeriesPeriod = {
3139
- /**
3140
- * Inclusive start of the window. A calendar day (YYYY-MM-DD, in the requested `timezone`) on the day grain; on the hour grain, an RFC 3339 UTC instant marking the start of the first hour bucket, which falls on a local hour boundary when `timezone` is set.
3141
- */
3142
- readonly from: string;
3143
- /**
3144
- * Inclusive end of the window. A calendar day (YYYY-MM-DD, in the requested `timezone`) on the day grain; on the hour grain, an RFC 3339 UTC instant marking the start of the last hour bucket, which falls on a local hour boundary when `timezone` is set.
3145
- */
3146
- readonly to: string;
3147
- /**
3148
- * The bucket grain of the series, either `day` or `hour`.
3149
- */
3150
- readonly grain: string;
3151
- /**
3152
- * The instant the statistics in this response are current to: events recorded up to roughly this time are reflected, while more recent events may not be yet. Statistics are served from a rolling aggregation that refreshes every few seconds, so a response is near-real-time but not live; use this field to label data freshness rather than assuming the numbers are to-the-second. Null when the freshness boundary is not being reported.
3153
- *
3154
- */
3155
- readonly data_as_of?: string | null;
3156
- };
3157
3878
  type WhatsAppTemplateList = {
3158
3879
  /**
3159
3880
  * The templates available to your workspace.
@@ -3926,7 +4647,6 @@ type AudienceContactsRemoveRequest = {
3926
4647
  */
3927
4648
  contact_ids: Array<ContactId>;
3928
4649
  };
3929
- type ContactId = string;
3930
4650
  type AudienceContactsAddRequest = {
3931
4651
  /**
3932
4652
  * Contacts to add to the audience. Adding a contact that is already a member has no effect and keeps its original join time; duplicate IDs in the list are collapsed. If any ID does not exist in the workspace, the whole request fails with a validation error and no contacts are added.
@@ -4208,40 +4928,6 @@ type EmailMessageBatchItem = {
4208
4928
  *
4209
4929
  */
4210
4930
  type EmailMessageBatchRequest = Array<EmailMessageSendRequest>;
4211
- /**
4212
- * File attached to an email send. The attachment bytes are passed as base64-encoded `content` directly in the request body (required). The `path` field (provide a URL and Bird fetches the attachment for you) is a preview feature and currently unavailable. Requests are rejected with 422 if `content` is missing — `path` alone does not satisfy the schema. When `path` becomes generally available, the schema will be relaxed so that exactly one of `content` or `path` is required.
4213
- * Inline images for `<img src="cid:..."/>` references in the HTML body use the `content_id` field together with `content`.
4214
- * Bird enforces a **20 MB estimated generated message size** cap. The estimate is the HTML and text body plus all attachments and inline images measured after base64 encoding. This is not a raw file-size cap. As a rule of thumb, keep total raw attachment content at or below **15 MB** so the generated message has enough room after encoding and MIME wrapping.
4215
- * Recipient-side delivery reality: downstream limits vary by product and tenant/server policy. Gmail personal and Outlook.com document 25 MB attachment limits. Exchange Online defaults to 35 MB send / 36 MB receive, but admins can configure limits; on-prem Exchange Server organizational defaults are 10 MB. Sends close to Bird's 20 MB generated-message cap may be accepted by Bird but bounce at the recipient's mail server.
4216
- * Batch sends can include attachments on individual message objects. Each message still has the 20 MB estimated generated-size cap, and the serialized JSON request body for the whole batch has a hard 20 MB cap. Certain executable / script content types are rejected at validation time.
4217
- *
4218
- */
4219
- type EmailAttachment = {
4220
- /**
4221
- * Filename shown to the recipient. Required.
4222
- */
4223
- filename: string;
4224
- /**
4225
- * Base64-encoded attachment bytes. Required. Counts toward the 20 MB estimated generated message-size cap after encoding and MIME wrapping.
4226
- *
4227
- */
4228
- content: string;
4229
- /**
4230
- * Preview feature — provide a URL and Bird fetches the attachment for you. Currently unavailable. Use `content` instead. The schema currently requires `content`, so a request with only `path` is rejected with 422 for missing `content`; a request supplying both `content` and `path` is rejected with 422 `UnsupportedEmailFeature` until this preview ships. When generally available: HTTPS-only, single redirect followed and re-validated, private IP ranges blocked, request timeout enforced, fetched content counts toward the 20 MB estimated generated message-size cap after encoding and MIME wrapping.
4231
- *
4232
- */
4233
- path?: string;
4234
- /**
4235
- * MIME type. Inferred from `filename` extension when omitted. Used to enforce the blocklist of disallowed executable / script types.
4236
- *
4237
- */
4238
- content_type?: string;
4239
- /**
4240
- * RFC 2392 Content-ID. When set, the attachment is rendered inline and can be referenced from the HTML body as `<img src="cid:{content_id}"/>`. When omitted, the attachment is rendered as a regular file attachment.
4241
- *
4242
- */
4243
- content_id?: string;
4244
- };
4245
4931
  type EmailTemplateSend = unknown & {
4246
4932
  /**
4247
4933
  * The template to send, by its id.
@@ -4259,11 +4945,6 @@ type EmailTemplateSend = unknown & {
4259
4945
  [key: string]: unknown;
4260
4946
  };
4261
4947
  };
4262
- /**
4263
- * A sender or recipient address. Accepts a plain email string (`jane@example.com`), an RFC 5322 mailbox string with an embedded display name (`Jane Doe <jane@example.com>`), or an object carrying the address and an optional display name. All forms can be mixed freely within one request; responses always return the object form.
4264
- *
4265
- */
4266
- type EmailAddressInput = string | EmailAddress;
4267
4948
  type EmailMessageSendRequest = {
4268
4949
  /**
4269
4950
  * Sender address, as a plain email string, an RFC 5322 mailbox string (`Jane <jane@example.com>`), or an object with an optional display name. Must be from a verified domain in this workspace.
@@ -4640,6 +5321,27 @@ type ListContactsData = {
4640
5321
  };
4641
5322
  url: "/v1/contacts";
4642
5323
  };
5324
+ type CreateContactData = {
5325
+ body: ContactCreateRequest;
5326
+ headers?: {
5327
+ /**
5328
+ * Client-supplied deduplication key. When present, the server replays the original response for any duplicate request with the same key within the idempotency TTL window (3 hours by default).
5329
+ * Two distinct 409 errors signal misuse:
5330
+ * - `request_in_progress` (E01004) — the same key is currently being
5331
+ * processed by a concurrent request. Wait briefly and retry; the lock
5332
+ * expires within 30 seconds.
5333
+ * - `idempotency_key_reuse` (E01005) — the same key has already completed
5334
+ * against a different request body or method. Generate a new key.
5335
+ *
5336
+ * Recommended key format is `<event-type>/<entity-id>` (e.g. `welcome-user/usr_abc123`).
5337
+ *
5338
+ */
5339
+ "Idempotency-Key"?: string;
5340
+ };
5341
+ path?: never;
5342
+ query?: never;
5343
+ url: "/v1/contacts";
5344
+ };
4643
5345
  type ListContactPropertiesData = {
4644
5346
  body?: never;
4645
5347
  path?: never;
@@ -5399,62 +6101,214 @@ type GetEmailStatsByClientData = {
5399
6101
  * Which reading-environment facet to group rows by. `email_client` (default) groups by mail client; `os` groups by operating system; `device_type` groups by device type. Each row populates the chosen facet and leaves the other two null.
5400
6102
  *
5401
6103
  */
5402
- group_by?: "email_client" | "os" | "device_type";
6104
+ group_by?: "email_client" | "os" | "device_type";
6105
+ /**
6106
+ * Metric to rank rows by, applied descending. Defaults to `unique_opens`. Only engagement counts are sortable; this breakdown has no rates.
6107
+ *
6108
+ */
6109
+ sort?: EmailEngagementSortMetric;
6110
+ /**
6111
+ * Maximum number of client rows to return, ranked by the `sort` field descending.
6112
+ */
6113
+ limit?: number;
6114
+ };
6115
+ url: "/v1/email/stats/clients";
6116
+ };
6117
+ type GetEmailStatsByBounceCodeData = {
6118
+ body?: never;
6119
+ path?: never;
6120
+ query?: {
6121
+ /**
6122
+ * Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
6123
+ */
6124
+ from?: string;
6125
+ /**
6126
+ * End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
6127
+ */
6128
+ to?: string;
6129
+ /**
6130
+ * IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
6131
+ *
6132
+ */
6133
+ timezone?: string;
6134
+ /**
6135
+ * Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
6136
+ */
6137
+ category?: string;
6138
+ /**
6139
+ * Metric to rank rows by, applied descending. Defaults to `bounced`. Only bounce counts are sortable; this breakdown has no rates.
6140
+ *
6141
+ */
6142
+ sort?: "bounced" | "bounces.hard" | "bounces.soft" | "bounces.admin" | "bounces.block" | "bounces.undetermined";
6143
+ /**
6144
+ * Maximum number of bounce-code rows to return, ranked by the `sort` field descending.
6145
+ */
6146
+ limit?: number;
6147
+ };
6148
+ url: "/v1/email/stats/bounce-codes";
6149
+ };
6150
+ type GetEmailStatsByComplaintTypeData = {
6151
+ body?: never;
6152
+ path?: never;
6153
+ query?: {
6154
+ /**
6155
+ * Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
6156
+ */
6157
+ from?: string;
6158
+ /**
6159
+ * End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
6160
+ */
6161
+ to?: string;
6162
+ /**
6163
+ * IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
6164
+ *
6165
+ */
6166
+ timezone?: string;
6167
+ /**
6168
+ * Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
6169
+ */
6170
+ category?: string;
6171
+ /**
6172
+ * Metric to rank rows by, applied descending. Defaults to `complained`, the only sortable metric for this breakdown.
6173
+ *
6174
+ */
6175
+ sort?: "complained";
6176
+ /**
6177
+ * Maximum number of complaint-type rows to return, ranked by `complained` descending.
6178
+ */
6179
+ limit?: number;
6180
+ };
6181
+ url: "/v1/email/stats/complaint-types";
6182
+ };
6183
+ type GetEmailStatsByBroadcastData = {
6184
+ body?: never;
6185
+ path?: never;
6186
+ query?: {
6187
+ /**
6188
+ * Start date (inclusive) in YYYY-MM-DD, UTC. Defaults to 30 days before `to` when omitted.
6189
+ */
6190
+ from?: string;
6191
+ /**
6192
+ * End date (inclusive) in YYYY-MM-DD, UTC. Defaults to today (UTC) when omitted. Window may not exceed 365 days.
6193
+ */
6194
+ to?: string;
6195
+ /**
6196
+ * Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
6197
+ */
6198
+ category?: string;
6199
+ /**
6200
+ * Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `processed`.
6201
+ *
6202
+ */
6203
+ sort?: EmailStatsSortMetric;
6204
+ /**
6205
+ * Maximum number of broadcast rows to return, ranked by the `sort` field descending.
6206
+ */
6207
+ limit?: number;
6208
+ /**
6209
+ * Requests a per-row `trend` series. Not available for the broadcast breakdown; supplying `true` returns 422.
6210
+ *
6211
+ */
6212
+ include_trend?: boolean;
6213
+ /**
6214
+ * Bucket grain for the `trend` series. Has no effect on this breakdown, where `include_trend` is not available.
6215
+ */
6216
+ trend_grain?: "daily" | "hourly";
6217
+ };
6218
+ url: "/v1/email/stats/broadcasts";
6219
+ };
6220
+ type ListDomainsData = {
6221
+ body?: never;
6222
+ path?: never;
6223
+ query?: {
6224
+ /**
6225
+ * Substring match against the domain name (case-insensitive).
6226
+ */
6227
+ name?: string;
6228
+ /**
6229
+ * Field to sort by.
6230
+ */
6231
+ sort?: "created_at" | "name";
6232
+ /**
6233
+ * Sort direction. Defaults to `desc` (newest/largest first).
6234
+ *
6235
+ */
6236
+ order?: "asc" | "desc";
6237
+ /**
6238
+ * Maximum number of items to return per page.
6239
+ */
6240
+ limit?: number;
6241
+ /**
6242
+ * Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
6243
+ */
6244
+ starting_after?: string;
5403
6245
  /**
5404
- * Metric to rank rows by, applied descending. Defaults to `unique_opens`. Only engagement counts are sortable; this breakdown has no rates.
5405
- *
6246
+ * Cursor from the `prev_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order.
5406
6247
  */
5407
- sort?: EmailEngagementSortMetric;
6248
+ ending_before?: string;
5408
6249
  /**
5409
- * Maximum number of client rows to return, ranked by the `sort` field descending.
6250
+ * When true, the response includes a `total` field with the total number of items matching the request's filters across all pages.
5410
6251
  */
5411
- limit?: number;
6252
+ include_total?: boolean;
5412
6253
  };
5413
- url: "/v1/email/stats/clients";
6254
+ url: "/v1/email/domains";
5414
6255
  };
5415
- type GetEmailStatsByBounceCodeData = {
6256
+ type ListMailboxesData = {
5416
6257
  body?: never;
5417
6258
  path?: never;
5418
6259
  query?: {
5419
6260
  /**
5420
- * Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
6261
+ * Filter to the mailbox with exactly this address.
5421
6262
  */
5422
- from?: string;
6263
+ address?: string;
5423
6264
  /**
5424
- * End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
6265
+ * Case-insensitive search matching the mailbox's address or display name (substring).
5425
6266
  */
5426
- to?: string;
6267
+ q?: string;
5427
6268
  /**
5428
- * IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
5429
- *
6269
+ * Filter by lifecycle state.
5430
6270
  */
5431
- timezone?: string;
6271
+ state?: "active" | "suspended";
5432
6272
  /**
5433
- * Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
6273
+ * Filter to mailboxes whose address is on this domain.
5434
6274
  */
5435
- category?: string;
6275
+ domain?: string;
5436
6276
  /**
5437
- * Metric to rank rows by, applied descending. Defaults to `bounced`. Only bounce counts are sortable; this breakdown has no rates.
5438
- *
6277
+ * Include mailboxes deleted within their 30-day restore window. Defaults to false, so only active and suspended mailboxes are returned. Deleted mailboxes carry a non-null `deleted_at`.
5439
6278
  */
5440
- sort?: "bounced" | "bounces.hard" | "bounces.soft" | "bounces.admin" | "bounces.block" | "bounces.undetermined";
6279
+ include_deleted?: boolean;
5441
6280
  /**
5442
- * Maximum number of bounce-code rows to return, ranked by the `sort` field descending.
6281
+ * Maximum number of items to return per page.
5443
6282
  */
5444
6283
  limit?: number;
6284
+ /**
6285
+ * Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
6286
+ */
6287
+ starting_after?: string;
6288
+ /**
6289
+ * Cursor from the `prev_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order.
6290
+ */
6291
+ ending_before?: string;
5445
6292
  };
5446
- url: "/v1/email/stats/bounce-codes";
6293
+ url: "/v1/email/mailboxes";
5447
6294
  };
5448
- type GetEmailStatsByComplaintTypeData = {
6295
+ type GetMailboxStatsData = {
5449
6296
  body?: never;
5450
- path?: never;
6297
+ path: {
6298
+ /**
6299
+ * Mailbox ID.
6300
+ */
6301
+ mailbox_id: MailboxId;
6302
+ };
5451
6303
  query?: {
5452
6304
  /**
5453
- * Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
6305
+ * Inclusive start of the window: a calendar day (YYYY-MM-DD, `day` granularity only) or an RFC 3339 instant rounded down to the hour (`hour` granularity only). Interpreted in `timezone`, or in UTC when `timezone` is omitted. A numeric UTC offset is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant. Must use the same form as `to`. Defaults to 30 days before `to` at `day` granularity and 7 days before `to` at `hour`, when omitted.
6306
+ *
5454
6307
  */
5455
6308
  from?: string;
5456
6309
  /**
5457
- * End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
6310
+ * Inclusive end of the window: a calendar day (YYYY-MM-DD, `day` granularity only) or an RFC 3339 instant rounded down to the hour (`hour` granularity only). Interpreted in `timezone`, or in UTC when `timezone` is omitted. A numeric UTC offset is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant. Must use the same form as `from`. Defaults to today (day) or the current hour (hour) in that timezone when omitted. Window may not exceed 365 days at `day` or 30 days at `hour` granularity.
6311
+ *
5458
6312
  */
5459
6313
  to?: string;
5460
6314
  /**
@@ -5463,75 +6317,114 @@ type GetEmailStatsByComplaintTypeData = {
5463
6317
  */
5464
6318
  timezone?: string;
5465
6319
  /**
5466
- * Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
6320
+ * Bucket grain of the series: `day` (default) or `hour`. Echoed back as `period.grain`.
6321
+ *
5467
6322
  */
5468
- category?: string;
6323
+ granularity?: "day" | "hour";
6324
+ };
6325
+ url: "/v1/email/mailboxes/{mailbox_id}/stats";
6326
+ };
6327
+ type ListMailboxReceiveRulesData = {
6328
+ body?: never;
6329
+ path: {
5469
6330
  /**
5470
- * Metric to rank rows by, applied descending. Defaults to `complained`, the only sortable metric for this breakdown.
5471
- *
6331
+ * Mailbox ID.
5472
6332
  */
5473
- sort?: "complained";
6333
+ mailbox_id: MailboxId;
6334
+ };
6335
+ query?: {
5474
6336
  /**
5475
- * Maximum number of complaint-type rows to return, ranked by `complained` descending.
6337
+ * Filter by rule action.
6338
+ */
6339
+ action?: "allow" | "block";
6340
+ /**
6341
+ * Maximum number of items to return per page.
5476
6342
  */
5477
6343
  limit?: number;
6344
+ /**
6345
+ * Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
6346
+ */
6347
+ starting_after?: string;
6348
+ /**
6349
+ * Cursor from the `prev_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order.
6350
+ */
6351
+ ending_before?: string;
5478
6352
  };
5479
- url: "/v1/email/stats/complaint-types";
6353
+ url: "/v1/email/mailboxes/{mailbox_id}/receive-rules";
5480
6354
  };
5481
- type GetEmailStatsByBroadcastData = {
6355
+ type ListEmailThreadsData = {
5482
6356
  body?: never;
5483
6357
  path?: never;
5484
6358
  query?: {
5485
6359
  /**
5486
- * Start date (inclusive) in YYYY-MM-DD, UTC. Defaults to 30 days before `to` when omitted.
6360
+ * Filter to conversations in a specific mailbox.
5487
6361
  */
5488
- from?: string;
6362
+ mailbox_id?: MailboxId;
5489
6363
  /**
5490
- * End date (inclusive) in YYYY-MM-DD, UTC. Defaults to today (UTC) when omitted. Window may not exceed 365 days.
6364
+ * Filter to conversations linked to a specific contact.
5491
6365
  */
5492
- to?: string;
6366
+ contact_id?: ContactId;
5493
6367
  /**
5494
- * Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
6368
+ * Filter to conversations carrying this label. Repeat the parameter to require several only conversations carrying every listed label match. A placement label selects a folder (`inbox`, `archive`, `spam`, `blocked`); a custom label matches conversations in any folder. Defaults to `inbox` when omitted.
5495
6369
  */
5496
- category?: string;
6370
+ label?: Array<string>;
5497
6371
  /**
5498
- * Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `processed`.
5499
- *
6372
+ * When `true`, only conversations with unread messages are returned. This filters on the conversation's unread state, so it combines with `label` for example, unread conversations in the archive. (The `unread` label itself lives on messages, not conversations.)
5500
6373
  */
5501
- sort?: EmailStatsSortMetric;
6374
+ has_unread?: boolean;
5502
6375
  /**
5503
- * Maximum number of broadcast rows to return, ranked by the `sort` field descending.
6376
+ * Conversations involving this address matches the sender or any recipient, as a case-insensitive contains-match, so a full address or any fragment of one works.
6377
+ */
6378
+ participant?: string;
6379
+ /**
6380
+ * Conversations whose subject contains this text (case-insensitive).
6381
+ */
6382
+ subject?: string;
6383
+ /**
6384
+ * Filter to conversations whose most recent message is at or after this time. This is a time filter, not a cursor.
6385
+ */
6386
+ after?: string;
6387
+ /**
6388
+ * Filter to conversations whose most recent message is at or before this time. This is a time filter, not a cursor.
6389
+ */
6390
+ before?: string;
6391
+ /**
6392
+ * Maximum number of items to return per page.
5504
6393
  */
5505
6394
  limit?: number;
5506
6395
  /**
5507
- * Requests a per-row `trend` series. Not available for the broadcast breakdown; supplying `true` returns 422.
5508
- *
6396
+ * Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
5509
6397
  */
5510
- include_trend?: boolean;
6398
+ starting_after?: string;
5511
6399
  /**
5512
- * Bucket grain for the `trend` series. Has no effect on this breakdown, where `include_trend` is not available.
6400
+ * Cursor from the `prev_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order.
5513
6401
  */
5514
- trend_grain?: "daily" | "hourly";
6402
+ ending_before?: string;
5515
6403
  };
5516
- url: "/v1/email/stats/broadcasts";
6404
+ url: "/v1/email/threads";
5517
6405
  };
5518
- type ListDomainsData = {
6406
+ type ListEmailThreadMessagesData = {
5519
6407
  body?: never;
5520
- path?: never;
5521
- query?: {
6408
+ path: {
5522
6409
  /**
5523
- * Substring match against the domain name (case-insensitive).
6410
+ * Thread ID.
5524
6411
  */
5525
- name?: string;
6412
+ thread_id: ThreadId;
6413
+ };
6414
+ query?: {
5526
6415
  /**
5527
- * Field to sort by.
6416
+ * Filter to received (`inbound`) or sent (`outbound`) messages.
5528
6417
  */
5529
- sort?: "created_at" | "name";
6418
+ direction?: "inbound" | "outbound";
5530
6419
  /**
5531
- * Sort direction. Defaults to `desc` (newest/largest first).
6420
+ * Filter to messages carrying this label. `trash` lists trashed messages; any other label — `archive`, `spam`, `blocked`, `unread`, or a custom label — lists its non-trashed carriers. When omitted, received messages in the inbox and all sent messages are returned.
5532
6421
  *
5533
6422
  */
5534
- order?: "asc" | "desc";
6423
+ label?: string;
6424
+ /**
6425
+ * Set to `extracted_text` to inline each message's extracted plain text.
6426
+ */
6427
+ include?: "extracted_text";
5535
6428
  /**
5536
6429
  * Maximum number of items to return per page.
5537
6430
  */
@@ -5544,12 +6437,8 @@ type ListDomainsData = {
5544
6437
  * Cursor from the `prev_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order.
5545
6438
  */
5546
6439
  ending_before?: string;
5547
- /**
5548
- * When true, the response includes a `total` field with the total number of items matching the request's filters across all pages.
5549
- */
5550
- include_total?: boolean;
5551
6440
  };
5552
- url: "/v1/email/domains";
6441
+ url: "/v1/email/threads/{thread_id}/messages";
5553
6442
  };
5554
6443
  //#endregion
5555
6444
  //#region src/generated/core/auth.gen.d.ts
@@ -5884,51 +6773,26 @@ declare abstract class Resource {
5884
6773
  protected paginated<T>(method: string, options: RequestOptions | undefined, invoke: (ctx: CallContext, cursor: string | undefined) => Promise<FetchOutcome<CursorPage<T>>>): PaginatedPromise<T>;
5885
6774
  }
5886
6775
  //#endregion
5887
- //#region src/resources/emailStats.d.ts
5888
- /** Query params for `bird.email.stats.summary`. */
6776
+ //#region src/resources/emailStats.gen.d.ts
5889
6777
  type EmailStatsSummaryQuery = NonNullable<GetEmailStatsSummaryData["query"]>;
5890
- /** Query params for `bird.email.stats.daily`. */
5891
6778
  type EmailStatsDailyQuery = NonNullable<GetEmailStatsDailyData["query"]>;
5892
- /** Query params for `bird.email.stats.hourly`. */
5893
6779
  type EmailStatsHourlyQuery = NonNullable<GetEmailStatsHourlyData["query"]>;
5894
- /** Query params for `bird.email.stats.byTag`. */
5895
6780
  type EmailStatsByTagQuery = NonNullable<GetEmailStatsByTagData["query"]>;
5896
- /** Query params for `bird.email.stats.byCategory`. */
5897
6781
  type EmailStatsByCategoryQuery = NonNullable<GetEmailStatsByCategoryData["query"]>;
5898
- /** Query params for `bird.email.stats.bySendingIp`. */
5899
6782
  type EmailStatsBySendingIpQuery = NonNullable<GetEmailStatsBySendingIpData["query"]>;
5900
- /** Query params for `bird.email.stats.bySendingDomain`. */
5901
6783
  type EmailStatsBySendingDomainQuery = NonNullable<GetEmailStatsBySendingDomainData["query"]>;
5902
- /** Query params for `bird.email.stats.byRecipientDomain`. */
5903
6784
  type EmailStatsByRecipientDomainQuery = NonNullable<GetEmailStatsByRecipientDomainData["query"]>;
5904
- /** Query params for `bird.email.stats.byMailboxProvider`. */
5905
6785
  type EmailStatsByMailboxProviderQuery = NonNullable<GetEmailStatsByMailboxProviderData["query"]>;
5906
- /** Query params for `bird.email.stats.byMailboxProviderRegion`. */
5907
6786
  type EmailStatsByMailboxProviderRegionQuery = NonNullable<GetEmailStatsByMailboxProviderRegionData["query"]>;
5908
- /** Query params for `bird.email.stats.byTemplate`. */
5909
6787
  type EmailStatsByTemplateQuery = NonNullable<GetEmailStatsByTemplateData["query"]>;
5910
- /** Query params for `bird.email.stats.byLocation`. */
5911
6788
  type EmailStatsByLocationQuery = NonNullable<GetEmailStatsByLocationData["query"]>;
5912
- /** Query params for `bird.email.stats.byClient`. */
5913
6789
  type EmailStatsByClientQuery = NonNullable<GetEmailStatsByClientData["query"]>;
5914
- /** Query params for `bird.email.stats.byBounceCode`. */
5915
6790
  type EmailStatsByBounceCodeQuery = NonNullable<GetEmailStatsByBounceCodeData["query"]>;
5916
- /** Query params for `bird.email.stats.byComplaintType`. */
5917
6791
  type EmailStatsByComplaintTypeQuery = NonNullable<GetEmailStatsByComplaintTypeData["query"]>;
5918
- /** Query params for `bird.email.stats.byBroadcast`. */
5919
6792
  type EmailStatsByBroadcastQuery = NonNullable<GetEmailStatsByBroadcastData["query"]>;
5920
- /**
5921
- * `bird.email.stats` — read-only email statistics. Every method takes an
5922
- * optional query object (window, timezone, and — for breakdowns — `limit` and
5923
- * `sort`) and resolves the typed aggregate or breakdown for that window. These
5924
- * are point reads, not cursor lists, so each returns an `APIPromise`, not a
5925
- * paginated iterator. Reached as `bird.email.stats.*`.
5926
- */
5927
6793
  declare class EmailStatsResource extends Resource {
5928
6794
  /**
5929
- * Aggregate delivery, engagement, and latency for a window. Pass
5930
- * `compare: "previous_period"` to also get the preceding window and the
5931
- * change between the two.
6795
+ * Aggregate email KPIs for one period: sends, delivered, bounces, complaints, opens, clicks, their rates, and latency percentiles. `from`/`to` are both YYYY-MM-DD days or both RFC 3339 instants (hour grain); add `compare=previous_period` for deltas versus the prior window. For a per-day or per-hour series use email_stats_daily or email_stats_hourly.
5932
6796
  *
5933
6797
  * @example Summary for a month
5934
6798
  * const s = await bird.email.stats.summary({ from: "2026-05-01", to: "2026-05-31" });
@@ -5936,23 +6800,23 @@ declare class EmailStatsResource extends Resource {
5936
6800
  */
5937
6801
  summary(query?: EmailStatsSummaryQuery, options?: RequestOptions): APIPromise<EmailStatsSummary>;
5938
6802
  /**
5939
- * Daily time series one row per calendar day in the window.
6803
+ * Per-day email stats series (counts, rates, latency percentiles), gap-filled with zero rows, max 365 days. At most one filter of `category`, `sending_domain`, `tag`, `sending_ip`, `recipient_domain`, `template`. For hour resolution use email_stats_hourly; for one aggregate row use email_stats_summary.
5940
6804
  *
5941
- * @example Per-day series for a month
6805
+ * @example
5942
6806
  * const series = await bird.email.stats.daily({ from: "2026-05-01", to: "2026-05-31" });
5943
6807
  * for (const row of series.data) console.log(row.bucket, row.delivery.delivered);
5944
6808
  */
5945
6809
  daily(query?: EmailStatsDailyQuery, options?: RequestOptions): APIPromise<EmailStatsResponse>;
5946
6810
  /**
5947
- * Hourly time series one row per hour in the window (max 720 hours).
6811
+ * Per-hour email stats series, gap-filled with zero rows, max 720 hours (30 days). Takes the same single-dimension filters as email_stats_daily; for longer ranges use email_stats_daily, for one aggregate row use email_stats_summary.
5948
6812
  *
5949
- * @example Per-hour series for a day
6813
+ * @example
5950
6814
  * const series = await bird.email.stats.hourly({ from: "2026-05-01", to: "2026-05-02" });
5951
6815
  * for (const row of series.data) console.log(row.bucket, row.delivery.delivered);
5952
6816
  */
5953
6817
  hourly(query?: EmailStatsHourlyQuery, options?: RequestOptions): APIPromise<EmailStatsResponse>;
5954
6818
  /**
5955
- * Breakdown by tag, ranked by `sort` (default `processed`) descending.
6819
+ * Email delivery and engagement stats grouped by tag, one row per `name:value` pair set at send time; ranked by `sort` (default `processed`). `include_trend=true` adds a per-bucket rate series to each row.
5956
6820
  *
5957
6821
  * @example Top 10 tags by delivered
5958
6822
  * const { data } = await bird.email.stats.byTag({
@@ -5965,17 +6829,17 @@ declare class EmailStatsResource extends Resource {
5965
6829
  */
5966
6830
  byTag(query?: EmailStatsByTagQuery, options?: RequestOptions): APIPromise<EmailStatsTagsResponse>;
5967
6831
  /**
5968
- * Breakdown by category (`transactional` / `marketing`).
6832
+ * Email delivery and engagement stats grouped by category (`transactional` versus `marketing`), ranked by `sort` (default `processed`). `include_trend=true` adds a per-bucket rate series to each row.
5969
6833
  *
5970
- * @example By category for a month
6834
+ * @example
5971
6835
  * const { data } = await bird.email.stats.byCategory({ from: "2026-05-01", to: "2026-05-31" });
5972
6836
  * for (const row of data) console.log(row.category, row.delivery.delivered);
5973
6837
  */
5974
6838
  byCategory(query?: EmailStatsByCategoryQuery, options?: RequestOptions): APIPromise<EmailStatsByCategoryResponse>;
5975
6839
  /**
5976
- * Breakdown by sending IP, ranked by `sort` (default `delivered`) descending.
6840
+ * Delivery and bounce stats grouped by sending IP; `sort=bounces.block` surfaces reputation-damaged IPs first. No engagement, complaint, or accepted/processed counts per IP; use email_stats_daily for workspace-wide figures.
5977
6841
  *
5978
- * @example IPs with the most block bounces
6842
+ * @example
5979
6843
  * const { data } = await bird.email.stats.bySendingIp({
5980
6844
  * from: "2026-05-01",
5981
6845
  * to: "2026-05-31",
@@ -5986,9 +6850,9 @@ declare class EmailStatsResource extends Resource {
5986
6850
  */
5987
6851
  bySendingIp(query?: EmailStatsBySendingIpQuery, options?: RequestOptions): APIPromise<EmailStatsBySendingIpResponse>;
5988
6852
  /**
5989
- * Breakdown by sending domain.
6853
+ * Email delivery and engagement stats grouped by sending (`From`) domain; compare deliverability across the workspace's verified domains. For per-IP reputation use email_stats_by_sending_ip.
5990
6854
  *
5991
- * @example By sending domain
6855
+ * @example
5992
6856
  * const { data } = await bird.email.stats.bySendingDomain({
5993
6857
  * from: "2026-05-01",
5994
6858
  * to: "2026-05-31",
@@ -5999,9 +6863,9 @@ declare class EmailStatsResource extends Resource {
5999
6863
  */
6000
6864
  bySendingDomain(query?: EmailStatsBySendingDomainQuery, options?: RequestOptions): APIPromise<EmailStatsBySendingDomainResponse>;
6001
6865
  /**
6002
- * Breakdown by recipient mailbox domain (e.g. `gmail.com`).
6866
+ * Email delivery and engagement stats grouped by exact recipient mailbox domain (for example `gmail.com`). Finer-grained than email_stats_by_mailbox_provider, which buckets domains into providers.
6003
6867
  *
6004
- * @example Recipient domains with the highest bounce rate
6868
+ * @example
6005
6869
  * const { data } = await bird.email.stats.byRecipientDomain({
6006
6870
  * from: "2026-05-01",
6007
6871
  * to: "2026-05-31",
@@ -6012,9 +6876,9 @@ declare class EmailStatsResource extends Resource {
6012
6876
  */
6013
6877
  byRecipientDomain(query?: EmailStatsByRecipientDomainQuery, options?: RequestOptions): APIPromise<EmailStatsByRecipientDomainResponse>;
6014
6878
  /**
6015
- * Breakdown by mailbox provider (e.g. Google, Microsoft).
6879
+ * Email delivery and engagement stats grouped by recipient mailbox provider (`gmail`, `microsoft`, `yahoo`, ...); covers the delivery stage onward, no accepted/processed counts. For a per-region split use email_stats_by_mailbox_provider_region; for exact destination domains use email_stats_by_recipient_domain.
6016
6880
  *
6017
- * @example By mailbox provider
6881
+ * @example
6018
6882
  * const { data } = await bird.email.stats.byMailboxProvider({
6019
6883
  * from: "2026-05-01",
6020
6884
  * to: "2026-05-31",
@@ -6024,9 +6888,9 @@ declare class EmailStatsResource extends Resource {
6024
6888
  */
6025
6889
  byMailboxProvider(query?: EmailStatsByMailboxProviderQuery, options?: RequestOptions): APIPromise<EmailStatsByMailboxProviderResponse>;
6026
6890
  /**
6027
- * Breakdown by mailbox provider and region.
6891
+ * Email delivery and engagement stats grouped by mailbox provider and provider region pair (for example `gmail` in `NA`); covers the delivery stage onward, no accepted/processed counts. For the provider-level view use email_stats_by_mailbox_provider.
6028
6892
  *
6029
- * @example By mailbox provider and region
6893
+ * @example
6030
6894
  * const { data } = await bird.email.stats.byMailboxProviderRegion({
6031
6895
  * from: "2026-05-01",
6032
6896
  * to: "2026-05-31",
@@ -6036,9 +6900,9 @@ declare class EmailStatsResource extends Resource {
6036
6900
  */
6037
6901
  byMailboxProviderRegion(query?: EmailStatsByMailboxProviderRegionQuery, options?: RequestOptions): APIPromise<EmailStatsByMailboxProviderRegionResponse>;
6038
6902
  /**
6039
- * Breakdown by template (by `emt_…` ID or name).
6903
+ * Email delivery and engagement stats grouped by the template used at send time, keyed by template id (`emt_…`); only templated sends appear. To track a single template over time, pass `template` to email_stats_daily instead.
6040
6904
  *
6041
- * @example By template
6905
+ * @example
6042
6906
  * const { data } = await bird.email.stats.byTemplate({
6043
6907
  * from: "2026-05-01",
6044
6908
  * to: "2026-05-31",
@@ -6049,9 +6913,9 @@ declare class EmailStatsResource extends Resource {
6049
6913
  */
6050
6914
  byTemplate(query?: EmailStatsByTemplateQuery, options?: RequestOptions): APIPromise<EmailStatsByTemplateResponse>;
6051
6915
  /**
6052
- * Breakdown by recipient geographic location.
6916
+ * Opens and clicks grouped by country, region, or city (`group_by`); engagement counts only, no delivery counts or rates. For engagement by mail client or device use email_stats_by_client.
6053
6917
  *
6054
- * @example By location
6918
+ * @example
6055
6919
  * const { data } = await bird.email.stats.byLocation({
6056
6920
  * from: "2026-05-01",
6057
6921
  * to: "2026-05-31",
@@ -6061,9 +6925,9 @@ declare class EmailStatsResource extends Resource {
6061
6925
  */
6062
6926
  byLocation(query?: EmailStatsByLocationQuery, options?: RequestOptions): APIPromise<EmailStatsByLocationResponse>;
6063
6927
  /**
6064
- * Breakdown by opening client (the application that opened the message).
6928
+ * Opens and clicks grouped by mail client, OS, or device type (`group_by`); engagement counts only, no delivery counts or rates. For engagement by geography use email_stats_by_location.
6065
6929
  *
6066
- * @example By client
6930
+ * @example
6067
6931
  * const { data } = await bird.email.stats.byClient({
6068
6932
  * from: "2026-05-01",
6069
6933
  * to: "2026-05-31",
@@ -6073,9 +6937,9 @@ declare class EmailStatsResource extends Resource {
6073
6937
  */
6074
6938
  byClient(query?: EmailStatsByClientQuery, options?: RequestOptions): APIPromise<EmailStatsByClientResponse>;
6075
6939
  /**
6076
- * Breakdown by bounce code which SMTP/enhanced codes drove bounces.
6940
+ * Bounce counts grouped by the SMTP error code the receiving server returned, with the hard/soft/admin/block/undetermined split; failure side only. Use it to find what is driving bounces; for bounces by destination use email_stats_by_recipient_domain or email_stats_by_mailbox_provider.
6077
6941
  *
6078
- * @example By bounce code
6942
+ * @example
6079
6943
  * const { data } = await bird.email.stats.byBounceCode({
6080
6944
  * from: "2026-05-01",
6081
6945
  * to: "2026-05-31",
@@ -6086,17 +6950,17 @@ declare class EmailStatsResource extends Resource {
6086
6950
  */
6087
6951
  byBounceCode(query?: EmailStatsByBounceCodeQuery, options?: RequestOptions): APIPromise<EmailStatsByBounceCodeResponse>;
6088
6952
  /**
6089
- * Breakdown by complaint type.
6953
+ * Spam-complaint counts grouped by the feedback-loop complaint type (for example `abuse`, `fraud`, `virus`); complaint side only. For complaints by destination use email_stats_by_mailbox_provider or email_stats_by_recipient_domain.
6090
6954
  *
6091
- * @example By complaint type
6955
+ * @example
6092
6956
  * const { data } = await bird.email.stats.byComplaintType({ from: "2026-05-01", to: "2026-05-31" });
6093
6957
  * for (const row of data) console.log(row.feedback_type, row.complained);
6094
6958
  */
6095
6959
  byComplaintType(query?: EmailStatsByComplaintTypeQuery, options?: RequestOptions): APIPromise<EmailStatsByComplaintTypeResponse>;
6096
6960
  /**
6097
- * Breakdown by broadcast.
6961
+ * Email delivery and engagement stats grouped by broadcast; only broadcast sends appear. Reflects roughly the last 30 days of activity; `include_trend` is not available here and returns 422.
6098
6962
  *
6099
- * @example By broadcast
6963
+ * @example
6100
6964
  * const { data } = await bird.email.stats.byBroadcast({
6101
6965
  * from: "2026-05-01",
6102
6966
  * to: "2026-05-31",
@@ -6470,32 +7334,12 @@ declare class ContactPropertiesResource extends Resource {
6470
7334
  unarchive(propertyId: string, options?: RequestOptions): APIPromise<ContactProperty>;
6471
7335
  }
6472
7336
  //#endregion
6473
- //#region src/resources/contacts.d.ts
6474
- /** Body for `bird.contacts.create`. */
6475
- type ContactCreateParams = ContactCreateRequest;
6476
- /** Body for `bird.contacts.update` — a partial patch. */
6477
- type ContactUpdateParams = ContactUpdateRequest;
6478
- /** Body for `bird.contacts.batch` — create-or-update many contacts in one call. */
6479
- type ContactBatchParams = ContactUpsertRequest;
6480
- /** Filters and cursor params for `bird.contacts.list`. */
7337
+ //#region src/resources/contacts.gen.d.ts
6481
7338
  type ContactListQuery = NonNullable<ListContactsData["query"]>;
6482
- declare class ContactsResource extends Resource {
7339
+ type ContactCreateParams = NonNullable<CreateContactData["body"]>;
7340
+ declare class ContactsResourceBase extends Resource {
6483
7341
  /**
6484
- * Create a contact. `email` is required and unique within the workspace; set
6485
- * custom fields via `data` (each key a property defined in contact properties).
6486
- *
6487
- * @example Create a contact
6488
- * const contact = await bird.contacts.create({
6489
- * email: "jane@acme.com",
6490
- * first_name: "Jane",
6491
- * });
6492
- * console.log(contact.id); // "con_…"
6493
- */
6494
- create(params: ContactCreateParams, options?: RequestOptions): APIPromise<Contact>;
6495
- /**
6496
- * List the workspace's contacts, newest first. `await` resolves the first page;
6497
- * `for await` walks every contact across pages. Filter by `email`,
6498
- * `external_id`, or a `q` search term.
7342
+ * List the workspace's contacts as a cursor page, newest first. Look one up by exact email or external_id, or search by email substring.
6499
7343
  *
6500
7344
  * @example Iterate every contact, or take one page
6501
7345
  * for await (const contact of bird.contacts.list({ q: "acme.com" })) {
@@ -6505,29 +7349,48 @@ declare class ContactsResource extends Resource {
6505
7349
  */
6506
7350
  list(query?: ContactListQuery, options?: RequestOptions): PaginatedPromise<Contact>;
6507
7351
  /**
6508
- * Fetch a single contact by id.
7352
+ * Get a single contact by ID (`con_`-prefixed). Look up an ID by exact email or external_id with `contacts.list`.
6509
7353
  *
6510
- * @example
7354
+ * @example Fetch a contact by id
6511
7355
  * const contact = await bird.contacts.get("con_01krdgeqcxet5s7t44vh8rt9mg");
6512
- * contact.email;
7356
+ * console.log(contact.email, contact.first_name);
6513
7357
  */
6514
7358
  get(contactId: string, options?: RequestOptions): APIPromise<Contact>;
6515
7359
  /**
6516
- * Update a contact. Only the fields you send change.
7360
+ * Create a contact by email address in the workspace. Fails with a conflict if the email or external_id is already used by another contact. For bulk import or create-or-update semantics use `contacts.batch`.
6517
7361
  *
6518
- * @example
6519
- * const contact = await bird.contacts.update("con_01krdgeqcxet5s7t44vh8rt9mg", {
7362
+ * @example Create a contact
7363
+ * const contact = await bird.contacts.create({
7364
+ * email: "jane@acme.com",
6520
7365
  * first_name: "Jane",
6521
7366
  * });
7367
+ * console.log(contact.id); // "con_…"
6522
7368
  */
6523
- update(contactId: string, params: ContactUpdateParams, options?: RequestOptions): APIPromise<Contact>;
7369
+ create(params: ContactCreateParams, options?: RequestOptions): APIPromise<Contact>;
6524
7370
  /**
6525
- * Delete a contact by id.
7371
+ * Delete a contact and remove it from every audience it belongs to. Suppression records for the address are unaffected.
6526
7372
  *
6527
- * @example
7373
+ * @example Delete a contact by id
6528
7374
  * await bird.contacts.delete("con_01krdgeqcxet5s7t44vh8rt9mg");
6529
7375
  */
6530
7376
  delete(contactId: string, options?: RequestOptions): APIPromise<void>;
7377
+ }
7378
+ //#endregion
7379
+ //#region src/resources/contacts.d.ts
7380
+ /** Body for `bird.contacts.update` — a partial patch. */
7381
+ type ContactUpdateParams = ContactUpdateRequest;
7382
+ /** Body for `bird.contacts.batch` — create-or-update many contacts in one call. */
7383
+ type ContactBatchParams = ContactUpsertRequest;
7384
+ declare class ContactsResource extends ContactsResourceBase {
7385
+ /**
7386
+ * Update a contact. Only the fields you send change.
7387
+ *
7388
+ * @example
7389
+ * const contact = await bird.contacts.update("con_01krdgeqcxet5s7t44vh8rt9mg", {
7390
+ * first_name: "Jane",
7391
+ * });
7392
+ */
7393
+ update(contactId: string, params: ContactUpdateParams, options?: RequestOptions): APIPromise<Contact>;
6531
7394
  /**
6532
7395
  * Create or update many contacts in one call, matched by email. Returns a
6533
7396
  * per-contact result.
@@ -6798,6 +7661,226 @@ declare class WebhooksResource {
6798
7661
  unwrap(payload: string, headers: WebhookHeaders, options?: WebhookOptions): BirdWebhookEvent;
6799
7662
  }
6800
7663
  //#endregion
7664
+ //#region src/resources/mailbox.d.ts
7665
+ /** Parameters for creating a mailbox. */
7666
+ type MailboxCreateParams = MailboxCreate;
7667
+ /** Partial update for a mailbox; omitted fields are unchanged. */
7668
+ type MailboxUpdateParams = MailboxUpdate;
7669
+ /** Filters for `bird.mailbox.list`. */
7670
+ type MailboxListQuery = NonNullable<ListMailboxesData["query"]>;
7671
+ /** Stats query parameters. */
7672
+ type MailboxStatsQuery = NonNullable<GetMailboxStatsData["query"]>;
7673
+ /** Parameters for composing a new message from a mailbox. */
7674
+ type MailboxComposeParams = EmailMailboxComposeRequest;
7675
+ /** Parameters for creating a receive rule. */
7676
+ type MailboxReceiveRuleCreateParams = ReceiveRuleCreate;
7677
+ /** Filters for `bird.mailboxReceiveRule.list`. */
7678
+ type MailboxReceiveRuleListQuery = NonNullable<ListMailboxReceiveRulesData["query"]>;
7679
+ declare class MailboxResource extends Resource {
7680
+ /**
7681
+ * Create a mailbox. Omit `local_part` to auto-generate a handle on inbox.ai.
7682
+ *
7683
+ * @example Create a mailbox
7684
+ * const mailbox = await bird.mailbox.create({ display_name: "Support" });
7685
+ * console.log(mailbox.address); // "abc123@inbox.ai"
7686
+ */
7687
+ create(params?: MailboxCreateParams, options?: RequestOptions): APIPromise<Mailbox>;
7688
+ /**
7689
+ * Get a mailbox by id.
7690
+ *
7691
+ * @example Get a mailbox
7692
+ * const mailbox = await bird.mailbox.get("mbx_01abc");
7693
+ * console.log(mailbox.state); // "active"
7694
+ */
7695
+ get(mailboxId: string, options?: RequestOptions): APIPromise<Mailbox>;
7696
+ /**
7697
+ * Update a mailbox. Only the fields you provide change.
7698
+ *
7699
+ * @example Update receive policy
7700
+ * const mailbox = await bird.mailbox.update("mbx_01abc", { receive_policy: "open" });
7701
+ */
7702
+ update(mailboxId: string, params: MailboxUpdateParams, options?: RequestOptions): APIPromise<Mailbox>;
7703
+ /**
7704
+ * Soft-delete a mailbox. It can be restored within 30 days.
7705
+ *
7706
+ * @example Delete a mailbox
7707
+ * await bird.mailbox.delete("mbx_01abc");
7708
+ */
7709
+ delete(mailboxId: string, options?: RequestOptions): APIPromise<void>;
7710
+ /**
7711
+ * Restore a deleted mailbox within its 30-day window.
7712
+ *
7713
+ * @example Restore a mailbox
7714
+ * const mailbox = await bird.mailbox.restore("mbx_01abc");
7715
+ */
7716
+ restore(mailboxId: string, options?: RequestOptions): APIPromise<Mailbox>;
7717
+ /**
7718
+ * Reactivate a suspended mailbox.
7719
+ *
7720
+ * @example Resume a mailbox
7721
+ * const mailbox = await bird.mailbox.resume("mbx_01abc");
7722
+ */
7723
+ resume(mailboxId: string, options?: RequestOptions): APIPromise<Mailbox>;
7724
+ /**
7725
+ * Get email activity statistics for a mailbox.
7726
+ *
7727
+ * @example Get mailbox stats
7728
+ * const stats = await bird.mailbox.stats("mbx_01abc");
7729
+ * console.log(stats.summary?.sends_accepted);
7730
+ */
7731
+ stats(mailboxId: string, query?: MailboxStatsQuery, options?: RequestOptions): APIPromise<MailboxStatsResponse>;
7732
+ /**
7733
+ * Send a new email from this mailbox, starting a new conversation.
7734
+ *
7735
+ * @example Send from a mailbox
7736
+ * const msg = await bird.mailbox.compose("mbx_01abc", {
7737
+ * to: ["customer@example.com"],
7738
+ * subject: "Hello",
7739
+ * text: "Hi there!",
7740
+ * });
7741
+ */
7742
+ compose(mailboxId: string, params: MailboxComposeParams, options?: RequestOptions): APIPromise<EmailThreadMessage>;
7743
+ /**
7744
+ * List labels available in a mailbox.
7745
+ *
7746
+ * @example List labels
7747
+ * const labels = await bird.mailbox.labels("mbx_01abc");
7748
+ * console.log(labels.data.map(l => l.name));
7749
+ */
7750
+ labels(mailboxId: string, options?: RequestOptions): APIPromise<EmailMailboxLabelList>;
7751
+ /**
7752
+ * List mailboxes in the workspace. `await` resolves the first page;
7753
+ * `for await` walks every mailbox.
7754
+ *
7755
+ * @example List mailboxes
7756
+ * for await (const mailbox of bird.mailbox.list()) {
7757
+ * console.log(mailbox.address);
7758
+ * }
7759
+ */
7760
+ list(query?: MailboxListQuery, options?: RequestOptions): PaginatedPromise<Mailbox>;
7761
+ }
7762
+ declare class MailboxReceiveRuleResource extends Resource {
7763
+ /**
7764
+ * Add an allow or block rule to a mailbox. Block rules always win.
7765
+ *
7766
+ * @example Block a domain
7767
+ * const rule = await bird.mailboxReceiveRule.create("mbx_01abc", {
7768
+ * action: "block",
7769
+ * entry: "spam.example.com",
7770
+ * });
7771
+ */
7772
+ create(mailboxId: string, params: MailboxReceiveRuleCreateParams, options?: RequestOptions): APIPromise<ReceiveRule>;
7773
+ /**
7774
+ * Remove a receive rule.
7775
+ *
7776
+ * @example Delete a rule
7777
+ * await bird.mailboxReceiveRule.delete("mbx_01abc", "erl_01xyz");
7778
+ */
7779
+ delete(mailboxId: string, ruleId: string, options?: RequestOptions): APIPromise<void>;
7780
+ /**
7781
+ * List receive rules for a mailbox.
7782
+ *
7783
+ * @example List rules
7784
+ * for await (const rule of bird.mailboxReceiveRule.list("mbx_01abc")) {
7785
+ * console.log(rule.action, rule.entry);
7786
+ * }
7787
+ */
7788
+ list(mailboxId: string, query?: MailboxReceiveRuleListQuery, options?: RequestOptions): PaginatedPromise<ReceiveRule>;
7789
+ }
7790
+ //#endregion
7791
+ //#region src/resources/mailboxThread.d.ts
7792
+ /** Partial update for a thread — add/remove labels, link/unlink a contact. */
7793
+ type MailboxThreadUpdateParams = EmailThreadUpdateRequest;
7794
+ /** Filters for `bird.mailboxThread.list`. */
7795
+ type MailboxThreadListQuery = NonNullable<ListEmailThreadsData["query"]>;
7796
+ /** Parameters for `bird.mailboxThreadMessage.reply`. */
7797
+ type MailboxThreadMessageReplyParams = EmailThreadMessageReplyRequest;
7798
+ /** Filters for `bird.mailboxThreadMessage.list`. */
7799
+ type MailboxThreadMessageListQuery = NonNullable<ListEmailThreadMessagesData["query"]>;
7800
+ declare class MailboxThreadResource extends Resource {
7801
+ /**
7802
+ * Get a conversation thread.
7803
+ *
7804
+ * @example Get a thread
7805
+ * const thread = await bird.mailboxThread.get("thr_01abc");
7806
+ * console.log(thread.message_count);
7807
+ */
7808
+ get(threadId: string, options?: RequestOptions): APIPromise<EmailThread>;
7809
+ /**
7810
+ * Apply label changes or contact link changes to a thread.
7811
+ *
7812
+ * @example Archive a thread
7813
+ * const thread = await bird.mailboxThread.update("thr_01abc", {
7814
+ * labels: { add: ["archive"] },
7815
+ * });
7816
+ */
7817
+ update(threadId: string, params: MailboxThreadUpdateParams, options?: RequestOptions): APIPromise<EmailThread>;
7818
+ /**
7819
+ * Move a thread to trash. Pass `query.permanent = true` to delete immediately.
7820
+ *
7821
+ * @example Delete a thread
7822
+ * await bird.mailboxThread.delete("thr_01abc");
7823
+ */
7824
+ delete(threadId: string, query?: {
7825
+ permanent?: boolean;
7826
+ }, options?: RequestOptions): APIPromise<void>;
7827
+ /**
7828
+ * List threads across the workspace's mailboxes. `await` resolves the first
7829
+ * page; `for await` walks every thread.
7830
+ *
7831
+ * @example List threads in the inbox
7832
+ * for await (const thread of bird.mailboxThread.list()) {
7833
+ * console.log(thread.id, thread.message_count);
7834
+ * }
7835
+ */
7836
+ list(query?: MailboxThreadListQuery, options?: RequestOptions): PaginatedPromise<EmailThread>;
7837
+ }
7838
+ declare class MailboxThreadMessageResource extends Resource {
7839
+ /**
7840
+ * Get metadata for a message (not the body; use `body` for that).
7841
+ *
7842
+ * @example Get a message
7843
+ * const msg = await bird.mailboxThreadMessage.get("thr_01abc", "rem_01xyz");
7844
+ * console.log(msg.direction); // "inbound"
7845
+ */
7846
+ get(threadId: string, messageId: string, options?: RequestOptions): APIPromise<EmailThreadMessage>;
7847
+ /**
7848
+ * Get the parsed HTML and plain-text body of a message.
7849
+ *
7850
+ * @example Get message body
7851
+ * const body = await bird.mailboxThreadMessage.body("thr_01abc", "rem_01xyz");
7852
+ * console.log(body.text);
7853
+ */
7854
+ body(threadId: string, messageId: string, options?: RequestOptions): APIPromise<EmailThreadMessageBody>;
7855
+ /**
7856
+ * Reply to a message from the mailbox's own address.
7857
+ *
7858
+ * @example Reply to a message
7859
+ * const reply = await bird.mailboxThreadMessage.reply("thr_01abc", "rem_01xyz", {
7860
+ * text: "Thanks for reaching out!",
7861
+ * });
7862
+ */
7863
+ reply(threadId: string, messageId: string, params: MailboxThreadMessageReplyParams, options?: RequestOptions): APIPromise<EmailThreadMessage>;
7864
+ /**
7865
+ * List the attachment manifest for a message.
7866
+ *
7867
+ * @example List attachments
7868
+ * const atts = await bird.mailboxThreadMessage.attachments("thr_01abc", "rem_01xyz");
7869
+ * console.log(atts.data.map(a => a.filename));
7870
+ */
7871
+ attachments(threadId: string, messageId: string, options?: RequestOptions): APIPromise<EmailThreadMessageAttachmentList>;
7872
+ /**
7873
+ * List messages in a thread. `await` resolves the first page; `for await`
7874
+ * walks every message.
7875
+ *
7876
+ * @example List messages
7877
+ * for await (const msg of bird.mailboxThreadMessage.list("thr_01abc")) {
7878
+ * console.log(msg.id, msg.direction);
7879
+ * }
7880
+ */
7881
+ list(threadId: string, query?: MailboxThreadMessageListQuery, options?: RequestOptions): PaginatedPromise<EmailThreadMessage>;
7882
+ }
7883
+ //#endregion
6801
7884
  //#region src/client.d.ts
6802
7885
  interface BirdClientOptions {
6803
7886
  apiKey: string;
@@ -6893,6 +7976,14 @@ declare class BirdClient<const O extends BirdClientOptions = BirdClientOptions>
6893
7976
  readonly domains: DomainsResource;
6894
7977
  /** Webhooks — `bird.webhooks.unwrap(payload, headers)` verifies an inbound delivery. */
6895
7978
  readonly webhooks: WebhooksResource;
7979
+ /** Agent mailboxes — `bird.mailbox.create(...)`, `.compose(...)`, `.list(...)`, … */
7980
+ readonly mailbox: MailboxResource;
7981
+ /** Mailbox receive rules — `bird.mailboxReceiveRule.create(...)`, `.delete(...)`, `.list(...)`. */
7982
+ readonly mailboxReceiveRule: MailboxReceiveRuleResource;
7983
+ /** Mailbox threads — `bird.mailboxThread.list(...)`, `.get(...)`, `.update(...)`, `.delete(...)`. */
7984
+ readonly mailboxThread: MailboxThreadResource;
7985
+ /** Thread messages — `bird.mailboxThreadMessage.list(...)`, `.get(...)`, `.reply(...)`, `.body(...)`, … */
7986
+ readonly mailboxThreadMessage: MailboxThreadMessageResource;
6896
7987
  constructor(options: O);
6897
7988
  /**
6898
7989
  * Escape hatch for endpoints the typed resources don't cover. Runs the full
@@ -6962,9 +8053,9 @@ declare const WebhookEventType: {
6962
8053
  readonly SmsTfnVerificationRejected: "sms.tfn_verification.rejected";
6963
8054
  readonly SmsTfnVerificationSubmitted: "sms.tfn_verification.submitted";
6964
8055
  readonly SmsUndelivered: "sms.undelivered";
6965
- readonly VoiceCallAnswered: "voice.call.answered";
6966
- readonly VoiceCallEnded: "voice.call.ended";
6967
- readonly VoiceCallInitiated: "voice.call.initiated";
8056
+ readonly VoiceCallAnswered: "voice_call.answered";
8057
+ readonly VoiceCallEnded: "voice_call.ended";
8058
+ readonly VoiceCallInitiated: "voice_call.initiated";
6968
8059
  readonly WhatsappAccepted: "whatsapp.accepted";
6969
8060
  readonly WhatsappDelivered: "whatsapp.delivered";
6970
8061
  readonly WhatsappFailed: "whatsapp.failed";
@@ -6975,5 +8066,5 @@ declare const WebhookEventType: {
6975
8066
  /** A known webhook event type value. */
6976
8067
  type WebhookEventTypeValue = (typeof WebhookEventType)[keyof typeof WebhookEventType];
6977
8068
  //#endregion
6978
- export { type APIPromise, type Audience, type AudienceAddContactsParams, type AudienceContactsQuery, type AudienceCreateParams, type AudienceListQuery, type AudienceMember, type AudienceRemoveContactsParams, type AudienceUpdateParams, BirdAPIError, BirdAuthError, BirdBadRequestError, BirdBillingError, BirdClient, type BirdClientOptions, BirdConflictError, BirdConnectionError, BirdError, BirdInternalError, BirdMisdirectedError, BirdNotFoundError, BirdNotImplementedError, BirdPayloadTooLargeError, BirdPermissionError, BirdPreconditionError, BirdRateLimitError, type BirdRequest, type BirdResponse, BirdServiceUnavailableError, BirdTimeoutError, BirdValidationError, type BirdWebhookEvent, BirdWebhookVerificationError, type Contact, type ContactBatchParams, type ContactCreateParams, type ContactListQuery, type ContactProperty, type ContactPropertyCreateParams, type ContactPropertyListQuery, type ContactPropertyUpdateParams, type ContactUpdateParams, type ContactUpsertResult, type CursorPage, type DnsRecord, type Domain, type DomainCapabilities, type DomainCreateParams, type DomainDkim, type DomainListQuery, type DomainUpdateParams, type EmailChannelDefaults, type EmailListQuery, 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 ErrorDetail, type ErrorNextAction, type PaginatedPromise, type RequestOptions, type SafeResult, type SmsListQuery, type SmsMessage, type SmsSendBatchParams, type SmsSendBatchResult, type SmsSendParams, type SmsTemplate, type SmsTemplateList, type SmsTemplateListQuery, type UnmetGate, type Verification, type VerificationCheckParams, type VerificationCheckResult, type VerificationCreateParams, WebhookEventType, type WebhookEventTypeValue, type WebhookHeaders, type WebhookOptions, type WhatsAppEventList, type WhatsAppMessage, type WhatsAppTemplate, type WhatsAppTemplateList, type WhatsappListEventsQuery, type WhatsappListQuery, type WhatsappSendParams, baseUrlForRegion, regionFromApiKey };
8069
+ export { type APIPromise, type Audience, type AudienceAddContactsParams, type AudienceContactsQuery, type AudienceCreateParams, type AudienceListQuery, type AudienceMember, type AudienceRemoveContactsParams, type AudienceUpdateParams, BirdAPIError, BirdAuthError, BirdBadRequestError, BirdBillingError, BirdClient, type BirdClientOptions, BirdConflictError, BirdConnectionError, BirdError, BirdInternalError, BirdMisdirectedError, BirdNotFoundError, BirdNotImplementedError, BirdPayloadTooLargeError, BirdPermissionError, BirdPreconditionError, BirdRateLimitError, type BirdRequest, type BirdResponse, BirdServiceUnavailableError, BirdTimeoutError, BirdValidationError, type BirdWebhookEvent, BirdWebhookVerificationError, type Contact, type ContactBatchParams, type ContactCreateParams, type ContactListQuery, type ContactProperty, type ContactPropertyCreateParams, type ContactPropertyListQuery, type ContactPropertyUpdateParams, type ContactUpdateParams, type ContactUpsertResult, type CursorPage, type DnsRecord, type Domain, type DomainCapabilities, type DomainCreateParams, type DomainDkim, type DomainListQuery, type DomainUpdateParams, type EmailChannelDefaults, type EmailListQuery, type EmailMailboxLabelList, 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 EmailThreadList, type EmailThreadMessage, type EmailThreadMessageAttachmentList, type EmailThreadMessageBody, type EmailThreadMessageList, type ErrorDetail, type ErrorNextAction, type Mailbox, type MailboxComposeParams, type MailboxCreateParams, type MailboxList, type MailboxListQuery, type MailboxReceiveRuleCreateParams, type MailboxReceiveRuleListQuery, type MailboxStatsResponse, type MailboxThreadListQuery, type MailboxThreadMessageListQuery, type MailboxThreadMessageReplyParams, type MailboxThreadUpdateParams, type MailboxUpdateParams, type PaginatedPromise, type ReceiveRule, type ReceiveRuleList, type RequestOptions, type SafeResult, type SmsListQuery, type SmsMessage, type SmsSendBatchParams, type SmsSendBatchResult, type SmsSendParams, type SmsTemplate, type SmsTemplateList, type SmsTemplateListQuery, type UnmetGate, type Verification, type VerificationCheckParams, type VerificationCheckResult, type VerificationCreateParams, WebhookEventType, type WebhookEventTypeValue, type WebhookHeaders, type WebhookOptions, type WhatsAppEventList, type WhatsAppMessage, type WhatsAppTemplate, type WhatsAppTemplateList, type WhatsappListEventsQuery, type WhatsappListQuery, type WhatsappSendParams, baseUrlForRegion, regionFromApiKey };
6979
8070
  //# sourceMappingURL=index.d.mts.map