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        )
class ThreadMemberCreateInput(typing.TypedDict):
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

agent: str | None

Agent ID of the principal to add. Required when type is "agent".

membership_type: str | None

Role granted to the new member. One of "owner" or "member". Defaults to "member".

type: Required[str]

Kind of principal being added. Must be "user" or "agent".

user: str | None

User ID of the principal to add. Required when type is "user".

class SettingReplaceInput(typing.TypedDict):
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

settings: dict[str, typing.Any]

Map of settings fields to update. Include only the keys you want to change.

class ThreadReplaceInputProfilePicture(typing.TypedDict):
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"`.'
data: str | None

Base64-encoded image payload. Must be a valid base64 string.

filename: str | None

Original filename of the image, e.g. "avatar.png". Used for storage metadata.

mime_type: str | None

MIME type of the image, e.g. "image/jpeg" or "image/png".

class ThreadReplaceInput(typing.TypedDict):
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

description: str | None

Optional longer text describing the thread's purpose. Replaces the existing description when provided.

metadata: dict[str, typing.Any] | None

Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.

muted: bool | None

When true, suppresses notifications for new messages in this thread for the authenticated user.

profile_picture: ThreadReplaceInputProfilePicture | None

New profile picture for the thread. Provide all three inner fields to replace the existing image.

title: str | None

Human-readable display name for the thread. Replaces the existing title when provided.

class ThreadMarkReadInput(typing.TypedDict):
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

last_read_message: str | None

Message ID (msg_...) to record as the last read message. Mutually exclusive with use_latest_message.

use_latest_message: bool | None

When true, marks the thread as read up to the latest message. Mutually exclusive with last_read_message.

user: str | None

User ID (usr_...) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.

class ThreadPictureInputPicture(typing.TypedDict):
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"`.'
data: str

Base64-encoded binary content of the image file.

filename: str

Original filename of the image, e.g. "avatar.png". Used for storage and display.

mime_type: str

MIME type of the image, e.g. "image/jpeg" or "image/png".

class ThreadPictureInput(typing.TypedDict):
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.

class ThreadMemberListResponseDataItemUser(pydantic.main.BaseModel):
 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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
alias: str | None = None

Short handle or alias for the user. null if not set.

app: str | None = None

ID of the app this user (and their access token) is scoped to (dap_...). null if the user is not scoped to an app.

app_name: str | None = None

Display name of the user's app. null when the app association was not preloaded by the caller.

email: str | None = None

Email address of the user.

id: str = PydanticUndefined

User ID (usr_...).

is_system_user: bool | None = None

true if this account is an internal system user rather than a human. System users are created automatically by the platform.

metadata: dict[str, typing.Any] | None = None

Arbitrary key-value metadata attached to the user. Defaults to an empty object.

name: str | None = None

Full display name of the user. null if the user has not set a name.

org: str | None = None

ID of the organization this user belongs to (org_...). null if the user is not a member of any organization.

org_name: str | None = None

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.

org_role: str | None = None

Role of the user within their organization. One of "admin", "member", or "viewer". null when the user is not a member of any organization.

sandbox: str | None = None

ID of the sandbox environment this user is scoped to (sbx_...). null for production users.

sandbox_name: str | None = None

Display name of the user's sandbox environment. null for production users, or when the sandbox association was not preloaded by the caller.

class ThreadMemberListResponseDataItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
membership_type: str | None = None

Role of the member within the thread. One of "owner" (the user who created or was granted ownership) or "member" (a regular participant).

thread: str | None = None

ID of the thread this membership belongs to (thr_...).

Full user object for the member (usr_...). Present when the association is preloaded; null otherwise.

class ThreadMemberListResponse(pydantic.main.BaseModel):
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

data: list[ThreadMemberListResponseDataItem] = PydanticUndefined

Array of thread member objects representing all current members of the thread.

class SettingListResponse(pydantic.main.BaseModel):
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

agent_enabled: bool | None = None

Whether the AI agent is active for this thread. Defaults to true when no settings have been explicitly set.

class ThreadAgentsResponse(pydantic.main.BaseModel):
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

data: list[dict[str, typing.Any]] = PydanticUndefined

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.

class ThreadArtifactsResponseDataItemImageSource(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
file: str | None = None

ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.

height: int | None = None

Height of the image in pixels. null if not known.

media: str | None = None

ID of the associated media record (med_...). null when the image is not linked to a media entity.

mime_type: str | None = None

MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.

refresh_url: str | None = None

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.

url: str | None = None

Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.

width: int | None = None

Width of the image in pixels. null if not known.

class ThreadArtifactsResponseDataItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
agent: str | None = None

ID of the agent that produced this artifact (agt_...). null if not agent-produced.

content_type: str | None = None

MIME type of the current version's file, e.g. "text/csv" or "image/png". null if no file is attached.

created_at: datetime.datetime | None = None

When the artifact was first created (ISO 8601).

current_version: str | None = None

ID of the current (latest published) artifact version (artv_...). null if no version has been published.

description: str | None = None

Optional longer description of the artifact's contents or purpose. null if not set.

file: str | None = None

Storage file ID for the current version (fil_...). null if no file is attached.

file_name: str | None = None

Original filename of the current version's file, e.g. "output.csv". null if no file is attached.

file_url: str | None = None

Short-lived signed URL for downloading the current version's file. null if no file is attached.

id: str = PydanticUndefined

Artifact ID (art_...).

image_source: ThreadArtifactsResponseDataItemImageSource | None = None

Image source metadata for rendering the current version's file inline. Present only when content_type starts with "image/". null otherwise.

name: str | None = None

Human-readable name for the artifact, e.g. "Q2 Report". null if not set.

org: str | None = None

ID of the organization this artifact belongs to (org_...).

sandbox: str | None = None

Identifier of the sandbox environment associated with this artifact. null if not sandbox-scoped.

team: str | None = None

ID of the team that owns this artifact (tea_...). null if not team-scoped.

thread: str | None = None

ID of the thread in which this artifact was created (thr_...). null if not thread-scoped.

updated_at: datetime.datetime | None = None

When the artifact record was last modified (ISO 8601).

user: str | None = None

ID of the user who created this artifact (usr_...). null if not user-scoped.

version: int | None = None

Current version number of the artifact. Increments each time a new version is published.

class ThreadArtifactsResponse(pydantic.main.BaseModel):
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

data: list[ThreadArtifactsResponseDataItem] = PydanticUndefined

Array of artifact objects produced during the thread's conversation.

class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
file: str | None = None

ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.

height: int | None = None

Height of the image in pixels. null if not known.

media: str | None = None

ID of the associated media record (med_...). null when the image is not linked to a media entity.

mime_type: str | None = None

MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.

refresh_url: str | None = None

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.

url: str | None = None

Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.

width: int | None = None

Width of the image in pixels. null if not known.

class ThreadMessagesResponseDataMessagesItemActorsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
alias: str | None = None

Short handle or alias for the actor, used as an alternate display identifier. null if not configured.

id: str | None = None

Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.

name: str | None = None

Display name of the actor shown in the UI. null if no name is set.

Profile picture for the actor. null if the actor has no profile picture.

class ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
file: str | None = None

ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.

height: int | None = None

Height of the image in pixels. null if not known.

media: str | None = None

ID of the associated media record (med_...). null when the image is not linked to a media entity.

mime_type: str | None = None

MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.

refresh_url: str | None = None

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.

url: str | None = None

Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.

width: int | None = None

Width of the image in pixels. null if not known.

class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
file: str | None = None

ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.

height: int | None = None

Height of the image in pixels. null if not known.

media: str | None = None

ID of the associated media record (med_...). null when the image is not linked to a media entity.

mime_type: str | None = None

MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.

refresh_url: str | None = None

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.

url: str | None = None

Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.

width: int | None = None

Width of the image in pixels. null if not known.

class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
content_type: str | None = None

MIME type of this variant's file (e.g., "image/jpeg", "video/mp4"). null if the file is not loaded.

created_at: datetime.datetime | None = None

When this variant was created (ISO 8601).

file: str | None = None

ID of the underlying storage file that backs this variant (fil_...).

filename: str | None = None

Original filename of the uploaded file for this variant. null if the file is not loaded.

height: int | None = None

Height of this variant in pixels. null if not recorded.

id: str = PydanticUndefined

Media variant ID (mvr_...).

Resolved image delivery metadata for this variant, including dimensions and CDN URL. null for non-image content types.

updated_at: datetime.datetime | None = None

When this variant was last updated (ISO 8601).

url: str | None = None

Signed download URL for this variant, resolved at request time. null if the file is unavailable.

variant_key: str | None = None

Identifier for this variant's processing tier. Common values include "original" (the unmodified upload) and "thumbnail" (a resized preview).

width: int | None = None

Width of this variant in pixels. null if not recorded.

class ThreadMessagesResponseDataMessagesItemAttachmentsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
content_type: str | None = None

MIME type of the attached file, e.g. "image/png" or "application/pdf". Present on file, artifact, and media types. null otherwise.

description: str | None = None

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.

filename: str | None = None

Original filename of the attached file, e.g. "report.pdf". Present on file, artifact, and media types. null otherwise.

height: int | None = None

Height in pixels of the media item. Present on media type only. null otherwise.

id: str = PydanticUndefined

Unique identifier for this attachment within the message.

image_height: int | None = None

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.

image_url: str | None = None

URL of the preview image extracted from the scraped page. Present on scraped_link type only. null otherwise.

image_width: int | None = None

Width in pixels of the scraped preview image. Present on scraped_link type only. null otherwise.

media_type: str | None = None

The media category, e.g. "video" or "audio". Present on media type only. null otherwise.

name: str | None = None

Display name of the media item. Present on media type only. null otherwise.

object: dict[str, typing.Any] | None = None

The full embedded object payload. For task type, contains the task record. For action type, contains the action definition. null on other types.

title: str | None = None

Display title. The page title for scraped_link, the artifact name for artifact, and the task title for task types. null on other types.

type: str = PydanticUndefined

The attachment type. One of "file", "scraped_link", "artifact", "task", "media", or "action". Determines which additional fields are present.

url: str | None = None

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.

version: int | None = None

Version number of the attached artifact at the time of attachment. Present on artifact type only. null otherwise.

width: int | None = None

Width in pixels of the media item. Present on media type only. null otherwise.

class ThreadMessagesResponseDataMessagesItemReactionsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
payload: dict[str, typing.Any] | None = None

Type-specific reaction data. For "emoji_reaction" reactions, contains an emoji key with the Unicode emoji string (e.g., " ").

type: str = PydanticUndefined

Reaction type identifier. Currently always "emoji_reaction" for emoji-based reactions.

user: str | None = None

Public ID of the user who added the reaction (usr_...).

class ThreadMessagesResponseDataMessagesItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.

agent: str | None = None

ID of the agent user that sent this message (agi_...). null for messages sent by human users.

agent_mode: Optional[Literal['cli', 'embedded']] = None

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.

branched_thread: str | None = None

ID of the thread that was branched from this message (thr_...). null if this message has not spawned a branch thread.

content: str | None = None

Text content of the message. null for messages that contain only attachments.

created_at: datetime.datetime | None = None

When the message was posted (ISO 8601).

has_replies: bool | None = None

Whether this message has at least one reply. Only present when explicitly requested or computed by the server.

id: str = PydanticUndefined

Message ID (msg_...).

idempotency_key: str | None = None

Client-supplied idempotency key used to deduplicate message sends. null if the sender did not provide one.

legacy_agent: str | None = None

Identifier of the legacy chat agent that sent this message, if applicable. null for messages sent by users or modern agent users.

metadata: dict[str, typing.Any] | None = None

Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.

org: str | None = None

ID of the organization that owns this message (org_...).

Emoji and other reactions added to this message by users. Empty array if no reactions have been added or the association is not preloaded.

rendering_mode: str | None = None

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.

replies: list[dict[str, typing.Any]] | None = None

Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.

replies_after_cursor: str | None = None

Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.

replies_before_cursor: str | None = None

Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.

reply_count: int | None = None

Total number of direct replies to this message. Only present when explicitly requested or computed by the server.

reply_to: dict[str, typing.Any] | None = None

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.

sandbox: str | None = None

ID of the developer sandbox this message belongs to (dsb_...). null for non-sandbox messages.

team: str | None = None

ID of the team this message is scoped to (tem_...). null if the message is not team-scoped.

thread: str | None = None

ID of the thread this message belongs to (thr_...). null for messages not yet associated with a thread.

user: str | None = None

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.

class ThreadMessagesResponseData(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
after_cursor: str | None = None

Opaque cursor to pass as after to retrieve the page of messages newer than this result set. null when there are no later messages.

anchor: str | None = None

Message ID used as the anchor for a windowed query. null for ordinary cursor pagination.

before_cursor: str | None = None

Opaque cursor to pass as before to retrieve the page of messages older than this result set. null when there are no earlier messages.

messages: list[ThreadMessagesResponseDataMessagesItem] = PydanticUndefined

Ordered array of message objects for this page of results.

class ThreadMessagesResponse(pydantic.main.BaseModel):
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

data: ThreadMessagesResponseData = PydanticUndefined

Pagination envelope containing the messages for this page along with cursors for adjacent pages.

class ThreadSearchResponse(pydantic.main.BaseModel):
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

data: list[dict[str, typing.Any]] = PydanticUndefined

Array of matching context items. Each item is a tagged object whose shape depends on the source type.

class AsyncThreadMemberResource:
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        )
AsyncThreadMemberResource(http: archastro.platform.runtime.http_client.HttpClient)
662    def __init__(self, http: HttpClient):
663        self._http = http
async def remove(self, thread: str) -> None:
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.

async def list( self, thread: str) -> ThreadMemberListResponse:
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

async def create( self, thread: str, input: ThreadMemberCreateInput) -> archastro.platform.types.threads.ThreadMember:
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 type is "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 type is "user".
Returns:

The newly created thread membership record.

class AsyncSettingResource:
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        )
AsyncSettingResource(http: archastro.platform.runtime.http_client.HttpClient)
731    def __init__(self, http: HttpClient):
732        self._http = http
async def list( self, thread: str) -> SettingListResponse:
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

async def replace( self, thread: str, input: SettingReplaceInput) -> archastro.platform.types.threads.ThreadSettings:
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.

class AsyncThreadResource:
 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        )
AsyncThreadResource(http: archastro.platform.runtime.http_client.HttpClient)
780    def __init__(self, http: HttpClient):
781        self._http = http
782        self.members = AsyncThreadMemberResource(http)
783        self.settings = AsyncSettingResource(http)
members
settings
async def delete(self, thread: str) -> None:
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.

async def get(self, thread: str) -> archastro.platform.types.threads.Thread:
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.

async def replace( self, thread: str, input: ThreadReplaceInput) -> archastro.platform.types.threads.Thread:
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.

async def agents( self, thread: str) -> ThreadAgentsResponse:
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

async def artifacts( self, thread: str) -> ThreadArtifactsResponse:
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

async def mark_read( self, thread: str, input: ThreadMarkReadInput) -> None:
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 with use_latest_message.
  • input.use_latest_message: When true, marks the thread as read up to the latest message. Mutually exclusive with last_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.

async def messages( self, thread: str, *, before_cursor: str | None = None, after_cursor: str | None = None, limit: int | None = None, anchor: str | None = None, direction: Optional[Literal['before', 'after', 'around']] = None, before_limit: int | None = None, after_limit: int | None = None, include_anchor: bool | None = None, anchor_agent_mode: Optional[Literal['cli', 'embedded']] = None, anchor_agent: str | None = None, include_reply_counts: bool | None = None) -> ThreadMessagesResponse:
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_cursor field. When provided, returns messages immediately before that position. May be combined with after_cursor to bound a range.
  • 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.
  • limit: Maximum number of messages to return per page. Defaults to 20.
  • 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.
  • 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.
  • 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 true for direction=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 with anchor_agent_mode to 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 to false. Adds latency; omit when reply counts are not needed.
Returns:

Successful response

async def picture( self, thread: str, input: ThreadPictureInput) -> archastro.platform.types.threads.Thread:
 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.

async def read_status( self, thread: str, *, user: str | None = None) -> archastro.platform.types.threads.ThreadReadStatus:
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.

async def search( self, thread: str, q: str, *, type: str | None = None) -> ThreadSearchResponse:
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

class ThreadMemberResource:
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        )
ThreadMemberResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1075    def __init__(self, http: SyncHttpClient):
1076        self._http = http
def remove(self, thread: str) -> None:
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.

def list( self, thread: str) -> ThreadMemberListResponse:
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

def create( self, thread: str, input: ThreadMemberCreateInput) -> archastro.platform.types.threads.ThreadMember:
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 type is "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 type is "user".
Returns:

The newly created thread membership record.

class SettingResource:
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        )
SettingResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1144    def __init__(self, http: SyncHttpClient):
1145        self._http = http
def list( self, thread: str) -> SettingListResponse:
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

def replace( self, thread: str, input: SettingReplaceInput) -> archastro.platform.types.threads.ThreadSettings:
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.

class ThreadResource:
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        )
ThreadResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1193    def __init__(self, http: SyncHttpClient):
1194        self._http = http
1195        self.members = ThreadMemberResource(http)
1196        self.settings = SettingResource(http)
members
settings
def delete(self, thread: str) -> None:
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.

def get(self, thread: str) -> archastro.platform.types.threads.Thread:
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.

def replace( self, thread: str, input: ThreadReplaceInput) -> archastro.platform.types.threads.Thread:
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.

def agents( self, thread: str) -> ThreadAgentsResponse:
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

def artifacts( self, thread: str) -> ThreadArtifactsResponse:
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

def mark_read( self, thread: str, input: ThreadMarkReadInput) -> None:
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 with use_latest_message.
  • input.use_latest_message: When true, marks the thread as read up to the latest message. Mutually exclusive with last_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.

def messages( self, thread: str, *, before_cursor: str | None = None, after_cursor: str | None = None, limit: int | None = None, anchor: str | None = None, direction: Optional[Literal['before', 'after', 'around']] = None, before_limit: int | None = None, after_limit: int | None = None, include_anchor: bool | None = None, anchor_agent_mode: Optional[Literal['cli', 'embedded']] = None, anchor_agent: str | None = None, include_reply_counts: bool | None = None) -> ThreadMessagesResponse:
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_cursor field. When provided, returns messages immediately before that position. May be combined with after_cursor to bound a range.
  • 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.
  • limit: Maximum number of messages to return per page. Defaults to 20.
  • 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.
  • 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.
  • 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 true for direction=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 with anchor_agent_mode to 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 to false. Adds latency; omit when reply counts are not needed.
Returns:

Successful response

def picture( self, thread: str, input: ThreadPictureInput) -> archastro.platform.types.threads.Thread:
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.

def read_status( self, thread: str, *, user: str | None = None) -> archastro.platform.types.threads.ThreadReadStatus:
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.

def search( self, thread: str, q: str, *, type: str | None = None) -> ThreadSearchResponse:
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