archastro.platform.v1.resources.threads
1# Copyright (c) 2026 ArchAstro Inc. All Rights Reserved. 2# This file is auto-generated by @archastro/sdk-generator. Do not edit. 3# Content hash: d3e40763df8d 4 5from __future__ import annotations 6 7from datetime import datetime 8from typing import Any, Literal, Required, TypedDict 9 10from pydantic import BaseModel, Field 11 12from ...runtime.http_client import HttpClient, SyncHttpClient 13from ...types.threads import Thread, ThreadMember, ThreadReadStatus, ThreadSettings 14 15 16class ThreadMemberCreateInput(TypedDict, total=False): 17 "Add a member to a thread" 18 19 agent: str | None 20 'Agent ID of the principal to add. Required when `type` is `"agent"`.' 21 membership_type: str | None 22 'Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.' 23 type: Required[str] 24 'Kind of principal being added. Must be `"user"` or `"agent"`.' 25 user: str | None 26 'User ID of the principal to add. Required when `type` is `"user"`.' 27 28 29class SettingReplaceInput(TypedDict): 30 "Update thread settings" 31 32 settings: dict[str, Any] 33 "Map of settings fields to update. Include only the keys you want to change." 34 35 36class ThreadReplaceInputProfilePicture(TypedDict, total=False): 37 data: str | None 38 "Base64-encoded image payload. Must be a valid base64 string." 39 filename: str | None 40 'Original filename of the image, e.g. `"avatar.png"`. Used for storage metadata.' 41 mime_type: str | None 42 'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.' 43 44 45class ThreadReplaceInput(TypedDict, total=False): 46 "Update a thread" 47 48 description: str | None 49 "Optional longer text describing the thread's purpose. Replaces the existing description when provided." 50 metadata: dict[str, Any] | None 51 "Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata." 52 muted: bool | None 53 "When `true`, suppresses notifications for new messages in this thread for the authenticated user." 54 profile_picture: ThreadReplaceInputProfilePicture | None 55 "New profile picture for the thread. Provide all three inner fields to replace the existing image." 56 title: str | None 57 "Human-readable display name for the thread. Replaces the existing title when provided." 58 59 60class ThreadMarkReadInput(TypedDict, total=False): 61 "Mark a thread as read" 62 63 last_read_message: str | None 64 "Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`." 65 use_latest_message: bool | None 66 "When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`." 67 user: str | None 68 "User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token." 69 70 71class ThreadPictureInputPicture(TypedDict): 72 data: str 73 "Base64-encoded binary content of the image file." 74 filename: str 75 'Original filename of the image, e.g. `"avatar.png"`. Used for storage and display.' 76 mime_type: str 77 'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.' 78 79 80class ThreadPictureInput(TypedDict): 81 "Update a thread's profile picture" 82 83 picture: ThreadPictureInputPicture 84 "Profile picture payload. Must include the base64-encoded image data and its MIME type." 85 86 87class ThreadMemberListResponseDataItemUser(BaseModel): 88 alias: str | None = Field( 89 default=None, description="Short handle or alias for the user. `null` if not set." 90 ) 91 app: str | None = Field( 92 default=None, 93 description="ID of the app this user (and their access token) is scoped to (`dap_...`). `null` if the user is not scoped to an app.", 94 ) 95 app_name: str | None = Field( 96 default=None, 97 description="Display name of the user's app. `null` when the app association was not preloaded by the caller.", 98 ) 99 email: str | None = Field(default=None, description="Email address of the user.") 100 id: str = Field(..., description="User ID (`usr_...`).") 101 is_system_user: bool | None = Field( 102 default=None, 103 description="`true` if this account is an internal system user rather than a human. System users are created automatically by the platform.", 104 ) 105 metadata: dict[str, Any] | None = Field( 106 default=None, 107 description="Arbitrary key-value metadata attached to the user. Defaults to an empty object.", 108 ) 109 name: str | None = Field( 110 default=None, 111 description="Full display name of the user. `null` if the user has not set a name.", 112 ) 113 org: str | None = Field( 114 default=None, 115 description="ID of the organization this user belongs to (`org_...`). `null` if the user is not a member of any organization.", 116 ) 117 org_name: str | None = Field( 118 default=None, 119 description="Display name of the user's organization. `null` when the user is not in an org, or when the org association was not preloaded by the caller.", 120 ) 121 org_role: str | None = Field( 122 default=None, 123 description='Role of the user within their organization. One of `"admin"`, `"member"`, or `"viewer"`. `null` when the user is not a member of any organization.', 124 ) 125 sandbox: str | None = Field( 126 default=None, 127 description="ID of the sandbox environment this user is scoped to (`sbx_...`). `null` for production users.", 128 ) 129 sandbox_name: str | None = Field( 130 default=None, 131 description="Display name of the user's sandbox environment. `null` for production users, or when the sandbox association was not preloaded by the caller.", 132 ) 133 134 135class ThreadMemberListResponseDataItem(BaseModel): 136 membership_type: str | None = Field( 137 default=None, 138 description='Role of the member within the thread. One of `"owner"` (the user who created or was granted ownership) or `"member"` (a regular participant).', 139 ) 140 thread: str | None = Field( 141 default=None, description="ID of the thread this membership belongs to (`thr_...`)." 142 ) 143 user: ThreadMemberListResponseDataItemUser | None = Field( 144 default=None, 145 description="Full user object for the member (`usr_...`). Present when the association is preloaded; `null` otherwise.", 146 ) 147 148 149class ThreadMemberListResponse(BaseModel): 150 """ 151 Successful response 152 """ 153 154 data: list[ThreadMemberListResponseDataItem] = Field( 155 ..., 156 description="Array of thread member objects representing all current members of the thread.", 157 ) 158 159 160class SettingListResponse(BaseModel): 161 """ 162 Successful response 163 """ 164 165 agent_enabled: bool | None = Field( 166 default=None, 167 description="Whether the AI agent is active for this thread. Defaults to `true` when no settings have been explicitly set.", 168 ) 169 170 171class ThreadAgentsResponse(BaseModel): 172 """ 173 Successful response 174 """ 175 176 data: list[dict[str, Any]] = Field( 177 ..., 178 description="Array of agent objects for the thread. Each object includes `id`, `name`, `alias`, `profile_picture`, and `metadata`. Thread owners also receive an `agent_config` object with the agent's policy type and context configuration.", 179 ) 180 181 182class ThreadArtifactsResponseDataItemImageSource(BaseModel): 183 file: str | None = Field( 184 default=None, 185 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 186 ) 187 height: int | None = Field( 188 default=None, description="Height of the image in pixels. `null` if not known." 189 ) 190 media: str | None = Field( 191 default=None, 192 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 193 ) 194 mime_type: str | None = Field( 195 default=None, 196 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 197 ) 198 refresh_url: str | None = Field( 199 default=None, 200 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 201 ) 202 url: str | None = Field( 203 default=None, 204 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 205 ) 206 width: int | None = Field( 207 default=None, description="Width of the image in pixels. `null` if not known." 208 ) 209 210 211class ThreadArtifactsResponseDataItem(BaseModel): 212 agent: str | None = Field( 213 default=None, 214 description="ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", 215 ) 216 content_type: str | None = Field( 217 default=None, 218 description='MIME type of the current version\'s file, e.g. `"text/csv"` or `"image/png"`. `null` if no file is attached.', 219 ) 220 created_at: datetime | None = Field( 221 default=None, description="When the artifact was first created (ISO 8601)." 222 ) 223 current_version: str | None = Field( 224 default=None, 225 description="ID of the current (latest published) artifact version (`artv_...`). `null` if no version has been published.", 226 ) 227 description: str | None = Field( 228 default=None, 229 description="Optional longer description of the artifact's contents or purpose. `null` if not set.", 230 ) 231 file: str | None = Field( 232 default=None, 233 description="Storage file ID for the current version (`fil_...`). `null` if no file is attached.", 234 ) 235 file_name: str | None = Field( 236 default=None, 237 description='Original filename of the current version\'s file, e.g. `"output.csv"`. `null` if no file is attached.', 238 ) 239 file_url: str | None = Field( 240 default=None, 241 description="Short-lived signed URL for downloading the current version's file. `null` if no file is attached.", 242 ) 243 id: str = Field(..., description="Artifact ID (`art_...`).") 244 image_source: ThreadArtifactsResponseDataItemImageSource | None = Field( 245 default=None, 246 description='Image source metadata for rendering the current version\'s file inline. Present only when `content_type` starts with `"image/"`. `null` otherwise.', 247 ) 248 name: str | None = Field( 249 default=None, 250 description='Human-readable name for the artifact, e.g. `"Q2 Report"`. `null` if not set.', 251 ) 252 org: str | None = Field( 253 default=None, description="ID of the organization this artifact belongs to (`org_...`)." 254 ) 255 sandbox: str | None = Field( 256 default=None, 257 description="Identifier of the sandbox environment associated with this artifact. `null` if not sandbox-scoped.", 258 ) 259 team: str | None = Field( 260 default=None, 261 description="ID of the team that owns this artifact (`tea_...`). `null` if not team-scoped.", 262 ) 263 thread: str | None = Field( 264 default=None, 265 description="ID of the thread in which this artifact was created (`thr_...`). `null` if not thread-scoped.", 266 ) 267 updated_at: datetime | None = Field( 268 default=None, description="When the artifact record was last modified (ISO 8601)." 269 ) 270 user: str | None = Field( 271 default=None, 272 description="ID of the user who created this artifact (`usr_...`). `null` if not user-scoped.", 273 ) 274 version: int | None = Field( 275 default=None, 276 description="Current version number of the artifact. Increments each time a new version is published.", 277 ) 278 279 280class ThreadArtifactsResponse(BaseModel): 281 """ 282 Successful response 283 """ 284 285 data: list[ThreadArtifactsResponseDataItem] = Field( 286 ..., description="Array of artifact objects produced during the thread's conversation." 287 ) 288 289 290class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(BaseModel): 291 file: str | None = Field( 292 default=None, 293 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 294 ) 295 height: int | None = Field( 296 default=None, description="Height of the image in pixels. `null` if not known." 297 ) 298 media: str | None = Field( 299 default=None, 300 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 301 ) 302 mime_type: str | None = Field( 303 default=None, 304 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 305 ) 306 refresh_url: str | None = Field( 307 default=None, 308 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 309 ) 310 url: str | None = Field( 311 default=None, 312 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 313 ) 314 width: int | None = Field( 315 default=None, description="Width of the image in pixels. `null` if not known." 316 ) 317 318 319class ThreadMessagesResponseDataMessagesItemActorsItem(BaseModel): 320 alias: str | None = Field( 321 default=None, 322 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 323 ) 324 id: str | None = Field( 325 default=None, 326 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 327 ) 328 name: str | None = Field( 329 default=None, 330 description="Display name of the actor shown in the UI. `null` if no name is set.", 331 ) 332 profile_picture: ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture | None = Field( 333 default=None, 334 description="Profile picture for the actor. `null` if the actor has no profile picture.", 335 ) 336 337 338class ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource(BaseModel): 339 file: str | None = Field( 340 default=None, 341 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 342 ) 343 height: int | None = Field( 344 default=None, description="Height of the image in pixels. `null` if not known." 345 ) 346 media: str | None = Field( 347 default=None, 348 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 349 ) 350 mime_type: str | None = Field( 351 default=None, 352 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 353 ) 354 refresh_url: str | None = Field( 355 default=None, 356 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 357 ) 358 url: str | None = Field( 359 default=None, 360 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 361 ) 362 width: int | None = Field( 363 default=None, description="Width of the image in pixels. `null` if not known." 364 ) 365 366 367class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource(BaseModel): 368 file: str | None = Field( 369 default=None, 370 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 371 ) 372 height: int | None = Field( 373 default=None, description="Height of the image in pixels. `null` if not known." 374 ) 375 media: str | None = Field( 376 default=None, 377 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 378 ) 379 mime_type: str | None = Field( 380 default=None, 381 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 382 ) 383 refresh_url: str | None = Field( 384 default=None, 385 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 386 ) 387 url: str | None = Field( 388 default=None, 389 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 390 ) 391 width: int | None = Field( 392 default=None, description="Width of the image in pixels. `null` if not known." 393 ) 394 395 396class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem(BaseModel): 397 content_type: str | None = Field( 398 default=None, 399 description='MIME type of this variant\'s file (e.g., `"image/jpeg"`, `"video/mp4"`). `null` if the file is not loaded.', 400 ) 401 created_at: datetime | None = Field( 402 default=None, description="When this variant was created (ISO 8601)." 403 ) 404 file: str | None = Field( 405 default=None, 406 description="ID of the underlying storage file that backs this variant (`fil_...`).", 407 ) 408 filename: str | None = Field( 409 default=None, 410 description="Original filename of the uploaded file for this variant. `null` if the file is not loaded.", 411 ) 412 height: int | None = Field( 413 default=None, description="Height of this variant in pixels. `null` if not recorded." 414 ) 415 id: str = Field(..., description="Media variant ID (`mvr_...`).") 416 image_source: ( 417 ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource | None 418 ) = Field( 419 default=None, 420 description="Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types.", 421 ) 422 updated_at: datetime | None = Field( 423 default=None, description="When this variant was last updated (ISO 8601)." 424 ) 425 url: str | None = Field( 426 default=None, 427 description="Signed download URL for this variant, resolved at request time. `null` if the file is unavailable.", 428 ) 429 variant_key: str | None = Field( 430 default=None, 431 description='Identifier for this variant\'s processing tier. Common values include `"original"` (the unmodified upload) and `"thumbnail"` (a resized preview).', 432 ) 433 width: int | None = Field( 434 default=None, description="Width of this variant in pixels. `null` if not recorded." 435 ) 436 437 438class ThreadMessagesResponseDataMessagesItemAttachmentsItem(BaseModel): 439 content_type: str | None = Field( 440 default=None, 441 description='MIME type of the attached file, e.g. `"image/png"` or `"application/pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.', 442 ) 443 description: str | None = Field( 444 default=None, 445 description="Short description. The page meta-description for `scraped_link`, the artifact description for `artifact`, and the task description for `task` types. `null` on other types.", 446 ) 447 filename: str | None = Field( 448 default=None, 449 description='Original filename of the attached file, e.g. `"report.pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.', 450 ) 451 height: int | None = Field( 452 default=None, 453 description="Height in pixels of the media item. Present on `media` type only. `null` otherwise.", 454 ) 455 id: str = Field(..., description="Unique identifier for this attachment within the message.") 456 image_height: int | None = Field( 457 default=None, 458 description="Height in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.", 459 ) 460 image_source: ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource | None = Field( 461 default=None, 462 description="Image source metadata for inline rendering. Present on `file`, `scraped_link`, `artifact`, and `media` types when the content is an image. `null` otherwise.", 463 ) 464 image_url: str | None = Field( 465 default=None, 466 description="URL of the preview image extracted from the scraped page. Present on `scraped_link` type only. `null` otherwise.", 467 ) 468 image_width: int | None = Field( 469 default=None, 470 description="Width in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.", 471 ) 472 media_type: str | None = Field( 473 default=None, 474 description='The media category, e.g. `"video"` or `"audio"`. Present on `media` type only. `null` otherwise.', 475 ) 476 name: str | None = Field( 477 default=None, 478 description="Display name of the media item. Present on `media` type only. `null` otherwise.", 479 ) 480 object: dict[str, Any] | None = Field( 481 default=None, 482 description="The full embedded object payload. For `task` type, contains the task record. For `action` type, contains the action definition. `null` on other types.", 483 ) 484 title: str | None = Field( 485 default=None, 486 description="Display title. The page title for `scraped_link`, the artifact name for `artifact`, and the task title for `task` types. `null` on other types.", 487 ) 488 type: str = Field( 489 ..., 490 description='The attachment type. One of `"file"`, `"scraped_link"`, `"artifact"`, `"task"`, `"media"`, or `"action"`. Determines which additional fields are present.', 491 ) 492 url: str | None = Field( 493 default=None, 494 description="URL to access the resource. A signed download URL for `file` and `artifact` types; the original URL for `scraped_link`; a media playback URL for `media`. `null` on `task` and `action` types.", 495 ) 496 variants: list[ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem] | None = ( 497 Field( 498 default=None, 499 description="Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only. `null` otherwise.", 500 ) 501 ) 502 version: int | None = Field( 503 default=None, 504 description="Version number of the attached artifact at the time of attachment. Present on `artifact` type only. `null` otherwise.", 505 ) 506 width: int | None = Field( 507 default=None, 508 description="Width in pixels of the media item. Present on `media` type only. `null` otherwise.", 509 ) 510 511 512class ThreadMessagesResponseDataMessagesItemReactionsItem(BaseModel): 513 payload: dict[str, Any] | None = Field( 514 default=None, 515 description='Type-specific reaction data. For `"emoji_reaction"` reactions, contains an `emoji` key with the Unicode emoji string (e.g., `" "`).', 516 ) 517 type: str = Field( 518 ..., 519 description='Reaction type identifier. Currently always `"emoji_reaction"` for emoji-based reactions.', 520 ) 521 user: str | None = Field( 522 default=None, description="Public ID of the user who added the reaction (`usr_...`)." 523 ) 524 525 526class ThreadMessagesResponseDataMessagesItem(BaseModel): 527 actors: list[ThreadMessagesResponseDataMessagesItemActorsItem] | None = Field( 528 default=None, 529 description="Resolved actor descriptors for the message sender, combining identity and display metadata. Always contains exactly one entry.", 530 ) 531 agent: str | None = Field( 532 default=None, 533 description="ID of the agent user that sent this message (`agi_...`). `null` for messages sent by human users.", 534 ) 535 agent_mode: Literal["cli", "embedded"] | None = Field( 536 default=None, 537 description="Local agent execution mode for this message. One of `cli`, `embedded`, or `null` when the message was not created by a local agent execution path.", 538 ) 539 attachments: list[ThreadMessagesResponseDataMessagesItemAttachmentsItem] | None = Field( 540 default=None, 541 description="Files, links, tasks, media, artifacts, and actions attached to this message. Empty array if there are no attachments.", 542 ) 543 branched_thread: str | None = Field( 544 default=None, 545 description="ID of the thread that was branched from this message (`thr_...`). `null` if this message has not spawned a branch thread.", 546 ) 547 content: str | None = Field( 548 default=None, 549 description="Text content of the message. `null` for messages that contain only attachments.", 550 ) 551 created_at: datetime | None = Field( 552 default=None, description="When the message was posted (ISO 8601)." 553 ) 554 has_replies: bool | None = Field( 555 default=None, 556 description="Whether this message has at least one reply. Only present when explicitly requested or computed by the server.", 557 ) 558 id: str = Field(..., description="Message ID (`msg_...`).") 559 idempotency_key: str | None = Field( 560 default=None, 561 description="Client-supplied idempotency key used to deduplicate message sends. `null` if the sender did not provide one.", 562 ) 563 legacy_agent: str | None = Field( 564 default=None, 565 description="Identifier of the legacy chat agent that sent this message, if applicable. `null` for messages sent by users or modern agent users.", 566 ) 567 metadata: dict[str, Any] | None = Field( 568 default=None, 569 description="Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.", 570 ) 571 org: str | None = Field( 572 default=None, description="ID of the organization that owns this message (`org_...`)." 573 ) 574 reactions: list[ThreadMessagesResponseDataMessagesItemReactionsItem] | None = Field( 575 default=None, 576 description="Emoji and other reactions added to this message by users. Empty array if no reactions have been added or the association is not preloaded.", 577 ) 578 rendering_mode: str | None = Field( 579 default=None, 580 description='Display hint for how the message should be rendered. One of `"reply"`, `"direct"`, or `"inline"`. `null` for user-authored messages, which are always rendered as standard replies.', 581 ) 582 replies: list[dict[str, Any]] | None = Field( 583 default=None, 584 description="Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.", 585 ) 586 replies_after_cursor: str | None = Field( 587 default=None, 588 description="Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.", 589 ) 590 replies_before_cursor: str | None = Field( 591 default=None, 592 description="Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.", 593 ) 594 reply_count: int | None = Field( 595 default=None, 596 description="Total number of direct replies to this message. Only present when explicitly requested or computed by the server.", 597 ) 598 reply_to: dict[str, Any] | None = Field( 599 default=None, 600 description="The parent message this message is a reply to, expanded as a full message object when loaded. `null` if this is a top-level message or the association is not preloaded.", 601 ) 602 sandbox: str | None = Field( 603 default=None, 604 description="ID of the developer sandbox this message belongs to (`dsb_...`). `null` for non-sandbox messages.", 605 ) 606 team: str | None = Field( 607 default=None, 608 description="ID of the team this message is scoped to (`tem_...`). `null` if the message is not team-scoped.", 609 ) 610 thread: str | None = Field( 611 default=None, 612 description="ID of the thread this message belongs to (`thr_...`). `null` for messages not yet associated with a thread.", 613 ) 614 user: str | None = Field( 615 default=None, 616 description="The human user who sent this message. Returns a public ID string (`usr_...`) when the association is not preloaded, or an expanded user object when it is. `null` for messages sent by agents.", 617 ) 618 619 620class ThreadMessagesResponseData(BaseModel): 621 after_cursor: str | None = Field( 622 default=None, 623 description="Opaque cursor to pass as `after` to retrieve the page of messages newer than this result set. `null` when there are no later messages.", 624 ) 625 anchor: str | None = Field( 626 default=None, 627 description="Message ID used as the anchor for a windowed query. `null` for ordinary cursor pagination.", 628 ) 629 before_cursor: str | None = Field( 630 default=None, 631 description="Opaque cursor to pass as `before` to retrieve the page of messages older than this result set. `null` when there are no earlier messages.", 632 ) 633 messages: list[ThreadMessagesResponseDataMessagesItem] = Field( 634 ..., description="Ordered array of message objects for this page of results." 635 ) 636 637 638class ThreadMessagesResponse(BaseModel): 639 """ 640 Successful response 641 """ 642 643 data: ThreadMessagesResponseData = Field( 644 ..., 645 description="Pagination envelope containing the messages for this page along with cursors for adjacent pages.", 646 ) 647 648 649class ThreadSearchResponse(BaseModel): 650 """ 651 Successful response 652 """ 653 654 data: list[dict[str, Any]] = Field( 655 ..., 656 description="Array of matching context items. Each item is a tagged object whose shape depends on the source type.", 657 ) 658 659 660class AsyncThreadMemberResource: 661 def __init__(self, http: HttpClient): 662 self._http = http 663 664 async def remove(self, thread: str) -> None: 665 """ 666 Remove a member from a thread 667 Removes a user or agent membership from the specified thread. The authenticated 668 user must have access to the thread. A successful removal returns HTTP 204 with 669 no response body. 670 Supply either `user` or `agent` depending on the value of `type`. Returns 404 671 if the thread or the membership record does not exist. 672 673 Args: 674 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 675 676 Returns: 677 Empty response body. HTTP 204 on success. 678 """ 679 await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE") 680 681 async def list(self, thread: str) -> ThreadMemberListResponse: 682 """ 683 List members of a thread 684 Returns all current members of the specified thread, including both user and 685 agent members. The authenticated user must have visibility into the thread; 686 requests from users without access return 403. 687 Results are returned as a flat array in the `data` field. The list is not 688 paginated all members are returned in a single response. 689 690 Args: 691 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 692 693 Returns: 694 Successful response 695 """ 696 return await self._http.request( 697 f"/api/v1/threads/{thread}/members", 698 response_type=ThreadMemberListResponse, 699 ) 700 701 async def create(self, thread: str, input: ThreadMemberCreateInput) -> ThreadMember: 702 """ 703 Add a member to a thread 704 Adds a user or agent as a member of the specified thread. The authenticated 705 user must have access to the thread. On success the new membership record is 706 returned with HTTP 201. 707 Supply either `user` or `agent` depending on the value of `type`. Attempting 708 to add a principal that is already a member of the thread returns a 422 error. 709 710 Args: 711 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 712 input: Request body. 713 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 714 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 715 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 716 input.user: User ID of the principal to add. Required when `type` is `"user"`. 717 718 Returns: 719 The newly created thread membership record. 720 """ 721 return await self._http.request( 722 f"/api/v1/threads/{thread}/members", 723 method="POST", 724 body=input, 725 response_type=ThreadMember, 726 ) 727 728 729class AsyncSettingResource: 730 def __init__(self, http: HttpClient): 731 self._http = http 732 733 async def list(self, thread: str) -> SettingListResponse: 734 """ 735 Retrieve thread settings 736 Returns the current settings for the specified thread. Settings control 737 per-thread behavior such as whether the AI agent is enabled. 738 The authenticated user must own the thread or be a member of its workspace. 739 If settings have never been explicitly configured, defaults are returned 740 (for example, `agent_enabled` defaults to `true`). 741 742 Args: 743 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 744 745 Returns: 746 Successful response 747 """ 748 return await self._http.request( 749 f"/api/v1/threads/{thread}/settings", 750 response_type=SettingListResponse, 751 ) 752 753 async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 754 """ 755 Update thread settings 756 Updates the settings for the specified thread. Only fields included in 757 the `settings` map are modified; omitted fields retain their current values. 758 The authenticated user must own the thread or be a member of its workspace. 759 Returns the full settings object reflecting the state after the update. 760 Validation errors are returned as `422 Unprocessable Entity`. 761 762 Args: 763 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 764 input: Request body. 765 input.settings: Map of settings fields to update. Include only the keys you want to change. 766 767 Returns: 768 The thread settings object after the update has been applied. 769 """ 770 return await self._http.request( 771 f"/api/v1/threads/{thread}/settings", 772 method="PUT", 773 body=input, 774 response_type=ThreadSettings, 775 ) 776 777 778class AsyncThreadResource: 779 def __init__(self, http: HttpClient): 780 self._http = http 781 self.members = AsyncThreadMemberResource(http) 782 self.settings = AsyncSettingResource(http) 783 784 async def delete(self, thread: str) -> None: 785 """ 786 Delete a thread 787 Permanently deletes a thread and all of its messages and artifacts. This action 788 cannot be undone. 789 The authenticated user must own the thread or be an owner of the team the thread 790 belongs to. Attempting to delete a thread owned by another user or team returns 403. 791 792 Args: 793 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 794 795 Returns: 796 Empty response on successful deletion. 797 """ 798 await self._http.request(f"/api/v1/threads/{thread}", method="DELETE") 799 800 async def get(self, thread: str) -> Thread: 801 """ 802 Retrieve a thread 803 Returns the full thread record for the given thread ID. The authenticated user 804 must own the thread or be a member of the workspace it belongs to. 805 Use this endpoint to fetch the current state of a single thread, including its 806 title, description, and metadata. To list many threads, use the list endpoint 807 with cursor-based pagination. 808 809 Args: 810 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 811 812 Returns: 813 The requested thread object. 814 """ 815 return await self._http.request(f"/api/v1/threads/{thread}", response_type=Thread) 816 817 async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 818 """ 819 Update a thread 820 Updates one or more mutable properties of the specified thread and returns 821 the full thread object with the applied changes. Only the fields you provide 822 are modified; omitted fields retain their current values. 823 If `profile_picture` is supplied, the image is uploaded before the other 824 fields are saved. Supplying invalid base64 picture data returns 422 and no 825 other fields are updated. 826 The authenticated user must own the thread or be a team owner of the workspace 827 the thread belongs to. 828 829 Args: 830 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 831 input: Request body. 832 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 833 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 834 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 835 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 836 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 837 838 Returns: 839 The thread object after the update has been applied. 840 """ 841 return await self._http.request( 842 f"/api/v1/threads/{thread}", 843 method="PUT", 844 body=input, 845 response_type=Thread, 846 ) 847 848 async def agents(self, thread: str) -> ThreadAgentsResponse: 849 """ 850 List agents in a thread 851 Returns the agents participating in the specified thread. Only personal user 852 threads (threads owned by a single user, not a team) expose agents through 853 this endpoint; requests for team threads return 404. 854 The authenticated user must have visibility into the thread. Each agent entry 855 includes display information such as name and profile picture. Thread-level 856 overrides (e.g. a custom name or profile picture set for this thread) take 857 precedence over the agent's default values. When the caller is the thread 858 owner, each entry also includes an `agent_config` object describing the 859 agent's message policy and context configuration. 860 861 Args: 862 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 863 864 Returns: 865 Successful response 866 """ 867 return await self._http.request( 868 f"/api/v1/threads/{thread}/agents", 869 response_type=ThreadAgentsResponse, 870 ) 871 872 async def artifacts(self, thread: str) -> ThreadArtifactsResponse: 873 """ 874 List artifacts for a thread 875 Returns all artifacts produced during a thread's AI conversation. Artifacts are 876 structured outputs such as code files, documents, or generated assets created 877 by the AI agent in response to messages in the thread. 878 The authenticated user must have access to the specified thread. Results are 879 returned in a single page; there is no cursor-based pagination for this endpoint. 880 881 Args: 882 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 883 884 Returns: 885 Successful response 886 """ 887 return await self._http.request( 888 f"/api/v1/threads/{thread}/artifacts", 889 response_type=ThreadArtifactsResponse, 890 ) 891 892 async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 893 """ 894 Mark a thread as read 895 Records that a user has read up to a specific message in the thread. Unread 896 indicators and badge counts are cleared up to the specified message. 897 You must supply exactly one of `last_read_message` or `use_latest_message`. 898 Omitting both returns 400. If `use_latest_message` is `true` and the thread 899 has no messages, the request succeeds silently with no state change. 900 For server-to-server (S2S) requests where no user identity is present in the 901 token, the `user` param is required to identify whose read state to update. 902 903 Args: 904 thread: Thread ID (`thr_...`). The thread to mark as read. 905 input: Request body. 906 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 907 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 908 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 909 910 Returns: 911 Empty response on success. 912 """ 913 await self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input) 914 915 async def messages( 916 self, 917 thread: str, 918 *, 919 before_cursor: str | None = None, 920 after_cursor: str | None = None, 921 limit: int | None = None, 922 anchor: str | None = None, 923 direction: Literal["before", "after", "around"] | None = None, 924 before_limit: int | None = None, 925 after_limit: int | None = None, 926 include_anchor: bool | None = None, 927 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 928 anchor_agent: str | None = None, 929 include_reply_counts: bool | None = None, 930 ) -> ThreadMessagesResponse: 931 """ 932 List messages in a thread 933 Returns a cursor-paginated list of messages belonging to the specified thread, 934 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 935 to page through or bound the result set; omit both to receive the most recent page. 936 Supply `anchor` and `direction` to fetch a window before, after, or around a 937 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 938 resolve the anchor from the latest embedded-agent message, and add 939 `anchor_agent` to scope that resolution to a single sender agent. 940 The authenticated user must have access to the thread's owner (workspace or user). 941 A 403 is returned if the thread exists but is not accessible to the caller; a 404 942 is returned if the thread does not exist or is not visible to the authenticated user. 943 Pass `include_reply_counts: true` to annotate each message with the number of 944 threaded replies it has received. This adds a small amount of latency and should 945 be omitted when reply counts are not needed. 946 947 Args: 948 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 949 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 950 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 951 limit: Maximum number of messages to return per page. Defaults to 20. 952 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 953 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 954 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20. 955 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20. 956 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 957 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 958 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 959 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 960 961 Returns: 962 Successful response 963 """ 964 query: dict[str, object] = {} 965 if before_cursor is not None: 966 query["before_cursor"] = before_cursor 967 if after_cursor is not None: 968 query["after_cursor"] = after_cursor 969 if limit is not None: 970 query["limit"] = limit 971 if anchor is not None: 972 query["anchor"] = anchor 973 if direction is not None: 974 query["direction"] = direction 975 if before_limit is not None: 976 query["before_limit"] = before_limit 977 if after_limit is not None: 978 query["after_limit"] = after_limit 979 if include_anchor is not None: 980 query["include_anchor"] = include_anchor 981 if anchor_agent_mode is not None: 982 query["anchor_agent_mode"] = anchor_agent_mode 983 if anchor_agent is not None: 984 query["anchor_agent"] = anchor_agent 985 if include_reply_counts is not None: 986 query["include_reply_counts"] = include_reply_counts 987 return await self._http.request( 988 f"/api/v1/threads/{thread}/messages", 989 query=query, 990 response_type=ThreadMessagesResponse, 991 ) 992 993 async def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 994 """ 995 Update a thread's profile picture 996 Uploads a new profile picture for the specified thread and returns the updated 997 thread object. The image must be supplied as a base64-encoded string with its 998 MIME type. 999 The authenticated user must own the thread or be a team owner of the workspace 1000 the thread belongs to. Supplying invalid base64 data returns 422. 1001 1002 Args: 1003 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1004 input: Request body. 1005 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1006 1007 Returns: 1008 The thread object after the profile picture has been updated. 1009 """ 1010 return await self._http.request( 1011 f"/api/v1/threads/{thread}/picture", 1012 method="PUT", 1013 body=input, 1014 response_type=Thread, 1015 ) 1016 1017 async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1018 """ 1019 Retrieve a thread's read status 1020 Returns the read status of a thread for the specified user, including the ID 1021 of the last message they have read and the number of unread messages remaining. 1022 For user-authenticated requests, the status is always returned for the 1023 authenticated user and the `user` parameter is ignored. For server-to-server 1024 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1025 Returns 404 if the thread does not exist or the caller does not have access 1026 to it. 1027 1028 Args: 1029 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1030 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1031 1032 Returns: 1033 The read status record for the requested thread and user. 1034 """ 1035 query: dict[str, object] = {} 1036 if user is not None: 1037 query["user"] = user 1038 return await self._http.request( 1039 f"/api/v1/threads/{thread}/read_status", 1040 query=query, 1041 response_type=ThreadReadStatus, 1042 ) 1043 1044 async def search(self, thread: str, q: str, *, type: str | None = None) -> ThreadSearchResponse: 1045 """ 1046 Search context items within a thread 1047 Performs a full-text search over context items (messages, files, and other 1048 indexed sources) attached to the specified thread. Returns tagged objects 1049 whose content matches the query string. 1050 Use the `type` param to restrict results to a particular context source. All 1051 accessible context source types are searched when `type` is omitted. The 1052 authenticated user must have access to the thread. 1053 1054 Args: 1055 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1056 q: Full-text search query. Results are ranked by relevance to this string. 1057 type: Context source type to restrict the search to, e.g. `"thread/messages"`. Omit to search across all context sources for the thread. 1058 1059 Returns: 1060 Successful response 1061 """ 1062 query: dict[str, object] = {} 1063 query["q"] = q 1064 if type is not None: 1065 query["type"] = type 1066 return await self._http.request( 1067 f"/api/v1/threads/{thread}/search", 1068 query=query, 1069 response_type=ThreadSearchResponse, 1070 ) 1071 1072 1073class ThreadMemberResource: 1074 def __init__(self, http: SyncHttpClient): 1075 self._http = http 1076 1077 def remove(self, thread: str) -> None: 1078 """ 1079 Remove a member from a thread 1080 Removes a user or agent membership from the specified thread. The authenticated 1081 user must have access to the thread. A successful removal returns HTTP 204 with 1082 no response body. 1083 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1084 if the thread or the membership record does not exist. 1085 1086 Args: 1087 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1088 1089 Returns: 1090 Empty response body. HTTP 204 on success. 1091 """ 1092 self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE") 1093 1094 def list(self, thread: str) -> ThreadMemberListResponse: 1095 """ 1096 List members of a thread 1097 Returns all current members of the specified thread, including both user and 1098 agent members. The authenticated user must have visibility into the thread; 1099 requests from users without access return 403. 1100 Results are returned as a flat array in the `data` field. The list is not 1101 paginated all members are returned in a single response. 1102 1103 Args: 1104 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1105 1106 Returns: 1107 Successful response 1108 """ 1109 return self._http.request( 1110 f"/api/v1/threads/{thread}/members", 1111 response_type=ThreadMemberListResponse, 1112 ) 1113 1114 def create(self, thread: str, input: ThreadMemberCreateInput) -> ThreadMember: 1115 """ 1116 Add a member to a thread 1117 Adds a user or agent as a member of the specified thread. The authenticated 1118 user must have access to the thread. On success the new membership record is 1119 returned with HTTP 201. 1120 Supply either `user` or `agent` depending on the value of `type`. Attempting 1121 to add a principal that is already a member of the thread returns a 422 error. 1122 1123 Args: 1124 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1125 input: Request body. 1126 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1127 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1128 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1129 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1130 1131 Returns: 1132 The newly created thread membership record. 1133 """ 1134 return self._http.request( 1135 f"/api/v1/threads/{thread}/members", 1136 method="POST", 1137 body=input, 1138 response_type=ThreadMember, 1139 ) 1140 1141 1142class SettingResource: 1143 def __init__(self, http: SyncHttpClient): 1144 self._http = http 1145 1146 def list(self, thread: str) -> SettingListResponse: 1147 """ 1148 Retrieve thread settings 1149 Returns the current settings for the specified thread. Settings control 1150 per-thread behavior such as whether the AI agent is enabled. 1151 The authenticated user must own the thread or be a member of its workspace. 1152 If settings have never been explicitly configured, defaults are returned 1153 (for example, `agent_enabled` defaults to `true`). 1154 1155 Args: 1156 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1157 1158 Returns: 1159 Successful response 1160 """ 1161 return self._http.request( 1162 f"/api/v1/threads/{thread}/settings", 1163 response_type=SettingListResponse, 1164 ) 1165 1166 def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1167 """ 1168 Update thread settings 1169 Updates the settings for the specified thread. Only fields included in 1170 the `settings` map are modified; omitted fields retain their current values. 1171 The authenticated user must own the thread or be a member of its workspace. 1172 Returns the full settings object reflecting the state after the update. 1173 Validation errors are returned as `422 Unprocessable Entity`. 1174 1175 Args: 1176 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1177 input: Request body. 1178 input.settings: Map of settings fields to update. Include only the keys you want to change. 1179 1180 Returns: 1181 The thread settings object after the update has been applied. 1182 """ 1183 return self._http.request( 1184 f"/api/v1/threads/{thread}/settings", 1185 method="PUT", 1186 body=input, 1187 response_type=ThreadSettings, 1188 ) 1189 1190 1191class ThreadResource: 1192 def __init__(self, http: SyncHttpClient): 1193 self._http = http 1194 self.members = ThreadMemberResource(http) 1195 self.settings = SettingResource(http) 1196 1197 def delete(self, thread: str) -> None: 1198 """ 1199 Delete a thread 1200 Permanently deletes a thread and all of its messages and artifacts. This action 1201 cannot be undone. 1202 The authenticated user must own the thread or be an owner of the team the thread 1203 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1204 1205 Args: 1206 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1207 1208 Returns: 1209 Empty response on successful deletion. 1210 """ 1211 self._http.request(f"/api/v1/threads/{thread}", method="DELETE") 1212 1213 def get(self, thread: str) -> Thread: 1214 """ 1215 Retrieve a thread 1216 Returns the full thread record for the given thread ID. The authenticated user 1217 must own the thread or be a member of the workspace it belongs to. 1218 Use this endpoint to fetch the current state of a single thread, including its 1219 title, description, and metadata. To list many threads, use the list endpoint 1220 with cursor-based pagination. 1221 1222 Args: 1223 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1224 1225 Returns: 1226 The requested thread object. 1227 """ 1228 return self._http.request(f"/api/v1/threads/{thread}", response_type=Thread) 1229 1230 def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1231 """ 1232 Update a thread 1233 Updates one or more mutable properties of the specified thread and returns 1234 the full thread object with the applied changes. Only the fields you provide 1235 are modified; omitted fields retain their current values. 1236 If `profile_picture` is supplied, the image is uploaded before the other 1237 fields are saved. Supplying invalid base64 picture data returns 422 and no 1238 other fields are updated. 1239 The authenticated user must own the thread or be a team owner of the workspace 1240 the thread belongs to. 1241 1242 Args: 1243 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1244 input: Request body. 1245 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1246 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1247 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1248 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1249 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1250 1251 Returns: 1252 The thread object after the update has been applied. 1253 """ 1254 return self._http.request( 1255 f"/api/v1/threads/{thread}", 1256 method="PUT", 1257 body=input, 1258 response_type=Thread, 1259 ) 1260 1261 def agents(self, thread: str) -> ThreadAgentsResponse: 1262 """ 1263 List agents in a thread 1264 Returns the agents participating in the specified thread. Only personal user 1265 threads (threads owned by a single user, not a team) expose agents through 1266 this endpoint; requests for team threads return 404. 1267 The authenticated user must have visibility into the thread. Each agent entry 1268 includes display information such as name and profile picture. Thread-level 1269 overrides (e.g. a custom name or profile picture set for this thread) take 1270 precedence over the agent's default values. When the caller is the thread 1271 owner, each entry also includes an `agent_config` object describing the 1272 agent's message policy and context configuration. 1273 1274 Args: 1275 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1276 1277 Returns: 1278 Successful response 1279 """ 1280 return self._http.request( 1281 f"/api/v1/threads/{thread}/agents", 1282 response_type=ThreadAgentsResponse, 1283 ) 1284 1285 def artifacts(self, thread: str) -> ThreadArtifactsResponse: 1286 """ 1287 List artifacts for a thread 1288 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1289 structured outputs such as code files, documents, or generated assets created 1290 by the AI agent in response to messages in the thread. 1291 The authenticated user must have access to the specified thread. Results are 1292 returned in a single page; there is no cursor-based pagination for this endpoint. 1293 1294 Args: 1295 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1296 1297 Returns: 1298 Successful response 1299 """ 1300 return self._http.request( 1301 f"/api/v1/threads/{thread}/artifacts", 1302 response_type=ThreadArtifactsResponse, 1303 ) 1304 1305 def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 1306 """ 1307 Mark a thread as read 1308 Records that a user has read up to a specific message in the thread. Unread 1309 indicators and badge counts are cleared up to the specified message. 1310 You must supply exactly one of `last_read_message` or `use_latest_message`. 1311 Omitting both returns 400. If `use_latest_message` is `true` and the thread 1312 has no messages, the request succeeds silently with no state change. 1313 For server-to-server (S2S) requests where no user identity is present in the 1314 token, the `user` param is required to identify whose read state to update. 1315 1316 Args: 1317 thread: Thread ID (`thr_...`). The thread to mark as read. 1318 input: Request body. 1319 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 1320 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 1321 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 1322 1323 Returns: 1324 Empty response on success. 1325 """ 1326 self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input) 1327 1328 def messages( 1329 self, 1330 thread: str, 1331 *, 1332 before_cursor: str | None = None, 1333 after_cursor: str | None = None, 1334 limit: int | None = None, 1335 anchor: str | None = None, 1336 direction: Literal["before", "after", "around"] | None = None, 1337 before_limit: int | None = None, 1338 after_limit: int | None = None, 1339 include_anchor: bool | None = None, 1340 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 1341 anchor_agent: str | None = None, 1342 include_reply_counts: bool | None = None, 1343 ) -> ThreadMessagesResponse: 1344 """ 1345 List messages in a thread 1346 Returns a cursor-paginated list of messages belonging to the specified thread, 1347 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 1348 to page through or bound the result set; omit both to receive the most recent page. 1349 Supply `anchor` and `direction` to fetch a window before, after, or around a 1350 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 1351 resolve the anchor from the latest embedded-agent message, and add 1352 `anchor_agent` to scope that resolution to a single sender agent. 1353 The authenticated user must have access to the thread's owner (workspace or user). 1354 A 403 is returned if the thread exists but is not accessible to the caller; a 404 1355 is returned if the thread does not exist or is not visible to the authenticated user. 1356 Pass `include_reply_counts: true` to annotate each message with the number of 1357 threaded replies it has received. This adds a small amount of latency and should 1358 be omitted when reply counts are not needed. 1359 1360 Args: 1361 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1362 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 1363 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 1364 limit: Maximum number of messages to return per page. Defaults to 20. 1365 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 1366 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 1367 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20. 1368 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20. 1369 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 1370 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 1371 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 1372 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 1373 1374 Returns: 1375 Successful response 1376 """ 1377 query: dict[str, object] = {} 1378 if before_cursor is not None: 1379 query["before_cursor"] = before_cursor 1380 if after_cursor is not None: 1381 query["after_cursor"] = after_cursor 1382 if limit is not None: 1383 query["limit"] = limit 1384 if anchor is not None: 1385 query["anchor"] = anchor 1386 if direction is not None: 1387 query["direction"] = direction 1388 if before_limit is not None: 1389 query["before_limit"] = before_limit 1390 if after_limit is not None: 1391 query["after_limit"] = after_limit 1392 if include_anchor is not None: 1393 query["include_anchor"] = include_anchor 1394 if anchor_agent_mode is not None: 1395 query["anchor_agent_mode"] = anchor_agent_mode 1396 if anchor_agent is not None: 1397 query["anchor_agent"] = anchor_agent 1398 if include_reply_counts is not None: 1399 query["include_reply_counts"] = include_reply_counts 1400 return self._http.request( 1401 f"/api/v1/threads/{thread}/messages", 1402 query=query, 1403 response_type=ThreadMessagesResponse, 1404 ) 1405 1406 def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 1407 """ 1408 Update a thread's profile picture 1409 Uploads a new profile picture for the specified thread and returns the updated 1410 thread object. The image must be supplied as a base64-encoded string with its 1411 MIME type. 1412 The authenticated user must own the thread or be a team owner of the workspace 1413 the thread belongs to. Supplying invalid base64 data returns 422. 1414 1415 Args: 1416 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1417 input: Request body. 1418 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1419 1420 Returns: 1421 The thread object after the profile picture has been updated. 1422 """ 1423 return self._http.request( 1424 f"/api/v1/threads/{thread}/picture", 1425 method="PUT", 1426 body=input, 1427 response_type=Thread, 1428 ) 1429 1430 def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1431 """ 1432 Retrieve a thread's read status 1433 Returns the read status of a thread for the specified user, including the ID 1434 of the last message they have read and the number of unread messages remaining. 1435 For user-authenticated requests, the status is always returned for the 1436 authenticated user and the `user` parameter is ignored. For server-to-server 1437 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1438 Returns 404 if the thread does not exist or the caller does not have access 1439 to it. 1440 1441 Args: 1442 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1443 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1444 1445 Returns: 1446 The read status record for the requested thread and user. 1447 """ 1448 query: dict[str, object] = {} 1449 if user is not None: 1450 query["user"] = user 1451 return self._http.request( 1452 f"/api/v1/threads/{thread}/read_status", 1453 query=query, 1454 response_type=ThreadReadStatus, 1455 ) 1456 1457 def search(self, thread: str, q: str, *, type: str | None = None) -> ThreadSearchResponse: 1458 """ 1459 Search context items within a thread 1460 Performs a full-text search over context items (messages, files, and other 1461 indexed sources) attached to the specified thread. Returns tagged objects 1462 whose content matches the query string. 1463 Use the `type` param to restrict results to a particular context source. All 1464 accessible context source types are searched when `type` is omitted. The 1465 authenticated user must have access to the thread. 1466 1467 Args: 1468 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1469 q: Full-text search query. Results are ranked by relevance to this string. 1470 type: Context source type to restrict the search to, e.g. `"thread/messages"`. Omit to search across all context sources for the thread. 1471 1472 Returns: 1473 Successful response 1474 """ 1475 query: dict[str, object] = {} 1476 query["q"] = q 1477 if type is not None: 1478 query["type"] = type 1479 return self._http.request( 1480 f"/api/v1/threads/{thread}/search", 1481 query=query, 1482 response_type=ThreadSearchResponse, 1483 )
17class ThreadMemberCreateInput(TypedDict, total=False): 18 "Add a member to a thread" 19 20 agent: str | None 21 'Agent ID of the principal to add. Required when `type` is `"agent"`.' 22 membership_type: str | None 23 'Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.' 24 type: Required[str] 25 'Kind of principal being added. Must be `"user"` or `"agent"`.' 26 user: str | None 27 'User ID of the principal to add. Required when `type` is `"user"`.'
Add a member to a thread
30class SettingReplaceInput(TypedDict): 31 "Update thread settings" 32 33 settings: dict[str, Any] 34 "Map of settings fields to update. Include only the keys you want to change."
Update thread settings
37class ThreadReplaceInputProfilePicture(TypedDict, total=False): 38 data: str | None 39 "Base64-encoded image payload. Must be a valid base64 string." 40 filename: str | None 41 'Original filename of the image, e.g. `"avatar.png"`. Used for storage metadata.' 42 mime_type: str | None 43 'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.'
46class ThreadReplaceInput(TypedDict, total=False): 47 "Update a thread" 48 49 description: str | None 50 "Optional longer text describing the thread's purpose. Replaces the existing description when provided." 51 metadata: dict[str, Any] | None 52 "Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata." 53 muted: bool | None 54 "When `true`, suppresses notifications for new messages in this thread for the authenticated user." 55 profile_picture: ThreadReplaceInputProfilePicture | None 56 "New profile picture for the thread. Provide all three inner fields to replace the existing image." 57 title: str | None 58 "Human-readable display name for the thread. Replaces the existing title when provided."
Update a thread
Optional longer text describing the thread's purpose. Replaces the existing description when provided.
Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
When true, suppresses notifications for new messages in this thread for the authenticated user.
New profile picture for the thread. Provide all three inner fields to replace the existing image.
61class ThreadMarkReadInput(TypedDict, total=False): 62 "Mark a thread as read" 63 64 last_read_message: str | None 65 "Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`." 66 use_latest_message: bool | None 67 "When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`." 68 user: str | None 69 "User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token."
Mark a thread as read
Message ID (msg_...) to record as the last read message. Mutually exclusive with use_latest_message.
When true, marks the thread as read up to the latest message. Mutually exclusive with last_read_message.
72class ThreadPictureInputPicture(TypedDict): 73 data: str 74 "Base64-encoded binary content of the image file." 75 filename: str 76 'Original filename of the image, e.g. `"avatar.png"`. Used for storage and display.' 77 mime_type: str 78 'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.'
81class ThreadPictureInput(TypedDict): 82 "Update a thread's profile picture" 83 84 picture: ThreadPictureInputPicture 85 "Profile picture payload. Must include the base64-encoded image data and its MIME type."
Update a thread's profile picture
Profile picture payload. Must include the base64-encoded image data and its MIME type.
88class ThreadMemberListResponseDataItemUser(BaseModel): 89 alias: str | None = Field( 90 default=None, description="Short handle or alias for the user. `null` if not set." 91 ) 92 app: str | None = Field( 93 default=None, 94 description="ID of the app this user (and their access token) is scoped to (`dap_...`). `null` if the user is not scoped to an app.", 95 ) 96 app_name: str | None = Field( 97 default=None, 98 description="Display name of the user's app. `null` when the app association was not preloaded by the caller.", 99 ) 100 email: str | None = Field(default=None, description="Email address of the user.") 101 id: str = Field(..., description="User ID (`usr_...`).") 102 is_system_user: bool | None = Field( 103 default=None, 104 description="`true` if this account is an internal system user rather than a human. System users are created automatically by the platform.", 105 ) 106 metadata: dict[str, Any] | None = Field( 107 default=None, 108 description="Arbitrary key-value metadata attached to the user. Defaults to an empty object.", 109 ) 110 name: str | None = Field( 111 default=None, 112 description="Full display name of the user. `null` if the user has not set a name.", 113 ) 114 org: str | None = Field( 115 default=None, 116 description="ID of the organization this user belongs to (`org_...`). `null` if the user is not a member of any organization.", 117 ) 118 org_name: str | None = Field( 119 default=None, 120 description="Display name of the user's organization. `null` when the user is not in an org, or when the org association was not preloaded by the caller.", 121 ) 122 org_role: str | None = Field( 123 default=None, 124 description='Role of the user within their organization. One of `"admin"`, `"member"`, or `"viewer"`. `null` when the user is not a member of any organization.', 125 ) 126 sandbox: str | None = Field( 127 default=None, 128 description="ID of the sandbox environment this user is scoped to (`sbx_...`). `null` for production users.", 129 ) 130 sandbox_name: str | None = Field( 131 default=None, 132 description="Display name of the user's sandbox environment. `null` for production users, or when the sandbox association was not preloaded by the caller.", 133 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the app this user (and their access token) is scoped to (dap_...). null if the user is not scoped to an app.
Display name of the user's app. null when the app association was not preloaded by the caller.
true if this account is an internal system user rather than a human. System users are created automatically by the platform.
Arbitrary key-value metadata attached to the user. Defaults to an empty object.
ID of the organization this user belongs to (org_...). null if the user is not a member of any organization.
Display name of the user's organization. null when the user is not in an org, or when the org association was not preloaded by the caller.
Role of the user within their organization. One of "admin", "member", or "viewer". null when the user is not a member of any organization.
136class ThreadMemberListResponseDataItem(BaseModel): 137 membership_type: str | None = Field( 138 default=None, 139 description='Role of the member within the thread. One of `"owner"` (the user who created or was granted ownership) or `"member"` (a regular participant).', 140 ) 141 thread: str | None = Field( 142 default=None, description="ID of the thread this membership belongs to (`thr_...`)." 143 ) 144 user: ThreadMemberListResponseDataItemUser | None = Field( 145 default=None, 146 description="Full user object for the member (`usr_...`). Present when the association is preloaded; `null` otherwise.", 147 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Role of the member within the thread. One of "owner" (the user who created or was granted ownership) or "member" (a regular participant).
150class ThreadMemberListResponse(BaseModel): 151 """ 152 Successful response 153 """ 154 155 data: list[ThreadMemberListResponseDataItem] = Field( 156 ..., 157 description="Array of thread member objects representing all current members of the thread.", 158 )
Successful response
161class SettingListResponse(BaseModel): 162 """ 163 Successful response 164 """ 165 166 agent_enabled: bool | None = Field( 167 default=None, 168 description="Whether the AI agent is active for this thread. Defaults to `true` when no settings have been explicitly set.", 169 )
Successful response
172class ThreadAgentsResponse(BaseModel): 173 """ 174 Successful response 175 """ 176 177 data: list[dict[str, Any]] = Field( 178 ..., 179 description="Array of agent objects for the thread. Each object includes `id`, `name`, `alias`, `profile_picture`, and `metadata`. Thread owners also receive an `agent_config` object with the agent's policy type and context configuration.", 180 )
Successful response
183class ThreadArtifactsResponseDataItemImageSource(BaseModel): 184 file: str | None = Field( 185 default=None, 186 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 187 ) 188 height: int | None = Field( 189 default=None, description="Height of the image in pixels. `null` if not known." 190 ) 191 media: str | None = Field( 192 default=None, 193 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 194 ) 195 mime_type: str | None = Field( 196 default=None, 197 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 198 ) 199 refresh_url: str | None = Field( 200 default=None, 201 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 202 ) 203 url: str | None = Field( 204 default=None, 205 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 206 ) 207 width: int | None = Field( 208 default=None, description="Width of the image in pixels. `null` if not known." 209 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
212class ThreadArtifactsResponseDataItem(BaseModel): 213 agent: str | None = Field( 214 default=None, 215 description="ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", 216 ) 217 content_type: str | None = Field( 218 default=None, 219 description='MIME type of the current version\'s file, e.g. `"text/csv"` or `"image/png"`. `null` if no file is attached.', 220 ) 221 created_at: datetime | None = Field( 222 default=None, description="When the artifact was first created (ISO 8601)." 223 ) 224 current_version: str | None = Field( 225 default=None, 226 description="ID of the current (latest published) artifact version (`artv_...`). `null` if no version has been published.", 227 ) 228 description: str | None = Field( 229 default=None, 230 description="Optional longer description of the artifact's contents or purpose. `null` if not set.", 231 ) 232 file: str | None = Field( 233 default=None, 234 description="Storage file ID for the current version (`fil_...`). `null` if no file is attached.", 235 ) 236 file_name: str | None = Field( 237 default=None, 238 description='Original filename of the current version\'s file, e.g. `"output.csv"`. `null` if no file is attached.', 239 ) 240 file_url: str | None = Field( 241 default=None, 242 description="Short-lived signed URL for downloading the current version's file. `null` if no file is attached.", 243 ) 244 id: str = Field(..., description="Artifact ID (`art_...`).") 245 image_source: ThreadArtifactsResponseDataItemImageSource | None = Field( 246 default=None, 247 description='Image source metadata for rendering the current version\'s file inline. Present only when `content_type` starts with `"image/"`. `null` otherwise.', 248 ) 249 name: str | None = Field( 250 default=None, 251 description='Human-readable name for the artifact, e.g. `"Q2 Report"`. `null` if not set.', 252 ) 253 org: str | None = Field( 254 default=None, description="ID of the organization this artifact belongs to (`org_...`)." 255 ) 256 sandbox: str | None = Field( 257 default=None, 258 description="Identifier of the sandbox environment associated with this artifact. `null` if not sandbox-scoped.", 259 ) 260 team: str | None = Field( 261 default=None, 262 description="ID of the team that owns this artifact (`tea_...`). `null` if not team-scoped.", 263 ) 264 thread: str | None = Field( 265 default=None, 266 description="ID of the thread in which this artifact was created (`thr_...`). `null` if not thread-scoped.", 267 ) 268 updated_at: datetime | None = Field( 269 default=None, description="When the artifact record was last modified (ISO 8601)." 270 ) 271 user: str | None = Field( 272 default=None, 273 description="ID of the user who created this artifact (`usr_...`). `null` if not user-scoped.", 274 ) 275 version: int | None = Field( 276 default=None, 277 description="Current version number of the artifact. Increments each time a new version is published.", 278 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the agent that produced this artifact (agt_...). null if not agent-produced.
MIME type of the current version's file, e.g. "text/csv" or "image/png". null if no file is attached.
ID of the current (latest published) artifact version (artv_...). null if no version has been published.
Optional longer description of the artifact's contents or purpose. null if not set.
Storage file ID for the current version (fil_...). null if no file is attached.
Original filename of the current version's file, e.g. "output.csv". null if no file is attached.
Short-lived signed URL for downloading the current version's file. null if no file is attached.
Image source metadata for rendering the current version's file inline. Present only when content_type starts with "image/". null otherwise.
Identifier of the sandbox environment associated with this artifact. null if not sandbox-scoped.
ID of the thread in which this artifact was created (thr_...). null if not thread-scoped.
281class ThreadArtifactsResponse(BaseModel): 282 """ 283 Successful response 284 """ 285 286 data: list[ThreadArtifactsResponseDataItem] = Field( 287 ..., description="Array of artifact objects produced during the thread's conversation." 288 )
Successful response
291class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(BaseModel): 292 file: str | None = Field( 293 default=None, 294 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 295 ) 296 height: int | None = Field( 297 default=None, description="Height of the image in pixels. `null` if not known." 298 ) 299 media: str | None = Field( 300 default=None, 301 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 302 ) 303 mime_type: str | None = Field( 304 default=None, 305 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 306 ) 307 refresh_url: str | None = Field( 308 default=None, 309 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 310 ) 311 url: str | None = Field( 312 default=None, 313 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 314 ) 315 width: int | None = Field( 316 default=None, description="Width of the image in pixels. `null` if not known." 317 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
320class ThreadMessagesResponseDataMessagesItemActorsItem(BaseModel): 321 alias: str | None = Field( 322 default=None, 323 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 324 ) 325 id: str | None = Field( 326 default=None, 327 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 328 ) 329 name: str | None = Field( 330 default=None, 331 description="Display name of the actor shown in the UI. `null` if no name is set.", 332 ) 333 profile_picture: ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture | None = Field( 334 default=None, 335 description="Profile picture for the actor. `null` if the actor has no profile picture.", 336 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
339class ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource(BaseModel): 340 file: str | None = Field( 341 default=None, 342 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 343 ) 344 height: int | None = Field( 345 default=None, description="Height of the image in pixels. `null` if not known." 346 ) 347 media: str | None = Field( 348 default=None, 349 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 350 ) 351 mime_type: str | None = Field( 352 default=None, 353 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 354 ) 355 refresh_url: str | None = Field( 356 default=None, 357 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 358 ) 359 url: str | None = Field( 360 default=None, 361 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 362 ) 363 width: int | None = Field( 364 default=None, description="Width of the image in pixels. `null` if not known." 365 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
368class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource(BaseModel): 369 file: str | None = Field( 370 default=None, 371 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 372 ) 373 height: int | None = Field( 374 default=None, description="Height of the image in pixels. `null` if not known." 375 ) 376 media: str | None = Field( 377 default=None, 378 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 379 ) 380 mime_type: str | None = Field( 381 default=None, 382 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 383 ) 384 refresh_url: str | None = Field( 385 default=None, 386 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 387 ) 388 url: str | None = Field( 389 default=None, 390 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 391 ) 392 width: int | None = Field( 393 default=None, description="Width of the image in pixels. `null` if not known." 394 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
397class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem(BaseModel): 398 content_type: str | None = Field( 399 default=None, 400 description='MIME type of this variant\'s file (e.g., `"image/jpeg"`, `"video/mp4"`). `null` if the file is not loaded.', 401 ) 402 created_at: datetime | None = Field( 403 default=None, description="When this variant was created (ISO 8601)." 404 ) 405 file: str | None = Field( 406 default=None, 407 description="ID of the underlying storage file that backs this variant (`fil_...`).", 408 ) 409 filename: str | None = Field( 410 default=None, 411 description="Original filename of the uploaded file for this variant. `null` if the file is not loaded.", 412 ) 413 height: int | None = Field( 414 default=None, description="Height of this variant in pixels. `null` if not recorded." 415 ) 416 id: str = Field(..., description="Media variant ID (`mvr_...`).") 417 image_source: ( 418 ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource | None 419 ) = Field( 420 default=None, 421 description="Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types.", 422 ) 423 updated_at: datetime | None = Field( 424 default=None, description="When this variant was last updated (ISO 8601)." 425 ) 426 url: str | None = Field( 427 default=None, 428 description="Signed download URL for this variant, resolved at request time. `null` if the file is unavailable.", 429 ) 430 variant_key: str | None = Field( 431 default=None, 432 description='Identifier for this variant\'s processing tier. Common values include `"original"` (the unmodified upload) and `"thumbnail"` (a resized preview).', 433 ) 434 width: int | None = Field( 435 default=None, description="Width of this variant in pixels. `null` if not recorded." 436 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
MIME type of this variant's file (e.g., "image/jpeg", "video/mp4"). null if the file is not loaded.
Original filename of the uploaded file for this variant. null if the file is not loaded.
Resolved image delivery metadata for this variant, including dimensions and CDN URL. null for non-image content types.
Signed download URL for this variant, resolved at request time. null if the file is unavailable.
439class ThreadMessagesResponseDataMessagesItemAttachmentsItem(BaseModel): 440 content_type: str | None = Field( 441 default=None, 442 description='MIME type of the attached file, e.g. `"image/png"` or `"application/pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.', 443 ) 444 description: str | None = Field( 445 default=None, 446 description="Short description. The page meta-description for `scraped_link`, the artifact description for `artifact`, and the task description for `task` types. `null` on other types.", 447 ) 448 filename: str | None = Field( 449 default=None, 450 description='Original filename of the attached file, e.g. `"report.pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.', 451 ) 452 height: int | None = Field( 453 default=None, 454 description="Height in pixels of the media item. Present on `media` type only. `null` otherwise.", 455 ) 456 id: str = Field(..., description="Unique identifier for this attachment within the message.") 457 image_height: int | None = Field( 458 default=None, 459 description="Height in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.", 460 ) 461 image_source: ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource | None = Field( 462 default=None, 463 description="Image source metadata for inline rendering. Present on `file`, `scraped_link`, `artifact`, and `media` types when the content is an image. `null` otherwise.", 464 ) 465 image_url: str | None = Field( 466 default=None, 467 description="URL of the preview image extracted from the scraped page. Present on `scraped_link` type only. `null` otherwise.", 468 ) 469 image_width: int | None = Field( 470 default=None, 471 description="Width in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.", 472 ) 473 media_type: str | None = Field( 474 default=None, 475 description='The media category, e.g. `"video"` or `"audio"`. Present on `media` type only. `null` otherwise.', 476 ) 477 name: str | None = Field( 478 default=None, 479 description="Display name of the media item. Present on `media` type only. `null` otherwise.", 480 ) 481 object: dict[str, Any] | None = Field( 482 default=None, 483 description="The full embedded object payload. For `task` type, contains the task record. For `action` type, contains the action definition. `null` on other types.", 484 ) 485 title: str | None = Field( 486 default=None, 487 description="Display title. The page title for `scraped_link`, the artifact name for `artifact`, and the task title for `task` types. `null` on other types.", 488 ) 489 type: str = Field( 490 ..., 491 description='The attachment type. One of `"file"`, `"scraped_link"`, `"artifact"`, `"task"`, `"media"`, or `"action"`. Determines which additional fields are present.', 492 ) 493 url: str | None = Field( 494 default=None, 495 description="URL to access the resource. A signed download URL for `file` and `artifact` types; the original URL for `scraped_link`; a media playback URL for `media`. `null` on `task` and `action` types.", 496 ) 497 variants: list[ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem] | None = ( 498 Field( 499 default=None, 500 description="Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only. `null` otherwise.", 501 ) 502 ) 503 version: int | None = Field( 504 default=None, 505 description="Version number of the attached artifact at the time of attachment. Present on `artifact` type only. `null` otherwise.", 506 ) 507 width: int | None = Field( 508 default=None, 509 description="Width in pixels of the media item. Present on `media` type only. `null` otherwise.", 510 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
MIME type of the attached file, e.g. "image/png" or "application/pdf". Present on file, artifact, and media types. null otherwise.
Short description. The page meta-description for scraped_link, the artifact description for artifact, and the task description for task types. null on other types.
Original filename of the attached file, e.g. "report.pdf". Present on file, artifact, and media types. null otherwise.
Height in pixels of the media item. Present on media type only. null otherwise.
Height in pixels of the scraped preview image. Present on scraped_link type only. null otherwise.
Image source metadata for inline rendering. Present on file, scraped_link, artifact, and media types when the content is an image. null otherwise.
URL of the preview image extracted from the scraped page. Present on scraped_link type only. null otherwise.
Width in pixels of the scraped preview image. Present on scraped_link type only. null otherwise.
The media category, e.g. "video" or "audio". Present on media type only. null otherwise.
The full embedded object payload. For task type, contains the task record. For action type, contains the action definition. null on other types.
Display title. The page title for scraped_link, the artifact name for artifact, and the task title for task types. null on other types.
The attachment type. One of "file", "scraped_link", "artifact", "task", "media", or "action". Determines which additional fields are present.
URL to access the resource. A signed download URL for file and artifact types; the original URL for scraped_link; a media playback URL for media. null on task and action types.
Array of available encoding variants for the media item (e.g. different resolutions). Present on media type only. null otherwise.
513class ThreadMessagesResponseDataMessagesItemReactionsItem(BaseModel): 514 payload: dict[str, Any] | None = Field( 515 default=None, 516 description='Type-specific reaction data. For `"emoji_reaction"` reactions, contains an `emoji` key with the Unicode emoji string (e.g., `" "`).', 517 ) 518 type: str = Field( 519 ..., 520 description='Reaction type identifier. Currently always `"emoji_reaction"` for emoji-based reactions.', 521 ) 522 user: str | None = Field( 523 default=None, description="Public ID of the user who added the reaction (`usr_...`)." 524 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Type-specific reaction data. For "emoji_reaction" reactions, contains an emoji key with the Unicode emoji string (e.g., " ").
527class ThreadMessagesResponseDataMessagesItem(BaseModel): 528 actors: list[ThreadMessagesResponseDataMessagesItemActorsItem] | None = Field( 529 default=None, 530 description="Resolved actor descriptors for the message sender, combining identity and display metadata. Always contains exactly one entry.", 531 ) 532 agent: str | None = Field( 533 default=None, 534 description="ID of the agent user that sent this message (`agi_...`). `null` for messages sent by human users.", 535 ) 536 agent_mode: Literal["cli", "embedded"] | None = Field( 537 default=None, 538 description="Local agent execution mode for this message. One of `cli`, `embedded`, or `null` when the message was not created by a local agent execution path.", 539 ) 540 attachments: list[ThreadMessagesResponseDataMessagesItemAttachmentsItem] | None = Field( 541 default=None, 542 description="Files, links, tasks, media, artifacts, and actions attached to this message. Empty array if there are no attachments.", 543 ) 544 branched_thread: str | None = Field( 545 default=None, 546 description="ID of the thread that was branched from this message (`thr_...`). `null` if this message has not spawned a branch thread.", 547 ) 548 content: str | None = Field( 549 default=None, 550 description="Text content of the message. `null` for messages that contain only attachments.", 551 ) 552 created_at: datetime | None = Field( 553 default=None, description="When the message was posted (ISO 8601)." 554 ) 555 has_replies: bool | None = Field( 556 default=None, 557 description="Whether this message has at least one reply. Only present when explicitly requested or computed by the server.", 558 ) 559 id: str = Field(..., description="Message ID (`msg_...`).") 560 idempotency_key: str | None = Field( 561 default=None, 562 description="Client-supplied idempotency key used to deduplicate message sends. `null` if the sender did not provide one.", 563 ) 564 legacy_agent: str | None = Field( 565 default=None, 566 description="Identifier of the legacy chat agent that sent this message, if applicable. `null` for messages sent by users or modern agent users.", 567 ) 568 metadata: dict[str, Any] | None = Field( 569 default=None, 570 description="Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.", 571 ) 572 org: str | None = Field( 573 default=None, description="ID of the organization that owns this message (`org_...`)." 574 ) 575 reactions: list[ThreadMessagesResponseDataMessagesItemReactionsItem] | None = Field( 576 default=None, 577 description="Emoji and other reactions added to this message by users. Empty array if no reactions have been added or the association is not preloaded.", 578 ) 579 rendering_mode: str | None = Field( 580 default=None, 581 description='Display hint for how the message should be rendered. One of `"reply"`, `"direct"`, or `"inline"`. `null` for user-authored messages, which are always rendered as standard replies.', 582 ) 583 replies: list[dict[str, Any]] | None = Field( 584 default=None, 585 description="Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.", 586 ) 587 replies_after_cursor: str | None = Field( 588 default=None, 589 description="Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.", 590 ) 591 replies_before_cursor: str | None = Field( 592 default=None, 593 description="Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.", 594 ) 595 reply_count: int | None = Field( 596 default=None, 597 description="Total number of direct replies to this message. Only present when explicitly requested or computed by the server.", 598 ) 599 reply_to: dict[str, Any] | None = Field( 600 default=None, 601 description="The parent message this message is a reply to, expanded as a full message object when loaded. `null` if this is a top-level message or the association is not preloaded.", 602 ) 603 sandbox: str | None = Field( 604 default=None, 605 description="ID of the developer sandbox this message belongs to (`dsb_...`). `null` for non-sandbox messages.", 606 ) 607 team: str | None = Field( 608 default=None, 609 description="ID of the team this message is scoped to (`tem_...`). `null` if the message is not team-scoped.", 610 ) 611 thread: str | None = Field( 612 default=None, 613 description="ID of the thread this message belongs to (`thr_...`). `null` for messages not yet associated with a thread.", 614 ) 615 user: str | None = Field( 616 default=None, 617 description="The human user who sent this message. Returns a public ID string (`usr_...`) when the association is not preloaded, or an expanded user object when it is. `null` for messages sent by agents.", 618 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Resolved actor descriptors for the message sender, combining identity and display metadata. Always contains exactly one entry.
ID of the agent user that sent this message (agi_...). null for messages sent by human users.
Local agent execution mode for this message. One of cli, embedded, or null when the message was not created by a local agent execution path.
Files, links, tasks, media, artifacts, and actions attached to this message. Empty array if there are no attachments.
ID of the thread that was branched from this message (thr_...). null if this message has not spawned a branch thread.
Text content of the message. null for messages that contain only attachments.
Whether this message has at least one reply. Only present when explicitly requested or computed by the server.
Client-supplied idempotency key used to deduplicate message sends. null if the sender did not provide one.
Identifier of the legacy chat agent that sent this message, if applicable. null for messages sent by users or modern agent users.
Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.
Emoji and other reactions added to this message by users. Empty array if no reactions have been added or the association is not preloaded.
Display hint for how the message should be rendered. One of "reply", "direct", or "inline". null for user-authored messages, which are always rendered as standard replies.
Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.
Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.
Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.
Total number of direct replies to this message. Only present when explicitly requested or computed by the server.
The parent message this message is a reply to, expanded as a full message object when loaded. null if this is a top-level message or the association is not preloaded.
ID of the developer sandbox this message belongs to (dsb_...). null for non-sandbox messages.
ID of the team this message is scoped to (tem_...). null if the message is not team-scoped.
621class ThreadMessagesResponseData(BaseModel): 622 after_cursor: str | None = Field( 623 default=None, 624 description="Opaque cursor to pass as `after` to retrieve the page of messages newer than this result set. `null` when there are no later messages.", 625 ) 626 anchor: str | None = Field( 627 default=None, 628 description="Message ID used as the anchor for a windowed query. `null` for ordinary cursor pagination.", 629 ) 630 before_cursor: str | None = Field( 631 default=None, 632 description="Opaque cursor to pass as `before` to retrieve the page of messages older than this result set. `null` when there are no earlier messages.", 633 ) 634 messages: list[ThreadMessagesResponseDataMessagesItem] = Field( 635 ..., description="Ordered array of message objects for this page of results." 636 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Opaque cursor to pass as after to retrieve the page of messages newer than this result set. null when there are no later messages.
Message ID used as the anchor for a windowed query. null for ordinary cursor pagination.
Opaque cursor to pass as before to retrieve the page of messages older than this result set. null when there are no earlier messages.
639class ThreadMessagesResponse(BaseModel): 640 """ 641 Successful response 642 """ 643 644 data: ThreadMessagesResponseData = Field( 645 ..., 646 description="Pagination envelope containing the messages for this page along with cursors for adjacent pages.", 647 )
Successful response
650class ThreadSearchResponse(BaseModel): 651 """ 652 Successful response 653 """ 654 655 data: list[dict[str, Any]] = Field( 656 ..., 657 description="Array of matching context items. Each item is a tagged object whose shape depends on the source type.", 658 )
Successful response
661class AsyncThreadMemberResource: 662 def __init__(self, http: HttpClient): 663 self._http = http 664 665 async def remove(self, thread: str) -> None: 666 """ 667 Remove a member from a thread 668 Removes a user or agent membership from the specified thread. The authenticated 669 user must have access to the thread. A successful removal returns HTTP 204 with 670 no response body. 671 Supply either `user` or `agent` depending on the value of `type`. Returns 404 672 if the thread or the membership record does not exist. 673 674 Args: 675 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 676 677 Returns: 678 Empty response body. HTTP 204 on success. 679 """ 680 await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE") 681 682 async def list(self, thread: str) -> ThreadMemberListResponse: 683 """ 684 List members of a thread 685 Returns all current members of the specified thread, including both user and 686 agent members. The authenticated user must have visibility into the thread; 687 requests from users without access return 403. 688 Results are returned as a flat array in the `data` field. The list is not 689 paginated all members are returned in a single response. 690 691 Args: 692 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 693 694 Returns: 695 Successful response 696 """ 697 return await self._http.request( 698 f"/api/v1/threads/{thread}/members", 699 response_type=ThreadMemberListResponse, 700 ) 701 702 async def create(self, thread: str, input: ThreadMemberCreateInput) -> ThreadMember: 703 """ 704 Add a member to a thread 705 Adds a user or agent as a member of the specified thread. The authenticated 706 user must have access to the thread. On success the new membership record is 707 returned with HTTP 201. 708 Supply either `user` or `agent` depending on the value of `type`. Attempting 709 to add a principal that is already a member of the thread returns a 422 error. 710 711 Args: 712 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 713 input: Request body. 714 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 715 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 716 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 717 input.user: User ID of the principal to add. Required when `type` is `"user"`. 718 719 Returns: 720 The newly created thread membership record. 721 """ 722 return await self._http.request( 723 f"/api/v1/threads/{thread}/members", 724 method="POST", 725 body=input, 726 response_type=ThreadMember, 727 )
665 async def remove(self, thread: str) -> None: 666 """ 667 Remove a member from a thread 668 Removes a user or agent membership from the specified thread. The authenticated 669 user must have access to the thread. A successful removal returns HTTP 204 with 670 no response body. 671 Supply either `user` or `agent` depending on the value of `type`. Returns 404 672 if the thread or the membership record does not exist. 673 674 Args: 675 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 676 677 Returns: 678 Empty response body. HTTP 204 on success. 679 """ 680 await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")
Remove a member from a thread
Removes a user or agent membership from the specified thread. The authenticated
user must have access to the thread. A successful removal returns HTTP 204 with
no response body.
Supply either user or agent depending on the value of type. Returns 404
if the thread or the membership record does not exist.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from.
Returns:
Empty response body. HTTP 204 on success.
682 async def list(self, thread: str) -> ThreadMemberListResponse: 683 """ 684 List members of a thread 685 Returns all current members of the specified thread, including both user and 686 agent members. The authenticated user must have visibility into the thread; 687 requests from users without access return 403. 688 Results are returned as a flat array in the `data` field. The list is not 689 paginated all members are returned in a single response. 690 691 Args: 692 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 693 694 Returns: 695 Successful response 696 """ 697 return await self._http.request( 698 f"/api/v1/threads/{thread}/members", 699 response_type=ThreadMemberListResponse, 700 )
List members of a thread
Returns all current members of the specified thread, including both user and
agent members. The authenticated user must have visibility into the thread;
requests from users without access return 403.
Results are returned as a flat array in the data field. The list is not
paginated all members are returned in a single response.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from.
Returns:
Successful response
702 async def create(self, thread: str, input: ThreadMemberCreateInput) -> ThreadMember: 703 """ 704 Add a member to a thread 705 Adds a user or agent as a member of the specified thread. The authenticated 706 user must have access to the thread. On success the new membership record is 707 returned with HTTP 201. 708 Supply either `user` or `agent` depending on the value of `type`. Attempting 709 to add a principal that is already a member of the thread returns a 422 error. 710 711 Args: 712 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 713 input: Request body. 714 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 715 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 716 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 717 input.user: User ID of the principal to add. Required when `type` is `"user"`. 718 719 Returns: 720 The newly created thread membership record. 721 """ 722 return await self._http.request( 723 f"/api/v1/threads/{thread}/members", 724 method="POST", 725 body=input, 726 response_type=ThreadMember, 727 )
Add a member to a thread
Adds a user or agent as a member of the specified thread. The authenticated
user must have access to the thread. On success the new membership record is
returned with HTTP 201.
Supply either user or agent depending on the value of type. Attempting
to add a principal that is already a member of the thread returns a 422 error.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from. - input: Request body.
- input.agent: Agent ID of the principal to add. Required when
typeis"agent". - input.membership_type: Role granted to the new member. One of
"owner"or"member". Defaults to"member". - input.type: Kind of principal being added. Must be
"user"or"agent". - input.user: User ID of the principal to add. Required when
typeis"user".
Returns:
The newly created thread membership record.
730class AsyncSettingResource: 731 def __init__(self, http: HttpClient): 732 self._http = http 733 734 async def list(self, thread: str) -> SettingListResponse: 735 """ 736 Retrieve thread settings 737 Returns the current settings for the specified thread. Settings control 738 per-thread behavior such as whether the AI agent is enabled. 739 The authenticated user must own the thread or be a member of its workspace. 740 If settings have never been explicitly configured, defaults are returned 741 (for example, `agent_enabled` defaults to `true`). 742 743 Args: 744 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 745 746 Returns: 747 Successful response 748 """ 749 return await self._http.request( 750 f"/api/v1/threads/{thread}/settings", 751 response_type=SettingListResponse, 752 ) 753 754 async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 755 """ 756 Update thread settings 757 Updates the settings for the specified thread. Only fields included in 758 the `settings` map are modified; omitted fields retain their current values. 759 The authenticated user must own the thread or be a member of its workspace. 760 Returns the full settings object reflecting the state after the update. 761 Validation errors are returned as `422 Unprocessable Entity`. 762 763 Args: 764 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 765 input: Request body. 766 input.settings: Map of settings fields to update. Include only the keys you want to change. 767 768 Returns: 769 The thread settings object after the update has been applied. 770 """ 771 return await self._http.request( 772 f"/api/v1/threads/{thread}/settings", 773 method="PUT", 774 body=input, 775 response_type=ThreadSettings, 776 )
734 async def list(self, thread: str) -> SettingListResponse: 735 """ 736 Retrieve thread settings 737 Returns the current settings for the specified thread. Settings control 738 per-thread behavior such as whether the AI agent is enabled. 739 The authenticated user must own the thread or be a member of its workspace. 740 If settings have never been explicitly configured, defaults are returned 741 (for example, `agent_enabled` defaults to `true`). 742 743 Args: 744 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 745 746 Returns: 747 Successful response 748 """ 749 return await self._http.request( 750 f"/api/v1/threads/{thread}/settings", 751 response_type=SettingListResponse, 752 )
Retrieve thread settings
Returns the current settings for the specified thread. Settings control
per-thread behavior such as whether the AI agent is enabled.
The authenticated user must own the thread or be a member of its workspace.
If settings have never been explicitly configured, defaults are returned
(for example, agent_enabled defaults to true).
Arguments:
- thread: Thread ID (
thr_...). Must belong to the authenticated user's workspace.
Returns:
Successful response
754 async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 755 """ 756 Update thread settings 757 Updates the settings for the specified thread. Only fields included in 758 the `settings` map are modified; omitted fields retain their current values. 759 The authenticated user must own the thread or be a member of its workspace. 760 Returns the full settings object reflecting the state after the update. 761 Validation errors are returned as `422 Unprocessable Entity`. 762 763 Args: 764 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 765 input: Request body. 766 input.settings: Map of settings fields to update. Include only the keys you want to change. 767 768 Returns: 769 The thread settings object after the update has been applied. 770 """ 771 return await self._http.request( 772 f"/api/v1/threads/{thread}/settings", 773 method="PUT", 774 body=input, 775 response_type=ThreadSettings, 776 )
Update thread settings
Updates the settings for the specified thread. Only fields included in
the settings map are modified; omitted fields retain their current values.
The authenticated user must own the thread or be a member of its workspace.
Returns the full settings object reflecting the state after the update.
Validation errors are returned as 422 Unprocessable Entity.
Arguments:
- thread: Thread ID (
thr_...). Must belong to the authenticated user's workspace. - input: Request body.
- input.settings: Map of settings fields to update. Include only the keys you want to change.
Returns:
The thread settings object after the update has been applied.
779class AsyncThreadResource: 780 def __init__(self, http: HttpClient): 781 self._http = http 782 self.members = AsyncThreadMemberResource(http) 783 self.settings = AsyncSettingResource(http) 784 785 async def delete(self, thread: str) -> None: 786 """ 787 Delete a thread 788 Permanently deletes a thread and all of its messages and artifacts. This action 789 cannot be undone. 790 The authenticated user must own the thread or be an owner of the team the thread 791 belongs to. Attempting to delete a thread owned by another user or team returns 403. 792 793 Args: 794 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 795 796 Returns: 797 Empty response on successful deletion. 798 """ 799 await self._http.request(f"/api/v1/threads/{thread}", method="DELETE") 800 801 async def get(self, thread: str) -> Thread: 802 """ 803 Retrieve a thread 804 Returns the full thread record for the given thread ID. The authenticated user 805 must own the thread or be a member of the workspace it belongs to. 806 Use this endpoint to fetch the current state of a single thread, including its 807 title, description, and metadata. To list many threads, use the list endpoint 808 with cursor-based pagination. 809 810 Args: 811 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 812 813 Returns: 814 The requested thread object. 815 """ 816 return await self._http.request(f"/api/v1/threads/{thread}", response_type=Thread) 817 818 async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 819 """ 820 Update a thread 821 Updates one or more mutable properties of the specified thread and returns 822 the full thread object with the applied changes. Only the fields you provide 823 are modified; omitted fields retain their current values. 824 If `profile_picture` is supplied, the image is uploaded before the other 825 fields are saved. Supplying invalid base64 picture data returns 422 and no 826 other fields are updated. 827 The authenticated user must own the thread or be a team owner of the workspace 828 the thread belongs to. 829 830 Args: 831 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 832 input: Request body. 833 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 834 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 835 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 836 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 837 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 838 839 Returns: 840 The thread object after the update has been applied. 841 """ 842 return await self._http.request( 843 f"/api/v1/threads/{thread}", 844 method="PUT", 845 body=input, 846 response_type=Thread, 847 ) 848 849 async def agents(self, thread: str) -> ThreadAgentsResponse: 850 """ 851 List agents in a thread 852 Returns the agents participating in the specified thread. Only personal user 853 threads (threads owned by a single user, not a team) expose agents through 854 this endpoint; requests for team threads return 404. 855 The authenticated user must have visibility into the thread. Each agent entry 856 includes display information such as name and profile picture. Thread-level 857 overrides (e.g. a custom name or profile picture set for this thread) take 858 precedence over the agent's default values. When the caller is the thread 859 owner, each entry also includes an `agent_config` object describing the 860 agent's message policy and context configuration. 861 862 Args: 863 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 864 865 Returns: 866 Successful response 867 """ 868 return await self._http.request( 869 f"/api/v1/threads/{thread}/agents", 870 response_type=ThreadAgentsResponse, 871 ) 872 873 async def artifacts(self, thread: str) -> ThreadArtifactsResponse: 874 """ 875 List artifacts for a thread 876 Returns all artifacts produced during a thread's AI conversation. Artifacts are 877 structured outputs such as code files, documents, or generated assets created 878 by the AI agent in response to messages in the thread. 879 The authenticated user must have access to the specified thread. Results are 880 returned in a single page; there is no cursor-based pagination for this endpoint. 881 882 Args: 883 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 884 885 Returns: 886 Successful response 887 """ 888 return await self._http.request( 889 f"/api/v1/threads/{thread}/artifacts", 890 response_type=ThreadArtifactsResponse, 891 ) 892 893 async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 894 """ 895 Mark a thread as read 896 Records that a user has read up to a specific message in the thread. Unread 897 indicators and badge counts are cleared up to the specified message. 898 You must supply exactly one of `last_read_message` or `use_latest_message`. 899 Omitting both returns 400. If `use_latest_message` is `true` and the thread 900 has no messages, the request succeeds silently with no state change. 901 For server-to-server (S2S) requests where no user identity is present in the 902 token, the `user` param is required to identify whose read state to update. 903 904 Args: 905 thread: Thread ID (`thr_...`). The thread to mark as read. 906 input: Request body. 907 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 908 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 909 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 910 911 Returns: 912 Empty response on success. 913 """ 914 await self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input) 915 916 async def messages( 917 self, 918 thread: str, 919 *, 920 before_cursor: str | None = None, 921 after_cursor: str | None = None, 922 limit: int | None = None, 923 anchor: str | None = None, 924 direction: Literal["before", "after", "around"] | None = None, 925 before_limit: int | None = None, 926 after_limit: int | None = None, 927 include_anchor: bool | None = None, 928 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 929 anchor_agent: str | None = None, 930 include_reply_counts: bool | None = None, 931 ) -> ThreadMessagesResponse: 932 """ 933 List messages in a thread 934 Returns a cursor-paginated list of messages belonging to the specified thread, 935 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 936 to page through or bound the result set; omit both to receive the most recent page. 937 Supply `anchor` and `direction` to fetch a window before, after, or around a 938 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 939 resolve the anchor from the latest embedded-agent message, and add 940 `anchor_agent` to scope that resolution to a single sender agent. 941 The authenticated user must have access to the thread's owner (workspace or user). 942 A 403 is returned if the thread exists but is not accessible to the caller; a 404 943 is returned if the thread does not exist or is not visible to the authenticated user. 944 Pass `include_reply_counts: true` to annotate each message with the number of 945 threaded replies it has received. This adds a small amount of latency and should 946 be omitted when reply counts are not needed. 947 948 Args: 949 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 950 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 951 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 952 limit: Maximum number of messages to return per page. Defaults to 20. 953 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 954 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 955 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20. 956 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20. 957 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 958 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 959 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 960 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 961 962 Returns: 963 Successful response 964 """ 965 query: dict[str, object] = {} 966 if before_cursor is not None: 967 query["before_cursor"] = before_cursor 968 if after_cursor is not None: 969 query["after_cursor"] = after_cursor 970 if limit is not None: 971 query["limit"] = limit 972 if anchor is not None: 973 query["anchor"] = anchor 974 if direction is not None: 975 query["direction"] = direction 976 if before_limit is not None: 977 query["before_limit"] = before_limit 978 if after_limit is not None: 979 query["after_limit"] = after_limit 980 if include_anchor is not None: 981 query["include_anchor"] = include_anchor 982 if anchor_agent_mode is not None: 983 query["anchor_agent_mode"] = anchor_agent_mode 984 if anchor_agent is not None: 985 query["anchor_agent"] = anchor_agent 986 if include_reply_counts is not None: 987 query["include_reply_counts"] = include_reply_counts 988 return await self._http.request( 989 f"/api/v1/threads/{thread}/messages", 990 query=query, 991 response_type=ThreadMessagesResponse, 992 ) 993 994 async def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 995 """ 996 Update a thread's profile picture 997 Uploads a new profile picture for the specified thread and returns the updated 998 thread object. The image must be supplied as a base64-encoded string with its 999 MIME type. 1000 The authenticated user must own the thread or be a team owner of the workspace 1001 the thread belongs to. Supplying invalid base64 data returns 422. 1002 1003 Args: 1004 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1005 input: Request body. 1006 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1007 1008 Returns: 1009 The thread object after the profile picture has been updated. 1010 """ 1011 return await self._http.request( 1012 f"/api/v1/threads/{thread}/picture", 1013 method="PUT", 1014 body=input, 1015 response_type=Thread, 1016 ) 1017 1018 async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1019 """ 1020 Retrieve a thread's read status 1021 Returns the read status of a thread for the specified user, including the ID 1022 of the last message they have read and the number of unread messages remaining. 1023 For user-authenticated requests, the status is always returned for the 1024 authenticated user and the `user` parameter is ignored. For server-to-server 1025 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1026 Returns 404 if the thread does not exist or the caller does not have access 1027 to it. 1028 1029 Args: 1030 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1031 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1032 1033 Returns: 1034 The read status record for the requested thread and user. 1035 """ 1036 query: dict[str, object] = {} 1037 if user is not None: 1038 query["user"] = user 1039 return await self._http.request( 1040 f"/api/v1/threads/{thread}/read_status", 1041 query=query, 1042 response_type=ThreadReadStatus, 1043 ) 1044 1045 async def search(self, thread: str, q: str, *, type: str | None = None) -> ThreadSearchResponse: 1046 """ 1047 Search context items within a thread 1048 Performs a full-text search over context items (messages, files, and other 1049 indexed sources) attached to the specified thread. Returns tagged objects 1050 whose content matches the query string. 1051 Use the `type` param to restrict results to a particular context source. All 1052 accessible context source types are searched when `type` is omitted. The 1053 authenticated user must have access to the thread. 1054 1055 Args: 1056 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1057 q: Full-text search query. Results are ranked by relevance to this string. 1058 type: Context source type to restrict the search to, e.g. `"thread/messages"`. Omit to search across all context sources for the thread. 1059 1060 Returns: 1061 Successful response 1062 """ 1063 query: dict[str, object] = {} 1064 query["q"] = q 1065 if type is not None: 1066 query["type"] = type 1067 return await self._http.request( 1068 f"/api/v1/threads/{thread}/search", 1069 query=query, 1070 response_type=ThreadSearchResponse, 1071 )
785 async def delete(self, thread: str) -> None: 786 """ 787 Delete a thread 788 Permanently deletes a thread and all of its messages and artifacts. This action 789 cannot be undone. 790 The authenticated user must own the thread or be an owner of the team the thread 791 belongs to. Attempting to delete a thread owned by another user or team returns 403. 792 793 Args: 794 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 795 796 Returns: 797 Empty response on successful deletion. 798 """ 799 await self._http.request(f"/api/v1/threads/{thread}", method="DELETE")
Delete a thread Permanently deletes a thread and all of its messages and artifacts. This action cannot be undone. The authenticated user must own the thread or be an owner of the team the thread belongs to. Attempting to delete a thread owned by another user or team returns 403.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must own this thread.
Returns:
Empty response on successful deletion.
801 async def get(self, thread: str) -> Thread: 802 """ 803 Retrieve a thread 804 Returns the full thread record for the given thread ID. The authenticated user 805 must own the thread or be a member of the workspace it belongs to. 806 Use this endpoint to fetch the current state of a single thread, including its 807 title, description, and metadata. To list many threads, use the list endpoint 808 with cursor-based pagination. 809 810 Args: 811 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 812 813 Returns: 814 The requested thread object. 815 """ 816 return await self._http.request(f"/api/v1/threads/{thread}", response_type=Thread)
Retrieve a thread Returns the full thread record for the given thread ID. The authenticated user must own the thread or be a member of the workspace it belongs to. Use this endpoint to fetch the current state of a single thread, including its title, description, and metadata. To list many threads, use the list endpoint with cursor-based pagination.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have access to this thread.
Returns:
The requested thread object.
818 async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 819 """ 820 Update a thread 821 Updates one or more mutable properties of the specified thread and returns 822 the full thread object with the applied changes. Only the fields you provide 823 are modified; omitted fields retain their current values. 824 If `profile_picture` is supplied, the image is uploaded before the other 825 fields are saved. Supplying invalid base64 picture data returns 422 and no 826 other fields are updated. 827 The authenticated user must own the thread or be a team owner of the workspace 828 the thread belongs to. 829 830 Args: 831 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 832 input: Request body. 833 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 834 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 835 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 836 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 837 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 838 839 Returns: 840 The thread object after the update has been applied. 841 """ 842 return await self._http.request( 843 f"/api/v1/threads/{thread}", 844 method="PUT", 845 body=input, 846 response_type=Thread, 847 )
Update a thread
Updates one or more mutable properties of the specified thread and returns
the full thread object with the applied changes. Only the fields you provide
are modified; omitted fields retain their current values.
If profile_picture is supplied, the image is uploaded before the other
fields are saved. Supplying invalid base64 picture data returns 422 and no
other fields are updated.
The authenticated user must own the thread or be a team owner of the workspace
the thread belongs to.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have permission to update this thread. - input: Request body.
- input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
- input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
- input.muted: When
true, suppresses notifications for new messages in this thread for the authenticated user. - input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
- input.title: Human-readable display name for the thread. Replaces the existing title when provided.
Returns:
The thread object after the update has been applied.
849 async def agents(self, thread: str) -> ThreadAgentsResponse: 850 """ 851 List agents in a thread 852 Returns the agents participating in the specified thread. Only personal user 853 threads (threads owned by a single user, not a team) expose agents through 854 this endpoint; requests for team threads return 404. 855 The authenticated user must have visibility into the thread. Each agent entry 856 includes display information such as name and profile picture. Thread-level 857 overrides (e.g. a custom name or profile picture set for this thread) take 858 precedence over the agent's default values. When the caller is the thread 859 owner, each entry also includes an `agent_config` object describing the 860 agent's message policy and context configuration. 861 862 Args: 863 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 864 865 Returns: 866 Successful response 867 """ 868 return await self._http.request( 869 f"/api/v1/threads/{thread}/agents", 870 response_type=ThreadAgentsResponse, 871 )
List agents in a thread
Returns the agents participating in the specified thread. Only personal user
threads (threads owned by a single user, not a team) expose agents through
this endpoint; requests for team threads return 404.
The authenticated user must have visibility into the thread. Each agent entry
includes display information such as name and profile picture. Thread-level
overrides (e.g. a custom name or profile picture set for this thread) take
precedence over the agent's default values. When the caller is the thread
owner, each entry also includes an agent_config object describing the
agent's message policy and context configuration.
Arguments:
- thread: Thread ID (
thr_...). Must be a personal user thread visible to the authenticated user.
Returns:
Successful response
873 async def artifacts(self, thread: str) -> ThreadArtifactsResponse: 874 """ 875 List artifacts for a thread 876 Returns all artifacts produced during a thread's AI conversation. Artifacts are 877 structured outputs such as code files, documents, or generated assets created 878 by the AI agent in response to messages in the thread. 879 The authenticated user must have access to the specified thread. Results are 880 returned in a single page; there is no cursor-based pagination for this endpoint. 881 882 Args: 883 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 884 885 Returns: 886 Successful response 887 """ 888 return await self._http.request( 889 f"/api/v1/threads/{thread}/artifacts", 890 response_type=ThreadArtifactsResponse, 891 )
List artifacts for a thread Returns all artifacts produced during a thread's AI conversation. Artifacts are structured outputs such as code files, documents, or generated assets created by the AI agent in response to messages in the thread. The authenticated user must have access to the specified thread. Results are returned in a single page; there is no cursor-based pagination for this endpoint.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user.
Returns:
Successful response
893 async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 894 """ 895 Mark a thread as read 896 Records that a user has read up to a specific message in the thread. Unread 897 indicators and badge counts are cleared up to the specified message. 898 You must supply exactly one of `last_read_message` or `use_latest_message`. 899 Omitting both returns 400. If `use_latest_message` is `true` and the thread 900 has no messages, the request succeeds silently with no state change. 901 For server-to-server (S2S) requests where no user identity is present in the 902 token, the `user` param is required to identify whose read state to update. 903 904 Args: 905 thread: Thread ID (`thr_...`). The thread to mark as read. 906 input: Request body. 907 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 908 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 909 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 910 911 Returns: 912 Empty response on success. 913 """ 914 await self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input)
Mark a thread as read
Records that a user has read up to a specific message in the thread. Unread
indicators and badge counts are cleared up to the specified message.
You must supply exactly one of last_read_message or use_latest_message.
Omitting both returns 400. If use_latest_message is true and the thread
has no messages, the request succeeds silently with no state change.
For server-to-server (S2S) requests where no user identity is present in the
token, the user param is required to identify whose read state to update.
Arguments:
- thread: Thread ID (
thr_...). The thread to mark as read. - input: Request body.
- input.last_read_message: Message ID (
msg_...) to record as the last read message. Mutually exclusive withuse_latest_message. - input.use_latest_message: When
true, marks the thread as read up to the latest message. Mutually exclusive withlast_read_message. - input.user: User ID (
usr_...) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
Returns:
Empty response on success.
916 async def messages( 917 self, 918 thread: str, 919 *, 920 before_cursor: str | None = None, 921 after_cursor: str | None = None, 922 limit: int | None = None, 923 anchor: str | None = None, 924 direction: Literal["before", "after", "around"] | None = None, 925 before_limit: int | None = None, 926 after_limit: int | None = None, 927 include_anchor: bool | None = None, 928 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 929 anchor_agent: str | None = None, 930 include_reply_counts: bool | None = None, 931 ) -> ThreadMessagesResponse: 932 """ 933 List messages in a thread 934 Returns a cursor-paginated list of messages belonging to the specified thread, 935 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 936 to page through or bound the result set; omit both to receive the most recent page. 937 Supply `anchor` and `direction` to fetch a window before, after, or around a 938 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 939 resolve the anchor from the latest embedded-agent message, and add 940 `anchor_agent` to scope that resolution to a single sender agent. 941 The authenticated user must have access to the thread's owner (workspace or user). 942 A 403 is returned if the thread exists but is not accessible to the caller; a 404 943 is returned if the thread does not exist or is not visible to the authenticated user. 944 Pass `include_reply_counts: true` to annotate each message with the number of 945 threaded replies it has received. This adds a small amount of latency and should 946 be omitted when reply counts are not needed. 947 948 Args: 949 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 950 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 951 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 952 limit: Maximum number of messages to return per page. Defaults to 20. 953 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 954 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 955 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20. 956 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20. 957 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 958 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 959 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 960 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 961 962 Returns: 963 Successful response 964 """ 965 query: dict[str, object] = {} 966 if before_cursor is not None: 967 query["before_cursor"] = before_cursor 968 if after_cursor is not None: 969 query["after_cursor"] = after_cursor 970 if limit is not None: 971 query["limit"] = limit 972 if anchor is not None: 973 query["anchor"] = anchor 974 if direction is not None: 975 query["direction"] = direction 976 if before_limit is not None: 977 query["before_limit"] = before_limit 978 if after_limit is not None: 979 query["after_limit"] = after_limit 980 if include_anchor is not None: 981 query["include_anchor"] = include_anchor 982 if anchor_agent_mode is not None: 983 query["anchor_agent_mode"] = anchor_agent_mode 984 if anchor_agent is not None: 985 query["anchor_agent"] = anchor_agent 986 if include_reply_counts is not None: 987 query["include_reply_counts"] = include_reply_counts 988 return await self._http.request( 989 f"/api/v1/threads/{thread}/messages", 990 query=query, 991 response_type=ThreadMessagesResponse, 992 )
List messages in a thread
Returns a cursor-paginated list of messages belonging to the specified thread,
ordered from oldest to newest. Supply before_cursor, after_cursor, or both
to page through or bound the result set; omit both to receive the most recent page.
Supply anchor and direction to fetch a window before, after, or around a
specific message. Use anchor=last_matching&anchor_agent_mode=embedded to
resolve the anchor from the latest embedded-agent message, and add
anchor_agent to scope that resolution to a single sender agent.
The authenticated user must have access to the thread's owner (workspace or user).
A 403 is returned if the thread exists but is not accessible to the caller; a 404
is returned if the thread does not exist or is not visible to the authenticated user.
Pass include_reply_counts: true to annotate each message with the number of
threaded replies it has received. This adds a small amount of latency and should
be omitted when reply counts are not needed.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have access to this thread. - before_cursor: Opaque cursor returned in a previous response's
before_cursorfield. When provided, returns messages immediately before that position. May be combined withafter_cursorto bound a range. - after_cursor: Opaque cursor returned in a previous response's
after_cursorfield. When provided, returns messages immediately after that position. May be combined withbefore_cursorto bound a range. - limit: Maximum number of messages to return per page. Defaults to 20.
- anchor: Message ID (
msg_...) to use as a window anchor, orlast_matchingto resolve the anchor from the latest message matching the anchor filters. Cannot be combined withbefore_cursororafter_cursor. - direction: Window direction relative to
anchor.beforereturns older messages,afterreturns newer messages, andaroundreturns messages on both sides. Defaults toafterwhenanchoris supplied.direction=aroundcannot be combined with an explicitlimit; usebefore_limitandafter_limit. - before_limit: For
direction=around, maximum number of messages older than the anchor. Defaults to 20. - after_limit: For
direction=around, maximum number of messages newer than the anchor. Defaults to 20. - include_anchor: Whether to include the anchor message in a window response. Defaults to
truefordirection=around; ignored for ordinary cursor pagination and one-sided windows. - anchor_agent_mode: When
anchor=last_matching, resolve the anchor from the latest message with this local agent execution mode. - anchor_agent: When
anchor=last_matching, scope the anchor resolution to messages sent by this agent (agi_...). Combine withanchor_agent_modeto resolve the latest message from a specific agent in a given mode. - include_reply_counts: When
true, each message in the response is annotated with its threaded reply count. Defaults tofalse. Adds latency; omit when reply counts are not needed.
Returns:
Successful response
994 async def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 995 """ 996 Update a thread's profile picture 997 Uploads a new profile picture for the specified thread and returns the updated 998 thread object. The image must be supplied as a base64-encoded string with its 999 MIME type. 1000 The authenticated user must own the thread or be a team owner of the workspace 1001 the thread belongs to. Supplying invalid base64 data returns 422. 1002 1003 Args: 1004 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1005 input: Request body. 1006 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1007 1008 Returns: 1009 The thread object after the profile picture has been updated. 1010 """ 1011 return await self._http.request( 1012 f"/api/v1/threads/{thread}/picture", 1013 method="PUT", 1014 body=input, 1015 response_type=Thread, 1016 )
Update a thread's profile picture Uploads a new profile picture for the specified thread and returns the updated thread object. The image must be supplied as a base64-encoded string with its MIME type. The authenticated user must own the thread or be a team owner of the workspace the thread belongs to. Supplying invalid base64 data returns 422.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have permission to update this thread. - input: Request body.
- input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
Returns:
The thread object after the profile picture has been updated.
1018 async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1019 """ 1020 Retrieve a thread's read status 1021 Returns the read status of a thread for the specified user, including the ID 1022 of the last message they have read and the number of unread messages remaining. 1023 For user-authenticated requests, the status is always returned for the 1024 authenticated user and the `user` parameter is ignored. For server-to-server 1025 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1026 Returns 404 if the thread does not exist or the caller does not have access 1027 to it. 1028 1029 Args: 1030 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1031 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1032 1033 Returns: 1034 The read status record for the requested thread and user. 1035 """ 1036 query: dict[str, object] = {} 1037 if user is not None: 1038 query["user"] = user 1039 return await self._http.request( 1040 f"/api/v1/threads/{thread}/read_status", 1041 query=query, 1042 response_type=ThreadReadStatus, 1043 )
Retrieve a thread's read status
Returns the read status of a thread for the specified user, including the ID
of the last message they have read and the number of unread messages remaining.
For user-authenticated requests, the status is always returned for the
authenticated user and the user parameter is ignored. For server-to-server
(S2S) requests, the user parameter is required and must be a valid user ID.
Returns 404 if the thread does not exist or the caller does not have access
to it.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user or, for S2S requests, to the specified user. - user: User ID (
usr_...) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user.
Returns:
The read status record for the requested thread and user.
1045 async def search(self, thread: str, q: str, *, type: str | None = None) -> ThreadSearchResponse: 1046 """ 1047 Search context items within a thread 1048 Performs a full-text search over context items (messages, files, and other 1049 indexed sources) attached to the specified thread. Returns tagged objects 1050 whose content matches the query string. 1051 Use the `type` param to restrict results to a particular context source. All 1052 accessible context source types are searched when `type` is omitted. The 1053 authenticated user must have access to the thread. 1054 1055 Args: 1056 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1057 q: Full-text search query. Results are ranked by relevance to this string. 1058 type: Context source type to restrict the search to, e.g. `"thread/messages"`. Omit to search across all context sources for the thread. 1059 1060 Returns: 1061 Successful response 1062 """ 1063 query: dict[str, object] = {} 1064 query["q"] = q 1065 if type is not None: 1066 query["type"] = type 1067 return await self._http.request( 1068 f"/api/v1/threads/{thread}/search", 1069 query=query, 1070 response_type=ThreadSearchResponse, 1071 )
Search context items within a thread
Performs a full-text search over context items (messages, files, and other
indexed sources) attached to the specified thread. Returns tagged objects
whose content matches the query string.
Use the type param to restrict results to a particular context source. All
accessible context source types are searched when type is omitted. The
authenticated user must have access to the thread.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user. - q: Full-text search query. Results are ranked by relevance to this string.
- type: Context source type to restrict the search to, e.g.
"thread/messages". Omit to search across all context sources for the thread.
Returns:
Successful response
1074class ThreadMemberResource: 1075 def __init__(self, http: SyncHttpClient): 1076 self._http = http 1077 1078 def remove(self, thread: str) -> None: 1079 """ 1080 Remove a member from a thread 1081 Removes a user or agent membership from the specified thread. The authenticated 1082 user must have access to the thread. A successful removal returns HTTP 204 with 1083 no response body. 1084 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1085 if the thread or the membership record does not exist. 1086 1087 Args: 1088 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1089 1090 Returns: 1091 Empty response body. HTTP 204 on success. 1092 """ 1093 self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE") 1094 1095 def list(self, thread: str) -> ThreadMemberListResponse: 1096 """ 1097 List members of a thread 1098 Returns all current members of the specified thread, including both user and 1099 agent members. The authenticated user must have visibility into the thread; 1100 requests from users without access return 403. 1101 Results are returned as a flat array in the `data` field. The list is not 1102 paginated all members are returned in a single response. 1103 1104 Args: 1105 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1106 1107 Returns: 1108 Successful response 1109 """ 1110 return self._http.request( 1111 f"/api/v1/threads/{thread}/members", 1112 response_type=ThreadMemberListResponse, 1113 ) 1114 1115 def create(self, thread: str, input: ThreadMemberCreateInput) -> ThreadMember: 1116 """ 1117 Add a member to a thread 1118 Adds a user or agent as a member of the specified thread. The authenticated 1119 user must have access to the thread. On success the new membership record is 1120 returned with HTTP 201. 1121 Supply either `user` or `agent` depending on the value of `type`. Attempting 1122 to add a principal that is already a member of the thread returns a 422 error. 1123 1124 Args: 1125 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1126 input: Request body. 1127 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1128 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1129 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1130 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1131 1132 Returns: 1133 The newly created thread membership record. 1134 """ 1135 return self._http.request( 1136 f"/api/v1/threads/{thread}/members", 1137 method="POST", 1138 body=input, 1139 response_type=ThreadMember, 1140 )
1078 def remove(self, thread: str) -> None: 1079 """ 1080 Remove a member from a thread 1081 Removes a user or agent membership from the specified thread. The authenticated 1082 user must have access to the thread. A successful removal returns HTTP 204 with 1083 no response body. 1084 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1085 if the thread or the membership record does not exist. 1086 1087 Args: 1088 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1089 1090 Returns: 1091 Empty response body. HTTP 204 on success. 1092 """ 1093 self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")
Remove a member from a thread
Removes a user or agent membership from the specified thread. The authenticated
user must have access to the thread. A successful removal returns HTTP 204 with
no response body.
Supply either user or agent depending on the value of type. Returns 404
if the thread or the membership record does not exist.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from.
Returns:
Empty response body. HTTP 204 on success.
1095 def list(self, thread: str) -> ThreadMemberListResponse: 1096 """ 1097 List members of a thread 1098 Returns all current members of the specified thread, including both user and 1099 agent members. The authenticated user must have visibility into the thread; 1100 requests from users without access return 403. 1101 Results are returned as a flat array in the `data` field. The list is not 1102 paginated all members are returned in a single response. 1103 1104 Args: 1105 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1106 1107 Returns: 1108 Successful response 1109 """ 1110 return self._http.request( 1111 f"/api/v1/threads/{thread}/members", 1112 response_type=ThreadMemberListResponse, 1113 )
List members of a thread
Returns all current members of the specified thread, including both user and
agent members. The authenticated user must have visibility into the thread;
requests from users without access return 403.
Results are returned as a flat array in the data field. The list is not
paginated all members are returned in a single response.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from.
Returns:
Successful response
1115 def create(self, thread: str, input: ThreadMemberCreateInput) -> ThreadMember: 1116 """ 1117 Add a member to a thread 1118 Adds a user or agent as a member of the specified thread. The authenticated 1119 user must have access to the thread. On success the new membership record is 1120 returned with HTTP 201. 1121 Supply either `user` or `agent` depending on the value of `type`. Attempting 1122 to add a principal that is already a member of the thread returns a 422 error. 1123 1124 Args: 1125 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1126 input: Request body. 1127 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1128 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1129 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1130 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1131 1132 Returns: 1133 The newly created thread membership record. 1134 """ 1135 return self._http.request( 1136 f"/api/v1/threads/{thread}/members", 1137 method="POST", 1138 body=input, 1139 response_type=ThreadMember, 1140 )
Add a member to a thread
Adds a user or agent as a member of the specified thread. The authenticated
user must have access to the thread. On success the new membership record is
returned with HTTP 201.
Supply either user or agent depending on the value of type. Attempting
to add a principal that is already a member of the thread returns a 422 error.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from. - input: Request body.
- input.agent: Agent ID of the principal to add. Required when
typeis"agent". - input.membership_type: Role granted to the new member. One of
"owner"or"member". Defaults to"member". - input.type: Kind of principal being added. Must be
"user"or"agent". - input.user: User ID of the principal to add. Required when
typeis"user".
Returns:
The newly created thread membership record.
1143class SettingResource: 1144 def __init__(self, http: SyncHttpClient): 1145 self._http = http 1146 1147 def list(self, thread: str) -> SettingListResponse: 1148 """ 1149 Retrieve thread settings 1150 Returns the current settings for the specified thread. Settings control 1151 per-thread behavior such as whether the AI agent is enabled. 1152 The authenticated user must own the thread or be a member of its workspace. 1153 If settings have never been explicitly configured, defaults are returned 1154 (for example, `agent_enabled` defaults to `true`). 1155 1156 Args: 1157 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1158 1159 Returns: 1160 Successful response 1161 """ 1162 return self._http.request( 1163 f"/api/v1/threads/{thread}/settings", 1164 response_type=SettingListResponse, 1165 ) 1166 1167 def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1168 """ 1169 Update thread settings 1170 Updates the settings for the specified thread. Only fields included in 1171 the `settings` map are modified; omitted fields retain their current values. 1172 The authenticated user must own the thread or be a member of its workspace. 1173 Returns the full settings object reflecting the state after the update. 1174 Validation errors are returned as `422 Unprocessable Entity`. 1175 1176 Args: 1177 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1178 input: Request body. 1179 input.settings: Map of settings fields to update. Include only the keys you want to change. 1180 1181 Returns: 1182 The thread settings object after the update has been applied. 1183 """ 1184 return self._http.request( 1185 f"/api/v1/threads/{thread}/settings", 1186 method="PUT", 1187 body=input, 1188 response_type=ThreadSettings, 1189 )
1147 def list(self, thread: str) -> SettingListResponse: 1148 """ 1149 Retrieve thread settings 1150 Returns the current settings for the specified thread. Settings control 1151 per-thread behavior such as whether the AI agent is enabled. 1152 The authenticated user must own the thread or be a member of its workspace. 1153 If settings have never been explicitly configured, defaults are returned 1154 (for example, `agent_enabled` defaults to `true`). 1155 1156 Args: 1157 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1158 1159 Returns: 1160 Successful response 1161 """ 1162 return self._http.request( 1163 f"/api/v1/threads/{thread}/settings", 1164 response_type=SettingListResponse, 1165 )
Retrieve thread settings
Returns the current settings for the specified thread. Settings control
per-thread behavior such as whether the AI agent is enabled.
The authenticated user must own the thread or be a member of its workspace.
If settings have never been explicitly configured, defaults are returned
(for example, agent_enabled defaults to true).
Arguments:
- thread: Thread ID (
thr_...). Must belong to the authenticated user's workspace.
Returns:
Successful response
1167 def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1168 """ 1169 Update thread settings 1170 Updates the settings for the specified thread. Only fields included in 1171 the `settings` map are modified; omitted fields retain their current values. 1172 The authenticated user must own the thread or be a member of its workspace. 1173 Returns the full settings object reflecting the state after the update. 1174 Validation errors are returned as `422 Unprocessable Entity`. 1175 1176 Args: 1177 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1178 input: Request body. 1179 input.settings: Map of settings fields to update. Include only the keys you want to change. 1180 1181 Returns: 1182 The thread settings object after the update has been applied. 1183 """ 1184 return self._http.request( 1185 f"/api/v1/threads/{thread}/settings", 1186 method="PUT", 1187 body=input, 1188 response_type=ThreadSettings, 1189 )
Update thread settings
Updates the settings for the specified thread. Only fields included in
the settings map are modified; omitted fields retain their current values.
The authenticated user must own the thread or be a member of its workspace.
Returns the full settings object reflecting the state after the update.
Validation errors are returned as 422 Unprocessable Entity.
Arguments:
- thread: Thread ID (
thr_...). Must belong to the authenticated user's workspace. - input: Request body.
- input.settings: Map of settings fields to update. Include only the keys you want to change.
Returns:
The thread settings object after the update has been applied.
1192class ThreadResource: 1193 def __init__(self, http: SyncHttpClient): 1194 self._http = http 1195 self.members = ThreadMemberResource(http) 1196 self.settings = SettingResource(http) 1197 1198 def delete(self, thread: str) -> None: 1199 """ 1200 Delete a thread 1201 Permanently deletes a thread and all of its messages and artifacts. This action 1202 cannot be undone. 1203 The authenticated user must own the thread or be an owner of the team the thread 1204 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1205 1206 Args: 1207 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1208 1209 Returns: 1210 Empty response on successful deletion. 1211 """ 1212 self._http.request(f"/api/v1/threads/{thread}", method="DELETE") 1213 1214 def get(self, thread: str) -> Thread: 1215 """ 1216 Retrieve a thread 1217 Returns the full thread record for the given thread ID. The authenticated user 1218 must own the thread or be a member of the workspace it belongs to. 1219 Use this endpoint to fetch the current state of a single thread, including its 1220 title, description, and metadata. To list many threads, use the list endpoint 1221 with cursor-based pagination. 1222 1223 Args: 1224 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1225 1226 Returns: 1227 The requested thread object. 1228 """ 1229 return self._http.request(f"/api/v1/threads/{thread}", response_type=Thread) 1230 1231 def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1232 """ 1233 Update a thread 1234 Updates one or more mutable properties of the specified thread and returns 1235 the full thread object with the applied changes. Only the fields you provide 1236 are modified; omitted fields retain their current values. 1237 If `profile_picture` is supplied, the image is uploaded before the other 1238 fields are saved. Supplying invalid base64 picture data returns 422 and no 1239 other fields are updated. 1240 The authenticated user must own the thread or be a team owner of the workspace 1241 the thread belongs to. 1242 1243 Args: 1244 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1245 input: Request body. 1246 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1247 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1248 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1249 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1250 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1251 1252 Returns: 1253 The thread object after the update has been applied. 1254 """ 1255 return self._http.request( 1256 f"/api/v1/threads/{thread}", 1257 method="PUT", 1258 body=input, 1259 response_type=Thread, 1260 ) 1261 1262 def agents(self, thread: str) -> ThreadAgentsResponse: 1263 """ 1264 List agents in a thread 1265 Returns the agents participating in the specified thread. Only personal user 1266 threads (threads owned by a single user, not a team) expose agents through 1267 this endpoint; requests for team threads return 404. 1268 The authenticated user must have visibility into the thread. Each agent entry 1269 includes display information such as name and profile picture. Thread-level 1270 overrides (e.g. a custom name or profile picture set for this thread) take 1271 precedence over the agent's default values. When the caller is the thread 1272 owner, each entry also includes an `agent_config` object describing the 1273 agent's message policy and context configuration. 1274 1275 Args: 1276 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1277 1278 Returns: 1279 Successful response 1280 """ 1281 return self._http.request( 1282 f"/api/v1/threads/{thread}/agents", 1283 response_type=ThreadAgentsResponse, 1284 ) 1285 1286 def artifacts(self, thread: str) -> ThreadArtifactsResponse: 1287 """ 1288 List artifacts for a thread 1289 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1290 structured outputs such as code files, documents, or generated assets created 1291 by the AI agent in response to messages in the thread. 1292 The authenticated user must have access to the specified thread. Results are 1293 returned in a single page; there is no cursor-based pagination for this endpoint. 1294 1295 Args: 1296 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1297 1298 Returns: 1299 Successful response 1300 """ 1301 return self._http.request( 1302 f"/api/v1/threads/{thread}/artifacts", 1303 response_type=ThreadArtifactsResponse, 1304 ) 1305 1306 def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 1307 """ 1308 Mark a thread as read 1309 Records that a user has read up to a specific message in the thread. Unread 1310 indicators and badge counts are cleared up to the specified message. 1311 You must supply exactly one of `last_read_message` or `use_latest_message`. 1312 Omitting both returns 400. If `use_latest_message` is `true` and the thread 1313 has no messages, the request succeeds silently with no state change. 1314 For server-to-server (S2S) requests where no user identity is present in the 1315 token, the `user` param is required to identify whose read state to update. 1316 1317 Args: 1318 thread: Thread ID (`thr_...`). The thread to mark as read. 1319 input: Request body. 1320 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 1321 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 1322 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 1323 1324 Returns: 1325 Empty response on success. 1326 """ 1327 self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input) 1328 1329 def messages( 1330 self, 1331 thread: str, 1332 *, 1333 before_cursor: str | None = None, 1334 after_cursor: str | None = None, 1335 limit: int | None = None, 1336 anchor: str | None = None, 1337 direction: Literal["before", "after", "around"] | None = None, 1338 before_limit: int | None = None, 1339 after_limit: int | None = None, 1340 include_anchor: bool | None = None, 1341 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 1342 anchor_agent: str | None = None, 1343 include_reply_counts: bool | None = None, 1344 ) -> ThreadMessagesResponse: 1345 """ 1346 List messages in a thread 1347 Returns a cursor-paginated list of messages belonging to the specified thread, 1348 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 1349 to page through or bound the result set; omit both to receive the most recent page. 1350 Supply `anchor` and `direction` to fetch a window before, after, or around a 1351 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 1352 resolve the anchor from the latest embedded-agent message, and add 1353 `anchor_agent` to scope that resolution to a single sender agent. 1354 The authenticated user must have access to the thread's owner (workspace or user). 1355 A 403 is returned if the thread exists but is not accessible to the caller; a 404 1356 is returned if the thread does not exist or is not visible to the authenticated user. 1357 Pass `include_reply_counts: true` to annotate each message with the number of 1358 threaded replies it has received. This adds a small amount of latency and should 1359 be omitted when reply counts are not needed. 1360 1361 Args: 1362 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1363 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 1364 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 1365 limit: Maximum number of messages to return per page. Defaults to 20. 1366 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 1367 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 1368 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20. 1369 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20. 1370 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 1371 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 1372 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 1373 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 1374 1375 Returns: 1376 Successful response 1377 """ 1378 query: dict[str, object] = {} 1379 if before_cursor is not None: 1380 query["before_cursor"] = before_cursor 1381 if after_cursor is not None: 1382 query["after_cursor"] = after_cursor 1383 if limit is not None: 1384 query["limit"] = limit 1385 if anchor is not None: 1386 query["anchor"] = anchor 1387 if direction is not None: 1388 query["direction"] = direction 1389 if before_limit is not None: 1390 query["before_limit"] = before_limit 1391 if after_limit is not None: 1392 query["after_limit"] = after_limit 1393 if include_anchor is not None: 1394 query["include_anchor"] = include_anchor 1395 if anchor_agent_mode is not None: 1396 query["anchor_agent_mode"] = anchor_agent_mode 1397 if anchor_agent is not None: 1398 query["anchor_agent"] = anchor_agent 1399 if include_reply_counts is not None: 1400 query["include_reply_counts"] = include_reply_counts 1401 return self._http.request( 1402 f"/api/v1/threads/{thread}/messages", 1403 query=query, 1404 response_type=ThreadMessagesResponse, 1405 ) 1406 1407 def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 1408 """ 1409 Update a thread's profile picture 1410 Uploads a new profile picture for the specified thread and returns the updated 1411 thread object. The image must be supplied as a base64-encoded string with its 1412 MIME type. 1413 The authenticated user must own the thread or be a team owner of the workspace 1414 the thread belongs to. Supplying invalid base64 data returns 422. 1415 1416 Args: 1417 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1418 input: Request body. 1419 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1420 1421 Returns: 1422 The thread object after the profile picture has been updated. 1423 """ 1424 return self._http.request( 1425 f"/api/v1/threads/{thread}/picture", 1426 method="PUT", 1427 body=input, 1428 response_type=Thread, 1429 ) 1430 1431 def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1432 """ 1433 Retrieve a thread's read status 1434 Returns the read status of a thread for the specified user, including the ID 1435 of the last message they have read and the number of unread messages remaining. 1436 For user-authenticated requests, the status is always returned for the 1437 authenticated user and the `user` parameter is ignored. For server-to-server 1438 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1439 Returns 404 if the thread does not exist or the caller does not have access 1440 to it. 1441 1442 Args: 1443 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1444 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1445 1446 Returns: 1447 The read status record for the requested thread and user. 1448 """ 1449 query: dict[str, object] = {} 1450 if user is not None: 1451 query["user"] = user 1452 return self._http.request( 1453 f"/api/v1/threads/{thread}/read_status", 1454 query=query, 1455 response_type=ThreadReadStatus, 1456 ) 1457 1458 def search(self, thread: str, q: str, *, type: str | None = None) -> ThreadSearchResponse: 1459 """ 1460 Search context items within a thread 1461 Performs a full-text search over context items (messages, files, and other 1462 indexed sources) attached to the specified thread. Returns tagged objects 1463 whose content matches the query string. 1464 Use the `type` param to restrict results to a particular context source. All 1465 accessible context source types are searched when `type` is omitted. The 1466 authenticated user must have access to the thread. 1467 1468 Args: 1469 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1470 q: Full-text search query. Results are ranked by relevance to this string. 1471 type: Context source type to restrict the search to, e.g. `"thread/messages"`. Omit to search across all context sources for the thread. 1472 1473 Returns: 1474 Successful response 1475 """ 1476 query: dict[str, object] = {} 1477 query["q"] = q 1478 if type is not None: 1479 query["type"] = type 1480 return self._http.request( 1481 f"/api/v1/threads/{thread}/search", 1482 query=query, 1483 response_type=ThreadSearchResponse, 1484 )
1198 def delete(self, thread: str) -> None: 1199 """ 1200 Delete a thread 1201 Permanently deletes a thread and all of its messages and artifacts. This action 1202 cannot be undone. 1203 The authenticated user must own the thread or be an owner of the team the thread 1204 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1205 1206 Args: 1207 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1208 1209 Returns: 1210 Empty response on successful deletion. 1211 """ 1212 self._http.request(f"/api/v1/threads/{thread}", method="DELETE")
Delete a thread Permanently deletes a thread and all of its messages and artifacts. This action cannot be undone. The authenticated user must own the thread or be an owner of the team the thread belongs to. Attempting to delete a thread owned by another user or team returns 403.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must own this thread.
Returns:
Empty response on successful deletion.
1214 def get(self, thread: str) -> Thread: 1215 """ 1216 Retrieve a thread 1217 Returns the full thread record for the given thread ID. The authenticated user 1218 must own the thread or be a member of the workspace it belongs to. 1219 Use this endpoint to fetch the current state of a single thread, including its 1220 title, description, and metadata. To list many threads, use the list endpoint 1221 with cursor-based pagination. 1222 1223 Args: 1224 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1225 1226 Returns: 1227 The requested thread object. 1228 """ 1229 return self._http.request(f"/api/v1/threads/{thread}", response_type=Thread)
Retrieve a thread Returns the full thread record for the given thread ID. The authenticated user must own the thread or be a member of the workspace it belongs to. Use this endpoint to fetch the current state of a single thread, including its title, description, and metadata. To list many threads, use the list endpoint with cursor-based pagination.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have access to this thread.
Returns:
The requested thread object.
1231 def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1232 """ 1233 Update a thread 1234 Updates one or more mutable properties of the specified thread and returns 1235 the full thread object with the applied changes. Only the fields you provide 1236 are modified; omitted fields retain their current values. 1237 If `profile_picture` is supplied, the image is uploaded before the other 1238 fields are saved. Supplying invalid base64 picture data returns 422 and no 1239 other fields are updated. 1240 The authenticated user must own the thread or be a team owner of the workspace 1241 the thread belongs to. 1242 1243 Args: 1244 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1245 input: Request body. 1246 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1247 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1248 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1249 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1250 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1251 1252 Returns: 1253 The thread object after the update has been applied. 1254 """ 1255 return self._http.request( 1256 f"/api/v1/threads/{thread}", 1257 method="PUT", 1258 body=input, 1259 response_type=Thread, 1260 )
Update a thread
Updates one or more mutable properties of the specified thread and returns
the full thread object with the applied changes. Only the fields you provide
are modified; omitted fields retain their current values.
If profile_picture is supplied, the image is uploaded before the other
fields are saved. Supplying invalid base64 picture data returns 422 and no
other fields are updated.
The authenticated user must own the thread or be a team owner of the workspace
the thread belongs to.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have permission to update this thread. - input: Request body.
- input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
- input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
- input.muted: When
true, suppresses notifications for new messages in this thread for the authenticated user. - input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
- input.title: Human-readable display name for the thread. Replaces the existing title when provided.
Returns:
The thread object after the update has been applied.
1262 def agents(self, thread: str) -> ThreadAgentsResponse: 1263 """ 1264 List agents in a thread 1265 Returns the agents participating in the specified thread. Only personal user 1266 threads (threads owned by a single user, not a team) expose agents through 1267 this endpoint; requests for team threads return 404. 1268 The authenticated user must have visibility into the thread. Each agent entry 1269 includes display information such as name and profile picture. Thread-level 1270 overrides (e.g. a custom name or profile picture set for this thread) take 1271 precedence over the agent's default values. When the caller is the thread 1272 owner, each entry also includes an `agent_config` object describing the 1273 agent's message policy and context configuration. 1274 1275 Args: 1276 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1277 1278 Returns: 1279 Successful response 1280 """ 1281 return self._http.request( 1282 f"/api/v1/threads/{thread}/agents", 1283 response_type=ThreadAgentsResponse, 1284 )
List agents in a thread
Returns the agents participating in the specified thread. Only personal user
threads (threads owned by a single user, not a team) expose agents through
this endpoint; requests for team threads return 404.
The authenticated user must have visibility into the thread. Each agent entry
includes display information such as name and profile picture. Thread-level
overrides (e.g. a custom name or profile picture set for this thread) take
precedence over the agent's default values. When the caller is the thread
owner, each entry also includes an agent_config object describing the
agent's message policy and context configuration.
Arguments:
- thread: Thread ID (
thr_...). Must be a personal user thread visible to the authenticated user.
Returns:
Successful response
1286 def artifacts(self, thread: str) -> ThreadArtifactsResponse: 1287 """ 1288 List artifacts for a thread 1289 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1290 structured outputs such as code files, documents, or generated assets created 1291 by the AI agent in response to messages in the thread. 1292 The authenticated user must have access to the specified thread. Results are 1293 returned in a single page; there is no cursor-based pagination for this endpoint. 1294 1295 Args: 1296 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1297 1298 Returns: 1299 Successful response 1300 """ 1301 return self._http.request( 1302 f"/api/v1/threads/{thread}/artifacts", 1303 response_type=ThreadArtifactsResponse, 1304 )
List artifacts for a thread Returns all artifacts produced during a thread's AI conversation. Artifacts are structured outputs such as code files, documents, or generated assets created by the AI agent in response to messages in the thread. The authenticated user must have access to the specified thread. Results are returned in a single page; there is no cursor-based pagination for this endpoint.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user.
Returns:
Successful response
1306 def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 1307 """ 1308 Mark a thread as read 1309 Records that a user has read up to a specific message in the thread. Unread 1310 indicators and badge counts are cleared up to the specified message. 1311 You must supply exactly one of `last_read_message` or `use_latest_message`. 1312 Omitting both returns 400. If `use_latest_message` is `true` and the thread 1313 has no messages, the request succeeds silently with no state change. 1314 For server-to-server (S2S) requests where no user identity is present in the 1315 token, the `user` param is required to identify whose read state to update. 1316 1317 Args: 1318 thread: Thread ID (`thr_...`). The thread to mark as read. 1319 input: Request body. 1320 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 1321 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 1322 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 1323 1324 Returns: 1325 Empty response on success. 1326 """ 1327 self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input)
Mark a thread as read
Records that a user has read up to a specific message in the thread. Unread
indicators and badge counts are cleared up to the specified message.
You must supply exactly one of last_read_message or use_latest_message.
Omitting both returns 400. If use_latest_message is true and the thread
has no messages, the request succeeds silently with no state change.
For server-to-server (S2S) requests where no user identity is present in the
token, the user param is required to identify whose read state to update.
Arguments:
- thread: Thread ID (
thr_...). The thread to mark as read. - input: Request body.
- input.last_read_message: Message ID (
msg_...) to record as the last read message. Mutually exclusive withuse_latest_message. - input.use_latest_message: When
true, marks the thread as read up to the latest message. Mutually exclusive withlast_read_message. - input.user: User ID (
usr_...) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
Returns:
Empty response on success.
1329 def messages( 1330 self, 1331 thread: str, 1332 *, 1333 before_cursor: str | None = None, 1334 after_cursor: str | None = None, 1335 limit: int | None = None, 1336 anchor: str | None = None, 1337 direction: Literal["before", "after", "around"] | None = None, 1338 before_limit: int | None = None, 1339 after_limit: int | None = None, 1340 include_anchor: bool | None = None, 1341 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 1342 anchor_agent: str | None = None, 1343 include_reply_counts: bool | None = None, 1344 ) -> ThreadMessagesResponse: 1345 """ 1346 List messages in a thread 1347 Returns a cursor-paginated list of messages belonging to the specified thread, 1348 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 1349 to page through or bound the result set; omit both to receive the most recent page. 1350 Supply `anchor` and `direction` to fetch a window before, after, or around a 1351 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 1352 resolve the anchor from the latest embedded-agent message, and add 1353 `anchor_agent` to scope that resolution to a single sender agent. 1354 The authenticated user must have access to the thread's owner (workspace or user). 1355 A 403 is returned if the thread exists but is not accessible to the caller; a 404 1356 is returned if the thread does not exist or is not visible to the authenticated user. 1357 Pass `include_reply_counts: true` to annotate each message with the number of 1358 threaded replies it has received. This adds a small amount of latency and should 1359 be omitted when reply counts are not needed. 1360 1361 Args: 1362 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1363 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 1364 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 1365 limit: Maximum number of messages to return per page. Defaults to 20. 1366 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 1367 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 1368 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20. 1369 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20. 1370 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 1371 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 1372 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 1373 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 1374 1375 Returns: 1376 Successful response 1377 """ 1378 query: dict[str, object] = {} 1379 if before_cursor is not None: 1380 query["before_cursor"] = before_cursor 1381 if after_cursor is not None: 1382 query["after_cursor"] = after_cursor 1383 if limit is not None: 1384 query["limit"] = limit 1385 if anchor is not None: 1386 query["anchor"] = anchor 1387 if direction is not None: 1388 query["direction"] = direction 1389 if before_limit is not None: 1390 query["before_limit"] = before_limit 1391 if after_limit is not None: 1392 query["after_limit"] = after_limit 1393 if include_anchor is not None: 1394 query["include_anchor"] = include_anchor 1395 if anchor_agent_mode is not None: 1396 query["anchor_agent_mode"] = anchor_agent_mode 1397 if anchor_agent is not None: 1398 query["anchor_agent"] = anchor_agent 1399 if include_reply_counts is not None: 1400 query["include_reply_counts"] = include_reply_counts 1401 return self._http.request( 1402 f"/api/v1/threads/{thread}/messages", 1403 query=query, 1404 response_type=ThreadMessagesResponse, 1405 )
List messages in a thread
Returns a cursor-paginated list of messages belonging to the specified thread,
ordered from oldest to newest. Supply before_cursor, after_cursor, or both
to page through or bound the result set; omit both to receive the most recent page.
Supply anchor and direction to fetch a window before, after, or around a
specific message. Use anchor=last_matching&anchor_agent_mode=embedded to
resolve the anchor from the latest embedded-agent message, and add
anchor_agent to scope that resolution to a single sender agent.
The authenticated user must have access to the thread's owner (workspace or user).
A 403 is returned if the thread exists but is not accessible to the caller; a 404
is returned if the thread does not exist or is not visible to the authenticated user.
Pass include_reply_counts: true to annotate each message with the number of
threaded replies it has received. This adds a small amount of latency and should
be omitted when reply counts are not needed.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have access to this thread. - before_cursor: Opaque cursor returned in a previous response's
before_cursorfield. When provided, returns messages immediately before that position. May be combined withafter_cursorto bound a range. - after_cursor: Opaque cursor returned in a previous response's
after_cursorfield. When provided, returns messages immediately after that position. May be combined withbefore_cursorto bound a range. - limit: Maximum number of messages to return per page. Defaults to 20.
- anchor: Message ID (
msg_...) to use as a window anchor, orlast_matchingto resolve the anchor from the latest message matching the anchor filters. Cannot be combined withbefore_cursororafter_cursor. - direction: Window direction relative to
anchor.beforereturns older messages,afterreturns newer messages, andaroundreturns messages on both sides. Defaults toafterwhenanchoris supplied.direction=aroundcannot be combined with an explicitlimit; usebefore_limitandafter_limit. - before_limit: For
direction=around, maximum number of messages older than the anchor. Defaults to 20. - after_limit: For
direction=around, maximum number of messages newer than the anchor. Defaults to 20. - include_anchor: Whether to include the anchor message in a window response. Defaults to
truefordirection=around; ignored for ordinary cursor pagination and one-sided windows. - anchor_agent_mode: When
anchor=last_matching, resolve the anchor from the latest message with this local agent execution mode. - anchor_agent: When
anchor=last_matching, scope the anchor resolution to messages sent by this agent (agi_...). Combine withanchor_agent_modeto resolve the latest message from a specific agent in a given mode. - include_reply_counts: When
true, each message in the response is annotated with its threaded reply count. Defaults tofalse. Adds latency; omit when reply counts are not needed.
Returns:
Successful response
1407 def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 1408 """ 1409 Update a thread's profile picture 1410 Uploads a new profile picture for the specified thread and returns the updated 1411 thread object. The image must be supplied as a base64-encoded string with its 1412 MIME type. 1413 The authenticated user must own the thread or be a team owner of the workspace 1414 the thread belongs to. Supplying invalid base64 data returns 422. 1415 1416 Args: 1417 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1418 input: Request body. 1419 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1420 1421 Returns: 1422 The thread object after the profile picture has been updated. 1423 """ 1424 return self._http.request( 1425 f"/api/v1/threads/{thread}/picture", 1426 method="PUT", 1427 body=input, 1428 response_type=Thread, 1429 )
Update a thread's profile picture Uploads a new profile picture for the specified thread and returns the updated thread object. The image must be supplied as a base64-encoded string with its MIME type. The authenticated user must own the thread or be a team owner of the workspace the thread belongs to. Supplying invalid base64 data returns 422.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have permission to update this thread. - input: Request body.
- input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
Returns:
The thread object after the profile picture has been updated.
1431 def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1432 """ 1433 Retrieve a thread's read status 1434 Returns the read status of a thread for the specified user, including the ID 1435 of the last message they have read and the number of unread messages remaining. 1436 For user-authenticated requests, the status is always returned for the 1437 authenticated user and the `user` parameter is ignored. For server-to-server 1438 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1439 Returns 404 if the thread does not exist or the caller does not have access 1440 to it. 1441 1442 Args: 1443 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1444 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1445 1446 Returns: 1447 The read status record for the requested thread and user. 1448 """ 1449 query: dict[str, object] = {} 1450 if user is not None: 1451 query["user"] = user 1452 return self._http.request( 1453 f"/api/v1/threads/{thread}/read_status", 1454 query=query, 1455 response_type=ThreadReadStatus, 1456 )
Retrieve a thread's read status
Returns the read status of a thread for the specified user, including the ID
of the last message they have read and the number of unread messages remaining.
For user-authenticated requests, the status is always returned for the
authenticated user and the user parameter is ignored. For server-to-server
(S2S) requests, the user parameter is required and must be a valid user ID.
Returns 404 if the thread does not exist or the caller does not have access
to it.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user or, for S2S requests, to the specified user. - user: User ID (
usr_...) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user.
Returns:
The read status record for the requested thread and user.
1458 def search(self, thread: str, q: str, *, type: str | None = None) -> ThreadSearchResponse: 1459 """ 1460 Search context items within a thread 1461 Performs a full-text search over context items (messages, files, and other 1462 indexed sources) attached to the specified thread. Returns tagged objects 1463 whose content matches the query string. 1464 Use the `type` param to restrict results to a particular context source. All 1465 accessible context source types are searched when `type` is omitted. The 1466 authenticated user must have access to the thread. 1467 1468 Args: 1469 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1470 q: Full-text search query. Results are ranked by relevance to this string. 1471 type: Context source type to restrict the search to, e.g. `"thread/messages"`. Omit to search across all context sources for the thread. 1472 1473 Returns: 1474 Successful response 1475 """ 1476 query: dict[str, object] = {} 1477 query["q"] = q 1478 if type is not None: 1479 query["type"] = type 1480 return self._http.request( 1481 f"/api/v1/threads/{thread}/search", 1482 query=query, 1483 response_type=ThreadSearchResponse, 1484 )
Search context items within a thread
Performs a full-text search over context items (messages, files, and other
indexed sources) attached to the specified thread. Returns tagged objects
whose content matches the query string.
Use the type param to restrict results to a particular context source. All
accessible context source types are searched when type is omitted. The
authenticated user must have access to the thread.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user. - q: Full-text search query. Results are ranked by relevance to this string.
- type: Context source type to restrict the search to, e.g.
"thread/messages". Omit to search across all context sources for the thread.
Returns:
Successful response