linq-python 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. linq/__init__.py +102 -0
  2. linq/_base_client.py +2149 -0
  3. linq/_client.py +2479 -0
  4. linq/_compat.py +226 -0
  5. linq/_constants.py +14 -0
  6. linq/_exceptions.py +108 -0
  7. linq/_files.py +123 -0
  8. linq/_models.py +878 -0
  9. linq/_qs.py +153 -0
  10. linq/_resource.py +43 -0
  11. linq/_response.py +833 -0
  12. linq/_streaming.py +338 -0
  13. linq/_types.py +271 -0
  14. linq/_utils/__init__.py +65 -0
  15. linq/_utils/_compat.py +45 -0
  16. linq/_utils/_datetime_parse.py +136 -0
  17. linq/_utils/_json.py +35 -0
  18. linq/_utils/_logs.py +25 -0
  19. linq/_utils/_path.py +127 -0
  20. linq/_utils/_proxy.py +65 -0
  21. linq/_utils/_reflection.py +42 -0
  22. linq/_utils/_resources_proxy.py +24 -0
  23. linq/_utils/_streams.py +12 -0
  24. linq/_utils/_sync.py +58 -0
  25. linq/_utils/_transform.py +457 -0
  26. linq/_utils/_typing.py +156 -0
  27. linq/_utils/_utils.py +421 -0
  28. linq/_version.py +4 -0
  29. linq/lib/.keep +4 -0
  30. linq/pagination.py +95 -0
  31. linq/py.typed +0 -0
  32. linq/resources/__init__.py +134 -0
  33. linq/resources/attachments.py +589 -0
  34. linq/resources/capability.py +297 -0
  35. linq/resources/chats/__init__.py +61 -0
  36. linq/resources/chats/chats.py +1492 -0
  37. linq/resources/chats/messages.py +416 -0
  38. linq/resources/chats/participants.py +322 -0
  39. linq/resources/chats/typing.py +299 -0
  40. linq/resources/contact_card.py +472 -0
  41. linq/resources/messages.py +686 -0
  42. linq/resources/phone_numbers.py +163 -0
  43. linq/resources/phonenumbers.py +165 -0
  44. linq/resources/webhook_events.py +319 -0
  45. linq/resources/webhook_subscriptions.py +776 -0
  46. linq/resources/webhooks.py +34 -0
  47. linq/types/__init__.py +90 -0
  48. linq/types/attachment_create_params.py +42 -0
  49. linq/types/attachment_create_response.py +44 -0
  50. linq/types/attachment_retrieve_response.py +55 -0
  51. linq/types/capability_check_RCS_params.py +20 -0
  52. linq/types/capability_check_i_message_params.py +20 -0
  53. linq/types/chat.py +44 -0
  54. linq/types/chat_create_params.py +33 -0
  55. linq/types/chat_create_response.py +44 -0
  56. linq/types/chat_created_webhook_event.py +87 -0
  57. linq/types/chat_group_icon_update_failed_webhook_event.py +65 -0
  58. linq/types/chat_group_icon_updated_webhook_event.py +66 -0
  59. linq/types/chat_group_name_update_failed_webhook_event.py +65 -0
  60. linq/types/chat_group_name_updated_webhook_event.py +66 -0
  61. linq/types/chat_leave_chat_response.py +15 -0
  62. linq/types/chat_list_chats_params.py +36 -0
  63. linq/types/chat_send_voicememo_params.py +23 -0
  64. linq/types/chat_send_voicememo_response.py +79 -0
  65. linq/types/chat_typing_indicator_started_webhook_event.py +52 -0
  66. linq/types/chat_typing_indicator_stopped_webhook_event.py +52 -0
  67. linq/types/chat_update_params.py +15 -0
  68. linq/types/chat_update_response.py +13 -0
  69. linq/types/chats/__init__.py +12 -0
  70. linq/types/chats/message_list_params.py +15 -0
  71. linq/types/chats/message_send_params.py +18 -0
  72. linq/types/chats/message_send_response.py +16 -0
  73. linq/types/chats/participant_add_params.py +12 -0
  74. linq/types/chats/participant_add_response.py +15 -0
  75. linq/types/chats/participant_remove_params.py +12 -0
  76. linq/types/chats/participant_remove_response.py +15 -0
  77. linq/types/chats/sent_message.py +69 -0
  78. linq/types/contact_card_create_params.py +24 -0
  79. linq/types/contact_card_retrieve_params.py +15 -0
  80. linq/types/contact_card_retrieve_response.py +23 -0
  81. linq/types/contact_card_update_params.py +21 -0
  82. linq/types/events_webhook_event.py +50 -0
  83. linq/types/handle_check_response.py +13 -0
  84. linq/types/link_part_param.py +22 -0
  85. linq/types/media_part_param.py +54 -0
  86. linq/types/message.py +87 -0
  87. linq/types/message_add_reaction_params.py +32 -0
  88. linq/types/message_add_reaction_response.py +15 -0
  89. linq/types/message_content_param.py +82 -0
  90. linq/types/message_delivered_webhook_event.py +65 -0
  91. linq/types/message_edited_webhook_event.py +100 -0
  92. linq/types/message_effect.py +23 -0
  93. linq/types/message_effect_param.py +22 -0
  94. linq/types/message_event_v2.py +116 -0
  95. linq/types/message_failed_webhook_event.py +72 -0
  96. linq/types/message_list_messages_thread_params.py +18 -0
  97. linq/types/message_read_webhook_event.py +65 -0
  98. linq/types/message_received_webhook_event.py +65 -0
  99. linq/types/message_sent_webhook_event.py +65 -0
  100. linq/types/message_update_params.py +15 -0
  101. linq/types/participant_added_webhook_event.py +66 -0
  102. linq/types/participant_removed_webhook_event.py +66 -0
  103. linq/types/phone_number_list_response.py +20 -0
  104. linq/types/phone_number_status_updated_webhook_event.py +82 -0
  105. linq/types/phonenumber_list_response.py +39 -0
  106. linq/types/reaction_added_webhook_event.py +46 -0
  107. linq/types/reaction_event_base.py +85 -0
  108. linq/types/reaction_removed_webhook_event.py +46 -0
  109. linq/types/reply_to.py +21 -0
  110. linq/types/reply_to_param.py +21 -0
  111. linq/types/schemas_media_part_response.py +29 -0
  112. linq/types/schemas_message_effect.py +18 -0
  113. linq/types/schemas_text_part_response.py +22 -0
  114. linq/types/set_contact_card.py +24 -0
  115. linq/types/shared/__init__.py +9 -0
  116. linq/types/shared/chat_handle.py +33 -0
  117. linq/types/shared/media_part_response.py +34 -0
  118. linq/types/shared/reaction.py +56 -0
  119. linq/types/shared/reaction_type.py +7 -0
  120. linq/types/shared/service_type.py +7 -0
  121. linq/types/shared/text_decoration.py +23 -0
  122. linq/types/shared/text_part_response.py +26 -0
  123. linq/types/shared_params/__init__.py +5 -0
  124. linq/types/shared_params/reaction_type.py +9 -0
  125. linq/types/shared_params/service_type.py +9 -0
  126. linq/types/shared_params/text_decoration.py +23 -0
  127. linq/types/supported_content_type.py +60 -0
  128. linq/types/text_part_param.py +44 -0
  129. linq/types/webhook_event_list_response.py +17 -0
  130. linq/types/webhook_event_type.py +33 -0
  131. linq/types/webhook_subscription.py +35 -0
  132. linq/types/webhook_subscription_create_params.py +27 -0
  133. linq/types/webhook_subscription_create_response.py +46 -0
  134. linq/types/webhook_subscription_list_response.py +13 -0
  135. linq/types/webhook_subscription_update_params.py +30 -0
  136. linq_python-0.1.0.dist-info/METADATA +572 -0
  137. linq_python-0.1.0.dist-info/RECORD +139 -0
  138. linq_python-0.1.0.dist-info/WHEEL +4 -0
  139. linq_python-0.1.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,1492 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ import httpx
6
+
7
+ from .typing import (
8
+ TypingResource,
9
+ AsyncTypingResource,
10
+ TypingResourceWithRawResponse,
11
+ AsyncTypingResourceWithRawResponse,
12
+ TypingResourceWithStreamingResponse,
13
+ AsyncTypingResourceWithStreamingResponse,
14
+ )
15
+ from ...types import (
16
+ chat_create_params,
17
+ chat_update_params,
18
+ chat_list_chats_params,
19
+ chat_send_voicememo_params,
20
+ )
21
+ from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
22
+ from ..._utils import path_template, maybe_transform, async_maybe_transform
23
+ from .messages import (
24
+ MessagesResource,
25
+ AsyncMessagesResource,
26
+ MessagesResourceWithRawResponse,
27
+ AsyncMessagesResourceWithRawResponse,
28
+ MessagesResourceWithStreamingResponse,
29
+ AsyncMessagesResourceWithStreamingResponse,
30
+ )
31
+ from ..._compat import cached_property
32
+ from ..._resource import SyncAPIResource, AsyncAPIResource
33
+ from ..._response import (
34
+ to_raw_response_wrapper,
35
+ to_streamed_response_wrapper,
36
+ async_to_raw_response_wrapper,
37
+ async_to_streamed_response_wrapper,
38
+ )
39
+ from ...pagination import SyncListChatsPagination, AsyncListChatsPagination
40
+ from ...types.chat import Chat
41
+ from .participants import (
42
+ ParticipantsResource,
43
+ AsyncParticipantsResource,
44
+ ParticipantsResourceWithRawResponse,
45
+ AsyncParticipantsResourceWithRawResponse,
46
+ ParticipantsResourceWithStreamingResponse,
47
+ AsyncParticipantsResourceWithStreamingResponse,
48
+ )
49
+ from ..._base_client import AsyncPaginator, make_request_options
50
+ from ...types.chat_create_response import ChatCreateResponse
51
+ from ...types.chat_update_response import ChatUpdateResponse
52
+ from ...types.message_content_param import MessageContentParam
53
+ from ...types.chat_leave_chat_response import ChatLeaveChatResponse
54
+ from ...types.chat_send_voicememo_response import ChatSendVoicememoResponse
55
+
56
+ __all__ = ["ChatsResource", "AsyncChatsResource"]
57
+
58
+
59
+ class ChatsResource(SyncAPIResource):
60
+ @cached_property
61
+ def participants(self) -> ParticipantsResource:
62
+ """A Chat is a conversation thread with one or more participants.
63
+
64
+ To begin a chat, you must create a Chat with at least one recipient handle.
65
+ Including multiple handles creates a group chat.
66
+
67
+ When creating a chat, the `from` field specifies which of your
68
+ authorized phone numbers the message originates from. Your authentication token grants
69
+ access to one or more phone numbers, but the `from` field determines the actual sender.
70
+
71
+ **Handle Format:**
72
+ - Handles can be phone numbers or email addresses
73
+ - Phone numbers MUST be in E.164 format (starting with +)
74
+ - Phone format: `+[country code][subscriber number]`
75
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
76
+ - Example email: `user@example.com`
77
+ - No spaces, dashes, or parentheses in phone numbers
78
+ """
79
+ return ParticipantsResource(self._client)
80
+
81
+ @cached_property
82
+ def typing(self) -> TypingResource:
83
+ """A Chat is a conversation thread with one or more participants.
84
+
85
+ To begin a chat, you must create a Chat with at least one recipient handle.
86
+ Including multiple handles creates a group chat.
87
+
88
+ When creating a chat, the `from` field specifies which of your
89
+ authorized phone numbers the message originates from. Your authentication token grants
90
+ access to one or more phone numbers, but the `from` field determines the actual sender.
91
+
92
+ **Handle Format:**
93
+ - Handles can be phone numbers or email addresses
94
+ - Phone numbers MUST be in E.164 format (starting with +)
95
+ - Phone format: `+[country code][subscriber number]`
96
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
97
+ - Example email: `user@example.com`
98
+ - No spaces, dashes, or parentheses in phone numbers
99
+ """
100
+ return TypingResource(self._client)
101
+
102
+ @cached_property
103
+ def messages(self) -> MessagesResource:
104
+ """Messages are individual communications within a chat thread.
105
+
106
+ Messages can include text, media attachments, rich link previews, special effects
107
+ (like confetti or fireworks), and reactions. All messages are associated with a
108
+ specific chat and sent from a phone number you own.
109
+
110
+ Messages support delivery status tracking, read receipts, and editing capabilities.
111
+
112
+ ## Rich Link Previews
113
+
114
+ Send a URL as a `link` part to deliver it with a rich preview card showing the
115
+ page's title, description, and image (when available). A `link` part must be the
116
+ **only** part in the message — it cannot be combined with text or media parts.
117
+ To send a URL without a preview card, include it in a `text` part instead.
118
+
119
+ **Limitations:**
120
+ - A `link` part cannot be combined with other parts in the same message.
121
+ - Maximum URL length: 2,048 characters.
122
+ """
123
+ return MessagesResource(self._client)
124
+
125
+ @cached_property
126
+ def with_raw_response(self) -> ChatsResourceWithRawResponse:
127
+ """
128
+ This property can be used as a prefix for any HTTP method call to return
129
+ the raw response object instead of the parsed content.
130
+
131
+ For more information, see https://www.github.com/linq-team/linq-python#accessing-raw-response-data-eg-headers
132
+ """
133
+ return ChatsResourceWithRawResponse(self)
134
+
135
+ @cached_property
136
+ def with_streaming_response(self) -> ChatsResourceWithStreamingResponse:
137
+ """
138
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
139
+
140
+ For more information, see https://www.github.com/linq-team/linq-python#with_streaming_response
141
+ """
142
+ return ChatsResourceWithStreamingResponse(self)
143
+
144
+ def create(
145
+ self,
146
+ *,
147
+ from_: str,
148
+ message: MessageContentParam,
149
+ to: SequenceNotStr[str],
150
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
151
+ # The extra values given here take precedence over values defined on the client or passed to this method.
152
+ extra_headers: Headers | None = None,
153
+ extra_query: Query | None = None,
154
+ extra_body: Body | None = None,
155
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
156
+ ) -> ChatCreateResponse:
157
+ """Create a new chat with specified participants and send an initial message.
158
+
159
+ The
160
+ initial message is required when creating a chat.
161
+
162
+ ## Message Effects
163
+
164
+ You can add iMessage effects to make your messages more expressive. Effects are
165
+ optional and can be either screen effects (full-screen animations) or bubble
166
+ effects (message bubble animations).
167
+
168
+ **Screen Effects:** `confetti`, `fireworks`, `lasers`, `sparkles`,
169
+ `celebration`, `hearts`, `love`, `balloons`, `happy_birthday`, `echo`,
170
+ `spotlight`
171
+
172
+ **Bubble Effects:** `slam`, `loud`, `gentle`, `invisible`
173
+
174
+ Only one effect type can be applied per message.
175
+
176
+ ## Inline Text Decorations (iMessage only)
177
+
178
+ Use the `text_decorations` array on a text part to apply styling and animations
179
+ to character ranges.
180
+
181
+ Each decoration specifies a `range: [start, end)` and exactly one of `style` or
182
+ `animation`.
183
+
184
+ **Styles:** `bold`, `italic`, `strikethrough`, `underline` **Animations:**
185
+ `big`, `small`, `shake`, `nod`, `explode`, `ripple`, `bloom`, `jitter`
186
+
187
+ ```json
188
+ {
189
+ "type": "text",
190
+ "value": "Hello world",
191
+ "text_decorations": [
192
+ { "range": [0, 5], "style": "bold" },
193
+ { "range": [6, 11], "animation": "shake" }
194
+ ]
195
+ }
196
+ ```
197
+
198
+ **Note:** Style ranges (bold, italic, etc.) may overlap, but animation ranges
199
+ must not overlap with other animations or styles. Text decorations only render
200
+ for iMessage recipients. For SMS/RCS, text decorations are not applied.
201
+
202
+ Args:
203
+ from_: Sender phone number in E.164 format. Must be a phone number that the
204
+ authenticated partner has permission to send from.
205
+
206
+ message: Message content container. Groups all message-related fields together,
207
+ separating the "what" (message content) from the "where" (routing fields like
208
+ from/to).
209
+
210
+ to: Array of recipient handles (phone numbers in E.164 format or email addresses).
211
+ For individual chats, provide one recipient. For group chats, provide multiple.
212
+
213
+ extra_headers: Send extra headers
214
+
215
+ extra_query: Add additional query parameters to the request
216
+
217
+ extra_body: Add additional JSON properties to the request
218
+
219
+ timeout: Override the client-level default timeout for this request, in seconds
220
+ """
221
+ return self._post(
222
+ "/v3/chats",
223
+ body=maybe_transform(
224
+ {
225
+ "from_": from_,
226
+ "message": message,
227
+ "to": to,
228
+ },
229
+ chat_create_params.ChatCreateParams,
230
+ ),
231
+ options=make_request_options(
232
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
233
+ ),
234
+ cast_to=ChatCreateResponse,
235
+ )
236
+
237
+ def retrieve(
238
+ self,
239
+ chat_id: str,
240
+ *,
241
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
242
+ # The extra values given here take precedence over values defined on the client or passed to this method.
243
+ extra_headers: Headers | None = None,
244
+ extra_query: Query | None = None,
245
+ extra_body: Body | None = None,
246
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
247
+ ) -> Chat:
248
+ """
249
+ Retrieve a chat by its unique identifier.
250
+
251
+ Args:
252
+ extra_headers: Send extra headers
253
+
254
+ extra_query: Add additional query parameters to the request
255
+
256
+ extra_body: Add additional JSON properties to the request
257
+
258
+ timeout: Override the client-level default timeout for this request, in seconds
259
+ """
260
+ if not chat_id:
261
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
262
+ return self._get(
263
+ path_template("/v3/chats/{chat_id}", chat_id=chat_id),
264
+ options=make_request_options(
265
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
266
+ ),
267
+ cast_to=Chat,
268
+ )
269
+
270
+ def update(
271
+ self,
272
+ chat_id: str,
273
+ *,
274
+ display_name: str | Omit = omit,
275
+ group_chat_icon: str | Omit = omit,
276
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
277
+ # The extra values given here take precedence over values defined on the client or passed to this method.
278
+ extra_headers: Headers | None = None,
279
+ extra_query: Query | None = None,
280
+ extra_body: Body | None = None,
281
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
282
+ ) -> ChatUpdateResponse:
283
+ """
284
+ Update chat properties such as display name and group chat icon.
285
+
286
+ Listen for `chat.group_name_updated`, `chat.group_icon_updated`,
287
+ `chat.group_name_update_failed`, or `chat.group_icon_update_failed` webhook
288
+ events to confirm the outcome.
289
+
290
+ Args:
291
+ display_name: New display name for the chat (group chats only)
292
+
293
+ group_chat_icon: URL of an image to set as the group chat icon (group chats only)
294
+
295
+ extra_headers: Send extra headers
296
+
297
+ extra_query: Add additional query parameters to the request
298
+
299
+ extra_body: Add additional JSON properties to the request
300
+
301
+ timeout: Override the client-level default timeout for this request, in seconds
302
+ """
303
+ if not chat_id:
304
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
305
+ return self._put(
306
+ path_template("/v3/chats/{chat_id}", chat_id=chat_id),
307
+ body=maybe_transform(
308
+ {
309
+ "display_name": display_name,
310
+ "group_chat_icon": group_chat_icon,
311
+ },
312
+ chat_update_params.ChatUpdateParams,
313
+ ),
314
+ options=make_request_options(
315
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
316
+ ),
317
+ cast_to=ChatUpdateResponse,
318
+ )
319
+
320
+ def leave_chat(
321
+ self,
322
+ chat_id: str,
323
+ *,
324
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
325
+ # The extra values given here take precedence over values defined on the client or passed to this method.
326
+ extra_headers: Headers | None = None,
327
+ extra_query: Query | None = None,
328
+ extra_body: Body | None = None,
329
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
330
+ ) -> ChatLeaveChatResponse:
331
+ """Removes your phone number from a group chat.
332
+
333
+ Once you leave, you will no longer
334
+ receive messages from the group and all interaction endpoints (send message,
335
+ typing, mark read, etc.) will return 409.
336
+
337
+ A `participant.removed` webhook will fire once the leave has been processed.
338
+
339
+ **Supported**
340
+
341
+ - iMessage group chats with 4 or more active participants (including yourself)
342
+
343
+ **Not supported**
344
+
345
+ - DM (1-on-1) chats — use the chat directly to continue the conversation
346
+
347
+ Args:
348
+ extra_headers: Send extra headers
349
+
350
+ extra_query: Add additional query parameters to the request
351
+
352
+ extra_body: Add additional JSON properties to the request
353
+
354
+ timeout: Override the client-level default timeout for this request, in seconds
355
+ """
356
+ if not chat_id:
357
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
358
+ return self._post(
359
+ path_template("/v3/chats/{chat_id}/leave", chat_id=chat_id),
360
+ options=make_request_options(
361
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
362
+ ),
363
+ cast_to=ChatLeaveChatResponse,
364
+ )
365
+
366
+ def list_chats(
367
+ self,
368
+ *,
369
+ cursor: str | Omit = omit,
370
+ from_: str | Omit = omit,
371
+ limit: int | Omit = omit,
372
+ to: str | Omit = omit,
373
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
374
+ # The extra values given here take precedence over values defined on the client or passed to this method.
375
+ extra_headers: Headers | None = None,
376
+ extra_query: Query | None = None,
377
+ extra_body: Body | None = None,
378
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
379
+ ) -> SyncListChatsPagination[Chat]:
380
+ """
381
+ Retrieves a paginated list of chats for the authenticated partner.
382
+
383
+ **Filtering:**
384
+
385
+ - If `from` is provided, returns chats for that specific phone number
386
+ - If `from` is omitted, returns chats across all phone numbers owned by the
387
+ partner
388
+ - If `to` is provided, only returns chats where the specified handle is a
389
+ participant
390
+
391
+ **Pagination:**
392
+
393
+ - Use `limit` to control page size (default: 20, max: 100)
394
+ - The response includes `next_cursor` for fetching the next page
395
+ - When `next_cursor` is `null`, there are no more results to fetch
396
+ - Pass the `next_cursor` value as the `cursor` parameter for the next request
397
+
398
+ **Example pagination flow:**
399
+
400
+ 1. First request: `GET /v3/chats?from=%2B12223334444&limit=20`
401
+ 2. Response includes `next_cursor: "20"` (more results exist)
402
+ 3. Next request: `GET /v3/chats?from=%2B12223334444&limit=20&cursor=20`
403
+ 4. Response includes `next_cursor: null` (no more results)
404
+
405
+ Args:
406
+ cursor: Pagination cursor from the previous response's `next_cursor` field. Omit this
407
+ parameter for the first page of results.
408
+
409
+ from_: Phone number to filter chats by. Returns chats made from this phone number. Must
410
+ be in E.164 format (e.g., `+13343284472`). The `+` is automatically URL-encoded
411
+ by HTTP clients. If omitted, returns chats across all phone numbers owned by the
412
+ partner.
413
+
414
+ limit: Maximum number of chats to return per page
415
+
416
+ to: Filter chats by a participant handle. Only returns chats where this handle is a
417
+ participant. Can be an E.164 phone number (e.g., `+13343284472`) or an email
418
+ address (e.g., `user@example.com`). For phone numbers, the `+` is automatically
419
+ URL-encoded by HTTP clients.
420
+
421
+ extra_headers: Send extra headers
422
+
423
+ extra_query: Add additional query parameters to the request
424
+
425
+ extra_body: Add additional JSON properties to the request
426
+
427
+ timeout: Override the client-level default timeout for this request, in seconds
428
+ """
429
+ return self._get_api_list(
430
+ "/v3/chats",
431
+ page=SyncListChatsPagination[Chat],
432
+ options=make_request_options(
433
+ extra_headers=extra_headers,
434
+ extra_query=extra_query,
435
+ extra_body=extra_body,
436
+ timeout=timeout,
437
+ query=maybe_transform(
438
+ {
439
+ "cursor": cursor,
440
+ "from_": from_,
441
+ "limit": limit,
442
+ "to": to,
443
+ },
444
+ chat_list_chats_params.ChatListChatsParams,
445
+ ),
446
+ ),
447
+ model=Chat,
448
+ )
449
+
450
+ def mark_as_read(
451
+ self,
452
+ chat_id: str,
453
+ *,
454
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
455
+ # The extra values given here take precedence over values defined on the client or passed to this method.
456
+ extra_headers: Headers | None = None,
457
+ extra_query: Query | None = None,
458
+ extra_body: Body | None = None,
459
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
460
+ ) -> None:
461
+ """
462
+ Mark all messages in a chat as read.
463
+
464
+ Args:
465
+ extra_headers: Send extra headers
466
+
467
+ extra_query: Add additional query parameters to the request
468
+
469
+ extra_body: Add additional JSON properties to the request
470
+
471
+ timeout: Override the client-level default timeout for this request, in seconds
472
+ """
473
+ if not chat_id:
474
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
475
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
476
+ return self._post(
477
+ path_template("/v3/chats/{chat_id}/read", chat_id=chat_id),
478
+ options=make_request_options(
479
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
480
+ ),
481
+ cast_to=NoneType,
482
+ )
483
+
484
+ def send_voicememo(
485
+ self,
486
+ chat_id: str,
487
+ *,
488
+ attachment_id: str | Omit = omit,
489
+ voice_memo_url: str | Omit = omit,
490
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
491
+ # The extra values given here take precedence over values defined on the client or passed to this method.
492
+ extra_headers: Headers | None = None,
493
+ extra_query: Query | None = None,
494
+ extra_body: Body | None = None,
495
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
496
+ ) -> ChatSendVoicememoResponse:
497
+ """
498
+ Send an audio file as an **iMessage voice memo bubble** to all participants in a
499
+ chat. Voice memos appear with iMessage's native inline playback UI, unlike
500
+ regular audio attachments sent via media parts which appear as downloadable
501
+ files.
502
+
503
+ **Supported audio formats:**
504
+
505
+ - MP3 (audio/mpeg)
506
+ - M4A (audio/x-m4a, audio/mp4)
507
+ - AAC (audio/aac)
508
+ - CAF (audio/x-caf) - Core Audio Format
509
+ - WAV (audio/wav)
510
+ - AIFF (audio/aiff, audio/x-aiff)
511
+ - AMR (audio/amr)
512
+
513
+ Args:
514
+ attachment_id: Reference to a voice memo file pre-uploaded via `POST /v3/attachments`. The file
515
+ is already stored, so sends using this ID skip the download step.
516
+
517
+ Either `voice_memo_url` or `attachment_id` must be provided, but not both.
518
+
519
+ voice_memo_url: URL of the voice memo audio file. Must be a publicly accessible HTTPS URL.
520
+
521
+ Either `voice_memo_url` or `attachment_id` must be provided, but not both.
522
+
523
+ extra_headers: Send extra headers
524
+
525
+ extra_query: Add additional query parameters to the request
526
+
527
+ extra_body: Add additional JSON properties to the request
528
+
529
+ timeout: Override the client-level default timeout for this request, in seconds
530
+ """
531
+ if not chat_id:
532
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
533
+ return self._post(
534
+ path_template("/v3/chats/{chat_id}/voicememo", chat_id=chat_id),
535
+ body=maybe_transform(
536
+ {
537
+ "attachment_id": attachment_id,
538
+ "voice_memo_url": voice_memo_url,
539
+ },
540
+ chat_send_voicememo_params.ChatSendVoicememoParams,
541
+ ),
542
+ options=make_request_options(
543
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
544
+ ),
545
+ cast_to=ChatSendVoicememoResponse,
546
+ )
547
+
548
+ def share_contact_card(
549
+ self,
550
+ chat_id: str,
551
+ *,
552
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
553
+ # The extra values given here take precedence over values defined on the client or passed to this method.
554
+ extra_headers: Headers | None = None,
555
+ extra_query: Query | None = None,
556
+ extra_body: Body | None = None,
557
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
558
+ ) -> None:
559
+ """
560
+ Share your contact information (Name and Photo Sharing) with a chat.
561
+
562
+ **Note:** A contact card must be configured before sharing. You can set up your
563
+ contact card via the [Contact Card API](#tag/Contact-Card) or on the
564
+ [Linq dashboard](https://dashboard.linqapp.com/contact-cards).
565
+
566
+ Args:
567
+ extra_headers: Send extra headers
568
+
569
+ extra_query: Add additional query parameters to the request
570
+
571
+ extra_body: Add additional JSON properties to the request
572
+
573
+ timeout: Override the client-level default timeout for this request, in seconds
574
+ """
575
+ if not chat_id:
576
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
577
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
578
+ return self._post(
579
+ path_template("/v3/chats/{chat_id}/share_contact_card", chat_id=chat_id),
580
+ options=make_request_options(
581
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
582
+ ),
583
+ cast_to=NoneType,
584
+ )
585
+
586
+
587
+ class AsyncChatsResource(AsyncAPIResource):
588
+ @cached_property
589
+ def participants(self) -> AsyncParticipantsResource:
590
+ """A Chat is a conversation thread with one or more participants.
591
+
592
+ To begin a chat, you must create a Chat with at least one recipient handle.
593
+ Including multiple handles creates a group chat.
594
+
595
+ When creating a chat, the `from` field specifies which of your
596
+ authorized phone numbers the message originates from. Your authentication token grants
597
+ access to one or more phone numbers, but the `from` field determines the actual sender.
598
+
599
+ **Handle Format:**
600
+ - Handles can be phone numbers or email addresses
601
+ - Phone numbers MUST be in E.164 format (starting with +)
602
+ - Phone format: `+[country code][subscriber number]`
603
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
604
+ - Example email: `user@example.com`
605
+ - No spaces, dashes, or parentheses in phone numbers
606
+ """
607
+ return AsyncParticipantsResource(self._client)
608
+
609
+ @cached_property
610
+ def typing(self) -> AsyncTypingResource:
611
+ """A Chat is a conversation thread with one or more participants.
612
+
613
+ To begin a chat, you must create a Chat with at least one recipient handle.
614
+ Including multiple handles creates a group chat.
615
+
616
+ When creating a chat, the `from` field specifies which of your
617
+ authorized phone numbers the message originates from. Your authentication token grants
618
+ access to one or more phone numbers, but the `from` field determines the actual sender.
619
+
620
+ **Handle Format:**
621
+ - Handles can be phone numbers or email addresses
622
+ - Phone numbers MUST be in E.164 format (starting with +)
623
+ - Phone format: `+[country code][subscriber number]`
624
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
625
+ - Example email: `user@example.com`
626
+ - No spaces, dashes, or parentheses in phone numbers
627
+ """
628
+ return AsyncTypingResource(self._client)
629
+
630
+ @cached_property
631
+ def messages(self) -> AsyncMessagesResource:
632
+ """Messages are individual communications within a chat thread.
633
+
634
+ Messages can include text, media attachments, rich link previews, special effects
635
+ (like confetti or fireworks), and reactions. All messages are associated with a
636
+ specific chat and sent from a phone number you own.
637
+
638
+ Messages support delivery status tracking, read receipts, and editing capabilities.
639
+
640
+ ## Rich Link Previews
641
+
642
+ Send a URL as a `link` part to deliver it with a rich preview card showing the
643
+ page's title, description, and image (when available). A `link` part must be the
644
+ **only** part in the message — it cannot be combined with text or media parts.
645
+ To send a URL without a preview card, include it in a `text` part instead.
646
+
647
+ **Limitations:**
648
+ - A `link` part cannot be combined with other parts in the same message.
649
+ - Maximum URL length: 2,048 characters.
650
+ """
651
+ return AsyncMessagesResource(self._client)
652
+
653
+ @cached_property
654
+ def with_raw_response(self) -> AsyncChatsResourceWithRawResponse:
655
+ """
656
+ This property can be used as a prefix for any HTTP method call to return
657
+ the raw response object instead of the parsed content.
658
+
659
+ For more information, see https://www.github.com/linq-team/linq-python#accessing-raw-response-data-eg-headers
660
+ """
661
+ return AsyncChatsResourceWithRawResponse(self)
662
+
663
+ @cached_property
664
+ def with_streaming_response(self) -> AsyncChatsResourceWithStreamingResponse:
665
+ """
666
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
667
+
668
+ For more information, see https://www.github.com/linq-team/linq-python#with_streaming_response
669
+ """
670
+ return AsyncChatsResourceWithStreamingResponse(self)
671
+
672
+ async def create(
673
+ self,
674
+ *,
675
+ from_: str,
676
+ message: MessageContentParam,
677
+ to: SequenceNotStr[str],
678
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
679
+ # The extra values given here take precedence over values defined on the client or passed to this method.
680
+ extra_headers: Headers | None = None,
681
+ extra_query: Query | None = None,
682
+ extra_body: Body | None = None,
683
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
684
+ ) -> ChatCreateResponse:
685
+ """Create a new chat with specified participants and send an initial message.
686
+
687
+ The
688
+ initial message is required when creating a chat.
689
+
690
+ ## Message Effects
691
+
692
+ You can add iMessage effects to make your messages more expressive. Effects are
693
+ optional and can be either screen effects (full-screen animations) or bubble
694
+ effects (message bubble animations).
695
+
696
+ **Screen Effects:** `confetti`, `fireworks`, `lasers`, `sparkles`,
697
+ `celebration`, `hearts`, `love`, `balloons`, `happy_birthday`, `echo`,
698
+ `spotlight`
699
+
700
+ **Bubble Effects:** `slam`, `loud`, `gentle`, `invisible`
701
+
702
+ Only one effect type can be applied per message.
703
+
704
+ ## Inline Text Decorations (iMessage only)
705
+
706
+ Use the `text_decorations` array on a text part to apply styling and animations
707
+ to character ranges.
708
+
709
+ Each decoration specifies a `range: [start, end)` and exactly one of `style` or
710
+ `animation`.
711
+
712
+ **Styles:** `bold`, `italic`, `strikethrough`, `underline` **Animations:**
713
+ `big`, `small`, `shake`, `nod`, `explode`, `ripple`, `bloom`, `jitter`
714
+
715
+ ```json
716
+ {
717
+ "type": "text",
718
+ "value": "Hello world",
719
+ "text_decorations": [
720
+ { "range": [0, 5], "style": "bold" },
721
+ { "range": [6, 11], "animation": "shake" }
722
+ ]
723
+ }
724
+ ```
725
+
726
+ **Note:** Style ranges (bold, italic, etc.) may overlap, but animation ranges
727
+ must not overlap with other animations or styles. Text decorations only render
728
+ for iMessage recipients. For SMS/RCS, text decorations are not applied.
729
+
730
+ Args:
731
+ from_: Sender phone number in E.164 format. Must be a phone number that the
732
+ authenticated partner has permission to send from.
733
+
734
+ message: Message content container. Groups all message-related fields together,
735
+ separating the "what" (message content) from the "where" (routing fields like
736
+ from/to).
737
+
738
+ to: Array of recipient handles (phone numbers in E.164 format or email addresses).
739
+ For individual chats, provide one recipient. For group chats, provide multiple.
740
+
741
+ extra_headers: Send extra headers
742
+
743
+ extra_query: Add additional query parameters to the request
744
+
745
+ extra_body: Add additional JSON properties to the request
746
+
747
+ timeout: Override the client-level default timeout for this request, in seconds
748
+ """
749
+ return await self._post(
750
+ "/v3/chats",
751
+ body=await async_maybe_transform(
752
+ {
753
+ "from_": from_,
754
+ "message": message,
755
+ "to": to,
756
+ },
757
+ chat_create_params.ChatCreateParams,
758
+ ),
759
+ options=make_request_options(
760
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
761
+ ),
762
+ cast_to=ChatCreateResponse,
763
+ )
764
+
765
+ async def retrieve(
766
+ self,
767
+ chat_id: str,
768
+ *,
769
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
770
+ # The extra values given here take precedence over values defined on the client or passed to this method.
771
+ extra_headers: Headers | None = None,
772
+ extra_query: Query | None = None,
773
+ extra_body: Body | None = None,
774
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
775
+ ) -> Chat:
776
+ """
777
+ Retrieve a chat by its unique identifier.
778
+
779
+ Args:
780
+ extra_headers: Send extra headers
781
+
782
+ extra_query: Add additional query parameters to the request
783
+
784
+ extra_body: Add additional JSON properties to the request
785
+
786
+ timeout: Override the client-level default timeout for this request, in seconds
787
+ """
788
+ if not chat_id:
789
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
790
+ return await self._get(
791
+ path_template("/v3/chats/{chat_id}", chat_id=chat_id),
792
+ options=make_request_options(
793
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
794
+ ),
795
+ cast_to=Chat,
796
+ )
797
+
798
+ async def update(
799
+ self,
800
+ chat_id: str,
801
+ *,
802
+ display_name: str | Omit = omit,
803
+ group_chat_icon: str | Omit = omit,
804
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
805
+ # The extra values given here take precedence over values defined on the client or passed to this method.
806
+ extra_headers: Headers | None = None,
807
+ extra_query: Query | None = None,
808
+ extra_body: Body | None = None,
809
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
810
+ ) -> ChatUpdateResponse:
811
+ """
812
+ Update chat properties such as display name and group chat icon.
813
+
814
+ Listen for `chat.group_name_updated`, `chat.group_icon_updated`,
815
+ `chat.group_name_update_failed`, or `chat.group_icon_update_failed` webhook
816
+ events to confirm the outcome.
817
+
818
+ Args:
819
+ display_name: New display name for the chat (group chats only)
820
+
821
+ group_chat_icon: URL of an image to set as the group chat icon (group chats only)
822
+
823
+ extra_headers: Send extra headers
824
+
825
+ extra_query: Add additional query parameters to the request
826
+
827
+ extra_body: Add additional JSON properties to the request
828
+
829
+ timeout: Override the client-level default timeout for this request, in seconds
830
+ """
831
+ if not chat_id:
832
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
833
+ return await self._put(
834
+ path_template("/v3/chats/{chat_id}", chat_id=chat_id),
835
+ body=await async_maybe_transform(
836
+ {
837
+ "display_name": display_name,
838
+ "group_chat_icon": group_chat_icon,
839
+ },
840
+ chat_update_params.ChatUpdateParams,
841
+ ),
842
+ options=make_request_options(
843
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
844
+ ),
845
+ cast_to=ChatUpdateResponse,
846
+ )
847
+
848
+ async def leave_chat(
849
+ self,
850
+ chat_id: str,
851
+ *,
852
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
853
+ # The extra values given here take precedence over values defined on the client or passed to this method.
854
+ extra_headers: Headers | None = None,
855
+ extra_query: Query | None = None,
856
+ extra_body: Body | None = None,
857
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
858
+ ) -> ChatLeaveChatResponse:
859
+ """Removes your phone number from a group chat.
860
+
861
+ Once you leave, you will no longer
862
+ receive messages from the group and all interaction endpoints (send message,
863
+ typing, mark read, etc.) will return 409.
864
+
865
+ A `participant.removed` webhook will fire once the leave has been processed.
866
+
867
+ **Supported**
868
+
869
+ - iMessage group chats with 4 or more active participants (including yourself)
870
+
871
+ **Not supported**
872
+
873
+ - DM (1-on-1) chats — use the chat directly to continue the conversation
874
+
875
+ Args:
876
+ extra_headers: Send extra headers
877
+
878
+ extra_query: Add additional query parameters to the request
879
+
880
+ extra_body: Add additional JSON properties to the request
881
+
882
+ timeout: Override the client-level default timeout for this request, in seconds
883
+ """
884
+ if not chat_id:
885
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
886
+ return await self._post(
887
+ path_template("/v3/chats/{chat_id}/leave", chat_id=chat_id),
888
+ options=make_request_options(
889
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
890
+ ),
891
+ cast_to=ChatLeaveChatResponse,
892
+ )
893
+
894
+ def list_chats(
895
+ self,
896
+ *,
897
+ cursor: str | Omit = omit,
898
+ from_: str | Omit = omit,
899
+ limit: int | Omit = omit,
900
+ to: str | Omit = omit,
901
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
902
+ # The extra values given here take precedence over values defined on the client or passed to this method.
903
+ extra_headers: Headers | None = None,
904
+ extra_query: Query | None = None,
905
+ extra_body: Body | None = None,
906
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
907
+ ) -> AsyncPaginator[Chat, AsyncListChatsPagination[Chat]]:
908
+ """
909
+ Retrieves a paginated list of chats for the authenticated partner.
910
+
911
+ **Filtering:**
912
+
913
+ - If `from` is provided, returns chats for that specific phone number
914
+ - If `from` is omitted, returns chats across all phone numbers owned by the
915
+ partner
916
+ - If `to` is provided, only returns chats where the specified handle is a
917
+ participant
918
+
919
+ **Pagination:**
920
+
921
+ - Use `limit` to control page size (default: 20, max: 100)
922
+ - The response includes `next_cursor` for fetching the next page
923
+ - When `next_cursor` is `null`, there are no more results to fetch
924
+ - Pass the `next_cursor` value as the `cursor` parameter for the next request
925
+
926
+ **Example pagination flow:**
927
+
928
+ 1. First request: `GET /v3/chats?from=%2B12223334444&limit=20`
929
+ 2. Response includes `next_cursor: "20"` (more results exist)
930
+ 3. Next request: `GET /v3/chats?from=%2B12223334444&limit=20&cursor=20`
931
+ 4. Response includes `next_cursor: null` (no more results)
932
+
933
+ Args:
934
+ cursor: Pagination cursor from the previous response's `next_cursor` field. Omit this
935
+ parameter for the first page of results.
936
+
937
+ from_: Phone number to filter chats by. Returns chats made from this phone number. Must
938
+ be in E.164 format (e.g., `+13343284472`). The `+` is automatically URL-encoded
939
+ by HTTP clients. If omitted, returns chats across all phone numbers owned by the
940
+ partner.
941
+
942
+ limit: Maximum number of chats to return per page
943
+
944
+ to: Filter chats by a participant handle. Only returns chats where this handle is a
945
+ participant. Can be an E.164 phone number (e.g., `+13343284472`) or an email
946
+ address (e.g., `user@example.com`). For phone numbers, the `+` is automatically
947
+ URL-encoded by HTTP clients.
948
+
949
+ extra_headers: Send extra headers
950
+
951
+ extra_query: Add additional query parameters to the request
952
+
953
+ extra_body: Add additional JSON properties to the request
954
+
955
+ timeout: Override the client-level default timeout for this request, in seconds
956
+ """
957
+ return self._get_api_list(
958
+ "/v3/chats",
959
+ page=AsyncListChatsPagination[Chat],
960
+ options=make_request_options(
961
+ extra_headers=extra_headers,
962
+ extra_query=extra_query,
963
+ extra_body=extra_body,
964
+ timeout=timeout,
965
+ query=maybe_transform(
966
+ {
967
+ "cursor": cursor,
968
+ "from_": from_,
969
+ "limit": limit,
970
+ "to": to,
971
+ },
972
+ chat_list_chats_params.ChatListChatsParams,
973
+ ),
974
+ ),
975
+ model=Chat,
976
+ )
977
+
978
+ async def mark_as_read(
979
+ self,
980
+ chat_id: str,
981
+ *,
982
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
983
+ # The extra values given here take precedence over values defined on the client or passed to this method.
984
+ extra_headers: Headers | None = None,
985
+ extra_query: Query | None = None,
986
+ extra_body: Body | None = None,
987
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
988
+ ) -> None:
989
+ """
990
+ Mark all messages in a chat as read.
991
+
992
+ Args:
993
+ extra_headers: Send extra headers
994
+
995
+ extra_query: Add additional query parameters to the request
996
+
997
+ extra_body: Add additional JSON properties to the request
998
+
999
+ timeout: Override the client-level default timeout for this request, in seconds
1000
+ """
1001
+ if not chat_id:
1002
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
1003
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
1004
+ return await self._post(
1005
+ path_template("/v3/chats/{chat_id}/read", chat_id=chat_id),
1006
+ options=make_request_options(
1007
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1008
+ ),
1009
+ cast_to=NoneType,
1010
+ )
1011
+
1012
+ async def send_voicememo(
1013
+ self,
1014
+ chat_id: str,
1015
+ *,
1016
+ attachment_id: str | Omit = omit,
1017
+ voice_memo_url: str | Omit = omit,
1018
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1019
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1020
+ extra_headers: Headers | None = None,
1021
+ extra_query: Query | None = None,
1022
+ extra_body: Body | None = None,
1023
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1024
+ ) -> ChatSendVoicememoResponse:
1025
+ """
1026
+ Send an audio file as an **iMessage voice memo bubble** to all participants in a
1027
+ chat. Voice memos appear with iMessage's native inline playback UI, unlike
1028
+ regular audio attachments sent via media parts which appear as downloadable
1029
+ files.
1030
+
1031
+ **Supported audio formats:**
1032
+
1033
+ - MP3 (audio/mpeg)
1034
+ - M4A (audio/x-m4a, audio/mp4)
1035
+ - AAC (audio/aac)
1036
+ - CAF (audio/x-caf) - Core Audio Format
1037
+ - WAV (audio/wav)
1038
+ - AIFF (audio/aiff, audio/x-aiff)
1039
+ - AMR (audio/amr)
1040
+
1041
+ Args:
1042
+ attachment_id: Reference to a voice memo file pre-uploaded via `POST /v3/attachments`. The file
1043
+ is already stored, so sends using this ID skip the download step.
1044
+
1045
+ Either `voice_memo_url` or `attachment_id` must be provided, but not both.
1046
+
1047
+ voice_memo_url: URL of the voice memo audio file. Must be a publicly accessible HTTPS URL.
1048
+
1049
+ Either `voice_memo_url` or `attachment_id` must be provided, but not both.
1050
+
1051
+ extra_headers: Send extra headers
1052
+
1053
+ extra_query: Add additional query parameters to the request
1054
+
1055
+ extra_body: Add additional JSON properties to the request
1056
+
1057
+ timeout: Override the client-level default timeout for this request, in seconds
1058
+ """
1059
+ if not chat_id:
1060
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
1061
+ return await self._post(
1062
+ path_template("/v3/chats/{chat_id}/voicememo", chat_id=chat_id),
1063
+ body=await async_maybe_transform(
1064
+ {
1065
+ "attachment_id": attachment_id,
1066
+ "voice_memo_url": voice_memo_url,
1067
+ },
1068
+ chat_send_voicememo_params.ChatSendVoicememoParams,
1069
+ ),
1070
+ options=make_request_options(
1071
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1072
+ ),
1073
+ cast_to=ChatSendVoicememoResponse,
1074
+ )
1075
+
1076
+ async def share_contact_card(
1077
+ self,
1078
+ chat_id: str,
1079
+ *,
1080
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1081
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1082
+ extra_headers: Headers | None = None,
1083
+ extra_query: Query | None = None,
1084
+ extra_body: Body | None = None,
1085
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1086
+ ) -> None:
1087
+ """
1088
+ Share your contact information (Name and Photo Sharing) with a chat.
1089
+
1090
+ **Note:** A contact card must be configured before sharing. You can set up your
1091
+ contact card via the [Contact Card API](#tag/Contact-Card) or on the
1092
+ [Linq dashboard](https://dashboard.linqapp.com/contact-cards).
1093
+
1094
+ Args:
1095
+ extra_headers: Send extra headers
1096
+
1097
+ extra_query: Add additional query parameters to the request
1098
+
1099
+ extra_body: Add additional JSON properties to the request
1100
+
1101
+ timeout: Override the client-level default timeout for this request, in seconds
1102
+ """
1103
+ if not chat_id:
1104
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
1105
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
1106
+ return await self._post(
1107
+ path_template("/v3/chats/{chat_id}/share_contact_card", chat_id=chat_id),
1108
+ options=make_request_options(
1109
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1110
+ ),
1111
+ cast_to=NoneType,
1112
+ )
1113
+
1114
+
1115
+ class ChatsResourceWithRawResponse:
1116
+ def __init__(self, chats: ChatsResource) -> None:
1117
+ self._chats = chats
1118
+
1119
+ self.create = to_raw_response_wrapper(
1120
+ chats.create,
1121
+ )
1122
+ self.retrieve = to_raw_response_wrapper(
1123
+ chats.retrieve,
1124
+ )
1125
+ self.update = to_raw_response_wrapper(
1126
+ chats.update,
1127
+ )
1128
+ self.leave_chat = to_raw_response_wrapper(
1129
+ chats.leave_chat,
1130
+ )
1131
+ self.list_chats = to_raw_response_wrapper(
1132
+ chats.list_chats,
1133
+ )
1134
+ self.mark_as_read = to_raw_response_wrapper(
1135
+ chats.mark_as_read,
1136
+ )
1137
+ self.send_voicememo = to_raw_response_wrapper(
1138
+ chats.send_voicememo,
1139
+ )
1140
+ self.share_contact_card = to_raw_response_wrapper(
1141
+ chats.share_contact_card,
1142
+ )
1143
+
1144
+ @cached_property
1145
+ def participants(self) -> ParticipantsResourceWithRawResponse:
1146
+ """A Chat is a conversation thread with one or more participants.
1147
+
1148
+ To begin a chat, you must create a Chat with at least one recipient handle.
1149
+ Including multiple handles creates a group chat.
1150
+
1151
+ When creating a chat, the `from` field specifies which of your
1152
+ authorized phone numbers the message originates from. Your authentication token grants
1153
+ access to one or more phone numbers, but the `from` field determines the actual sender.
1154
+
1155
+ **Handle Format:**
1156
+ - Handles can be phone numbers or email addresses
1157
+ - Phone numbers MUST be in E.164 format (starting with +)
1158
+ - Phone format: `+[country code][subscriber number]`
1159
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
1160
+ - Example email: `user@example.com`
1161
+ - No spaces, dashes, or parentheses in phone numbers
1162
+ """
1163
+ return ParticipantsResourceWithRawResponse(self._chats.participants)
1164
+
1165
+ @cached_property
1166
+ def typing(self) -> TypingResourceWithRawResponse:
1167
+ """A Chat is a conversation thread with one or more participants.
1168
+
1169
+ To begin a chat, you must create a Chat with at least one recipient handle.
1170
+ Including multiple handles creates a group chat.
1171
+
1172
+ When creating a chat, the `from` field specifies which of your
1173
+ authorized phone numbers the message originates from. Your authentication token grants
1174
+ access to one or more phone numbers, but the `from` field determines the actual sender.
1175
+
1176
+ **Handle Format:**
1177
+ - Handles can be phone numbers or email addresses
1178
+ - Phone numbers MUST be in E.164 format (starting with +)
1179
+ - Phone format: `+[country code][subscriber number]`
1180
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
1181
+ - Example email: `user@example.com`
1182
+ - No spaces, dashes, or parentheses in phone numbers
1183
+ """
1184
+ return TypingResourceWithRawResponse(self._chats.typing)
1185
+
1186
+ @cached_property
1187
+ def messages(self) -> MessagesResourceWithRawResponse:
1188
+ """Messages are individual communications within a chat thread.
1189
+
1190
+ Messages can include text, media attachments, rich link previews, special effects
1191
+ (like confetti or fireworks), and reactions. All messages are associated with a
1192
+ specific chat and sent from a phone number you own.
1193
+
1194
+ Messages support delivery status tracking, read receipts, and editing capabilities.
1195
+
1196
+ ## Rich Link Previews
1197
+
1198
+ Send a URL as a `link` part to deliver it with a rich preview card showing the
1199
+ page's title, description, and image (when available). A `link` part must be the
1200
+ **only** part in the message — it cannot be combined with text or media parts.
1201
+ To send a URL without a preview card, include it in a `text` part instead.
1202
+
1203
+ **Limitations:**
1204
+ - A `link` part cannot be combined with other parts in the same message.
1205
+ - Maximum URL length: 2,048 characters.
1206
+ """
1207
+ return MessagesResourceWithRawResponse(self._chats.messages)
1208
+
1209
+
1210
+ class AsyncChatsResourceWithRawResponse:
1211
+ def __init__(self, chats: AsyncChatsResource) -> None:
1212
+ self._chats = chats
1213
+
1214
+ self.create = async_to_raw_response_wrapper(
1215
+ chats.create,
1216
+ )
1217
+ self.retrieve = async_to_raw_response_wrapper(
1218
+ chats.retrieve,
1219
+ )
1220
+ self.update = async_to_raw_response_wrapper(
1221
+ chats.update,
1222
+ )
1223
+ self.leave_chat = async_to_raw_response_wrapper(
1224
+ chats.leave_chat,
1225
+ )
1226
+ self.list_chats = async_to_raw_response_wrapper(
1227
+ chats.list_chats,
1228
+ )
1229
+ self.mark_as_read = async_to_raw_response_wrapper(
1230
+ chats.mark_as_read,
1231
+ )
1232
+ self.send_voicememo = async_to_raw_response_wrapper(
1233
+ chats.send_voicememo,
1234
+ )
1235
+ self.share_contact_card = async_to_raw_response_wrapper(
1236
+ chats.share_contact_card,
1237
+ )
1238
+
1239
+ @cached_property
1240
+ def participants(self) -> AsyncParticipantsResourceWithRawResponse:
1241
+ """A Chat is a conversation thread with one or more participants.
1242
+
1243
+ To begin a chat, you must create a Chat with at least one recipient handle.
1244
+ Including multiple handles creates a group chat.
1245
+
1246
+ When creating a chat, the `from` field specifies which of your
1247
+ authorized phone numbers the message originates from. Your authentication token grants
1248
+ access to one or more phone numbers, but the `from` field determines the actual sender.
1249
+
1250
+ **Handle Format:**
1251
+ - Handles can be phone numbers or email addresses
1252
+ - Phone numbers MUST be in E.164 format (starting with +)
1253
+ - Phone format: `+[country code][subscriber number]`
1254
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
1255
+ - Example email: `user@example.com`
1256
+ - No spaces, dashes, or parentheses in phone numbers
1257
+ """
1258
+ return AsyncParticipantsResourceWithRawResponse(self._chats.participants)
1259
+
1260
+ @cached_property
1261
+ def typing(self) -> AsyncTypingResourceWithRawResponse:
1262
+ """A Chat is a conversation thread with one or more participants.
1263
+
1264
+ To begin a chat, you must create a Chat with at least one recipient handle.
1265
+ Including multiple handles creates a group chat.
1266
+
1267
+ When creating a chat, the `from` field specifies which of your
1268
+ authorized phone numbers the message originates from. Your authentication token grants
1269
+ access to one or more phone numbers, but the `from` field determines the actual sender.
1270
+
1271
+ **Handle Format:**
1272
+ - Handles can be phone numbers or email addresses
1273
+ - Phone numbers MUST be in E.164 format (starting with +)
1274
+ - Phone format: `+[country code][subscriber number]`
1275
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
1276
+ - Example email: `user@example.com`
1277
+ - No spaces, dashes, or parentheses in phone numbers
1278
+ """
1279
+ return AsyncTypingResourceWithRawResponse(self._chats.typing)
1280
+
1281
+ @cached_property
1282
+ def messages(self) -> AsyncMessagesResourceWithRawResponse:
1283
+ """Messages are individual communications within a chat thread.
1284
+
1285
+ Messages can include text, media attachments, rich link previews, special effects
1286
+ (like confetti or fireworks), and reactions. All messages are associated with a
1287
+ specific chat and sent from a phone number you own.
1288
+
1289
+ Messages support delivery status tracking, read receipts, and editing capabilities.
1290
+
1291
+ ## Rich Link Previews
1292
+
1293
+ Send a URL as a `link` part to deliver it with a rich preview card showing the
1294
+ page's title, description, and image (when available). A `link` part must be the
1295
+ **only** part in the message — it cannot be combined with text or media parts.
1296
+ To send a URL without a preview card, include it in a `text` part instead.
1297
+
1298
+ **Limitations:**
1299
+ - A `link` part cannot be combined with other parts in the same message.
1300
+ - Maximum URL length: 2,048 characters.
1301
+ """
1302
+ return AsyncMessagesResourceWithRawResponse(self._chats.messages)
1303
+
1304
+
1305
+ class ChatsResourceWithStreamingResponse:
1306
+ def __init__(self, chats: ChatsResource) -> None:
1307
+ self._chats = chats
1308
+
1309
+ self.create = to_streamed_response_wrapper(
1310
+ chats.create,
1311
+ )
1312
+ self.retrieve = to_streamed_response_wrapper(
1313
+ chats.retrieve,
1314
+ )
1315
+ self.update = to_streamed_response_wrapper(
1316
+ chats.update,
1317
+ )
1318
+ self.leave_chat = to_streamed_response_wrapper(
1319
+ chats.leave_chat,
1320
+ )
1321
+ self.list_chats = to_streamed_response_wrapper(
1322
+ chats.list_chats,
1323
+ )
1324
+ self.mark_as_read = to_streamed_response_wrapper(
1325
+ chats.mark_as_read,
1326
+ )
1327
+ self.send_voicememo = to_streamed_response_wrapper(
1328
+ chats.send_voicememo,
1329
+ )
1330
+ self.share_contact_card = to_streamed_response_wrapper(
1331
+ chats.share_contact_card,
1332
+ )
1333
+
1334
+ @cached_property
1335
+ def participants(self) -> ParticipantsResourceWithStreamingResponse:
1336
+ """A Chat is a conversation thread with one or more participants.
1337
+
1338
+ To begin a chat, you must create a Chat with at least one recipient handle.
1339
+ Including multiple handles creates a group chat.
1340
+
1341
+ When creating a chat, the `from` field specifies which of your
1342
+ authorized phone numbers the message originates from. Your authentication token grants
1343
+ access to one or more phone numbers, but the `from` field determines the actual sender.
1344
+
1345
+ **Handle Format:**
1346
+ - Handles can be phone numbers or email addresses
1347
+ - Phone numbers MUST be in E.164 format (starting with +)
1348
+ - Phone format: `+[country code][subscriber number]`
1349
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
1350
+ - Example email: `user@example.com`
1351
+ - No spaces, dashes, or parentheses in phone numbers
1352
+ """
1353
+ return ParticipantsResourceWithStreamingResponse(self._chats.participants)
1354
+
1355
+ @cached_property
1356
+ def typing(self) -> TypingResourceWithStreamingResponse:
1357
+ """A Chat is a conversation thread with one or more participants.
1358
+
1359
+ To begin a chat, you must create a Chat with at least one recipient handle.
1360
+ Including multiple handles creates a group chat.
1361
+
1362
+ When creating a chat, the `from` field specifies which of your
1363
+ authorized phone numbers the message originates from. Your authentication token grants
1364
+ access to one or more phone numbers, but the `from` field determines the actual sender.
1365
+
1366
+ **Handle Format:**
1367
+ - Handles can be phone numbers or email addresses
1368
+ - Phone numbers MUST be in E.164 format (starting with +)
1369
+ - Phone format: `+[country code][subscriber number]`
1370
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
1371
+ - Example email: `user@example.com`
1372
+ - No spaces, dashes, or parentheses in phone numbers
1373
+ """
1374
+ return TypingResourceWithStreamingResponse(self._chats.typing)
1375
+
1376
+ @cached_property
1377
+ def messages(self) -> MessagesResourceWithStreamingResponse:
1378
+ """Messages are individual communications within a chat thread.
1379
+
1380
+ Messages can include text, media attachments, rich link previews, special effects
1381
+ (like confetti or fireworks), and reactions. All messages are associated with a
1382
+ specific chat and sent from a phone number you own.
1383
+
1384
+ Messages support delivery status tracking, read receipts, and editing capabilities.
1385
+
1386
+ ## Rich Link Previews
1387
+
1388
+ Send a URL as a `link` part to deliver it with a rich preview card showing the
1389
+ page's title, description, and image (when available). A `link` part must be the
1390
+ **only** part in the message — it cannot be combined with text or media parts.
1391
+ To send a URL without a preview card, include it in a `text` part instead.
1392
+
1393
+ **Limitations:**
1394
+ - A `link` part cannot be combined with other parts in the same message.
1395
+ - Maximum URL length: 2,048 characters.
1396
+ """
1397
+ return MessagesResourceWithStreamingResponse(self._chats.messages)
1398
+
1399
+
1400
+ class AsyncChatsResourceWithStreamingResponse:
1401
+ def __init__(self, chats: AsyncChatsResource) -> None:
1402
+ self._chats = chats
1403
+
1404
+ self.create = async_to_streamed_response_wrapper(
1405
+ chats.create,
1406
+ )
1407
+ self.retrieve = async_to_streamed_response_wrapper(
1408
+ chats.retrieve,
1409
+ )
1410
+ self.update = async_to_streamed_response_wrapper(
1411
+ chats.update,
1412
+ )
1413
+ self.leave_chat = async_to_streamed_response_wrapper(
1414
+ chats.leave_chat,
1415
+ )
1416
+ self.list_chats = async_to_streamed_response_wrapper(
1417
+ chats.list_chats,
1418
+ )
1419
+ self.mark_as_read = async_to_streamed_response_wrapper(
1420
+ chats.mark_as_read,
1421
+ )
1422
+ self.send_voicememo = async_to_streamed_response_wrapper(
1423
+ chats.send_voicememo,
1424
+ )
1425
+ self.share_contact_card = async_to_streamed_response_wrapper(
1426
+ chats.share_contact_card,
1427
+ )
1428
+
1429
+ @cached_property
1430
+ def participants(self) -> AsyncParticipantsResourceWithStreamingResponse:
1431
+ """A Chat is a conversation thread with one or more participants.
1432
+
1433
+ To begin a chat, you must create a Chat with at least one recipient handle.
1434
+ Including multiple handles creates a group chat.
1435
+
1436
+ When creating a chat, the `from` field specifies which of your
1437
+ authorized phone numbers the message originates from. Your authentication token grants
1438
+ access to one or more phone numbers, but the `from` field determines the actual sender.
1439
+
1440
+ **Handle Format:**
1441
+ - Handles can be phone numbers or email addresses
1442
+ - Phone numbers MUST be in E.164 format (starting with +)
1443
+ - Phone format: `+[country code][subscriber number]`
1444
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
1445
+ - Example email: `user@example.com`
1446
+ - No spaces, dashes, or parentheses in phone numbers
1447
+ """
1448
+ return AsyncParticipantsResourceWithStreamingResponse(self._chats.participants)
1449
+
1450
+ @cached_property
1451
+ def typing(self) -> AsyncTypingResourceWithStreamingResponse:
1452
+ """A Chat is a conversation thread with one or more participants.
1453
+
1454
+ To begin a chat, you must create a Chat with at least one recipient handle.
1455
+ Including multiple handles creates a group chat.
1456
+
1457
+ When creating a chat, the `from` field specifies which of your
1458
+ authorized phone numbers the message originates from. Your authentication token grants
1459
+ access to one or more phone numbers, but the `from` field determines the actual sender.
1460
+
1461
+ **Handle Format:**
1462
+ - Handles can be phone numbers or email addresses
1463
+ - Phone numbers MUST be in E.164 format (starting with +)
1464
+ - Phone format: `+[country code][subscriber number]`
1465
+ - Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
1466
+ - Example email: `user@example.com`
1467
+ - No spaces, dashes, or parentheses in phone numbers
1468
+ """
1469
+ return AsyncTypingResourceWithStreamingResponse(self._chats.typing)
1470
+
1471
+ @cached_property
1472
+ def messages(self) -> AsyncMessagesResourceWithStreamingResponse:
1473
+ """Messages are individual communications within a chat thread.
1474
+
1475
+ Messages can include text, media attachments, rich link previews, special effects
1476
+ (like confetti or fireworks), and reactions. All messages are associated with a
1477
+ specific chat and sent from a phone number you own.
1478
+
1479
+ Messages support delivery status tracking, read receipts, and editing capabilities.
1480
+
1481
+ ## Rich Link Previews
1482
+
1483
+ Send a URL as a `link` part to deliver it with a rich preview card showing the
1484
+ page's title, description, and image (when available). A `link` part must be the
1485
+ **only** part in the message — it cannot be combined with text or media parts.
1486
+ To send a URL without a preview card, include it in a `text` part instead.
1487
+
1488
+ **Limitations:**
1489
+ - A `link` part cannot be combined with other parts in the same message.
1490
+ - Maximum URL length: 2,048 characters.
1491
+ """
1492
+ return AsyncMessagesResourceWithStreamingResponse(self._chats.messages)