archastro.platform.v1.resources.threads

   1# Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License.
   2# This file is auto-generated by @archastro/sdk-generator. Do not edit.
   3# Content hash: 8d947a8b5d00
   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.chat import ChatMember
  14from ...types.threads import Thread, ThreadReadStatus, ThreadSettings
  15
  16
  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"`.'
  28
  29
  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."
  35
  36
  37class TagCreateInput(TypedDict):
  38    "Add tags to a thread"
  39
  40    tags: list[str]
  41    "Tags to add to the thread."
  42
  43
  44class TagReplaceInput(TypedDict):
  45    "Replace a thread's tags"
  46
  47    tags: list[str]
  48    "The complete set of tags for the thread. An empty array clears all tags."
  49
  50
  51class ThreadReplaceInputProfilePicture(TypedDict, total=False):
  52    data: str | None
  53    "Base64-encoded image payload. Must be a valid base64 string."
  54    filename: str | None
  55    'Original filename of the image, e.g. `"avatar.png"`. Used for storage metadata.'
  56    mime_type: str | None
  57    'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.'
  58
  59
  60class ThreadReplaceInput(TypedDict, total=False):
  61    "Update a thread"
  62
  63    description: str | None
  64    "Optional longer text describing the thread's purpose. Replaces the existing description when provided."
  65    metadata: dict[str, Any] | None
  66    "Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata."
  67    muted: bool | None
  68    "When `true`, suppresses notifications for new messages in this thread for the authenticated user."
  69    profile_picture: ThreadReplaceInputProfilePicture | None
  70    "New profile picture for the thread. Provide all three inner fields to replace the existing image."
  71    title: str | None
  72    "Human-readable display name for the thread. Replaces the existing title when provided."
  73    visibility: Literal["private", "restricted", "team"] | None
  74    "Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed."
  75
  76
  77class ThreadMarkReadInput(TypedDict, total=False):
  78    "Mark a thread as read"
  79
  80    last_read_message: str | None
  81    "Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`."
  82    use_latest_message: bool | None
  83    "When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`."
  84    user: str | None
  85    "User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token."
  86
  87
  88class ThreadPictureInputPicture(TypedDict):
  89    data: str
  90    "Base64-encoded binary content of the image file."
  91    filename: str
  92    'Original filename of the image, e.g. `"avatar.png"`. Used for storage and display.'
  93    mime_type: str
  94    'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.'
  95
  96
  97class ThreadPictureInput(TypedDict):
  98    "Update a thread's profile picture"
  99
 100    picture: ThreadPictureInputPicture
 101    "Profile picture payload. Must include the base64-encoded image data and its MIME type."
 102
 103
 104class ThreadMemberListResponseDataItemAgent(BaseModel):
 105    email: str | None = Field(
 106        default=None, description="Agent email address. `null` if not configured."
 107    )
 108    id: str = Field(..., description="Agent ID (`agi_...`).")
 109    name: str | None = Field(
 110        default=None, description="Human-readable agent name. `null` if not set."
 111    )
 112    org: str | None = Field(
 113        default=None,
 114        description="Organization that owns this agent (`org_...`). `null` if not org-scoped.",
 115    )
 116    team: str | None = Field(
 117        default=None,
 118        description="Team that owns this agent (`tem_...`). `null` if not team-scoped.",
 119    )
 120    user: str | None = Field(
 121        default=None,
 122        description="User that owns this agent (`usr_...`). `null` if not user-scoped.",
 123    )
 124
 125
 126class ThreadMemberListResponseDataItemUser(BaseModel):
 127    email: str | None = Field(default=None, description="User's email address. `null` if not set.")
 128    full_name: str | None = Field(
 129        default=None, description="Backward-compatible alias of `name`. `null` if not set."
 130    )
 131    id: str = Field(..., description="User ID (`usr_...`).")
 132    name: str | None = Field(
 133        default=None, description="Full display name of the user. `null` if not set."
 134    )
 135    org: str | None = Field(
 136        default=None,
 137        description="Organization this user belongs to (`org_...`). `null` if the user is not org-scoped.",
 138    )
 139
 140
 141class ThreadMemberListResponseDataItem(BaseModel):
 142    agent: ThreadMemberListResponseDataItemAgent | None = Field(
 143        default=None,
 144        description="Roster-safe agent identity. Populated for agent members; `null` for users.",
 145    )
 146    joined_at: datetime | None = Field(
 147        default=None, description="When this member joined the thread (ISO 8601)."
 148    )
 149    member_type: str | None = Field(
 150        default=None, description="Backward-compatible alias of `type`."
 151    )
 152    membership_type: str | None = Field(
 153        default=None, description='Role of this member, commonly `"owner"` or `"member"`.'
 154    )
 155    role: str | None = Field(
 156        default=None, description="Backward-compatible alias of `membership_type`."
 157    )
 158    type: str = Field(..., description='Kind of participant. One of `"user"` or `"agent"`.')
 159    user: ThreadMemberListResponseDataItemUser | None = Field(
 160        default=None,
 161        description="Roster-safe user identity. Populated for user members; `null` for agents.",
 162    )
 163
 164
 165class ThreadMemberListResponse(BaseModel):
 166    """
 167    Successful response
 168    """
 169
 170    data: list[ThreadMemberListResponseDataItem] = Field(
 171        ...,
 172        description="Array of thread member objects representing all current members of the thread.",
 173    )
 174
 175
 176class SettingListResponse(BaseModel):
 177    """
 178    Successful response
 179    """
 180
 181    agent_enabled: bool | None = Field(
 182        default=None,
 183        description="Whether the AI agent is active for this thread. Defaults to `true` when no settings have been explicitly set.",
 184    )
 185
 186
 187class ThreadAgentsResponse(BaseModel):
 188    """
 189    Successful response
 190    """
 191
 192    data: list[dict[str, Any]] = Field(
 193        ...,
 194        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.",
 195    )
 196
 197
 198class ThreadArtifactsResponseDataItemImageSource(BaseModel):
 199    file: str | None = Field(
 200        default=None,
 201        description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.",
 202    )
 203    height: int | None = Field(
 204        default=None, description="Height of the image in pixels. `null` if not known."
 205    )
 206    media: str | None = Field(
 207        default=None,
 208        description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.",
 209    )
 210    mime_type: str | None = Field(
 211        default=None,
 212        description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.',
 213    )
 214    refresh_url: str | None = Field(
 215        default=None,
 216        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.",
 217    )
 218    url: str | None = Field(
 219        default=None,
 220        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.",
 221    )
 222    width: int | None = Field(
 223        default=None, description="Width of the image in pixels. `null` if not known."
 224    )
 225
 226
 227class ThreadArtifactsResponseDataItem(BaseModel):
 228    agent: str | None = Field(
 229        default=None,
 230        description="ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.",
 231    )
 232    content_type: str | None = Field(
 233        default=None,
 234        description='MIME type of the current version\'s file, e.g. `"text/csv"` or `"image/png"`. `null` if no file is attached.',
 235    )
 236    created_at: datetime | None = Field(
 237        default=None, description="When the artifact was first created (ISO 8601)."
 238    )
 239    current_version: str | None = Field(
 240        default=None,
 241        description="ID of the current (latest published) artifact version (`artv_...`). `null` if no version has been published.",
 242    )
 243    description: str | None = Field(
 244        default=None,
 245        description="Optional longer description of the artifact's contents or purpose. `null` if not set.",
 246    )
 247    file: str | None = Field(
 248        default=None,
 249        description="Storage file ID for the current version (`fil_...`). `null` if no file is attached.",
 250    )
 251    file_name: str | None = Field(
 252        default=None,
 253        description='Original filename of the current version\'s file, e.g. `"output.csv"`. `null` if no file is attached.',
 254    )
 255    file_url: str | None = Field(
 256        default=None,
 257        description="Short-lived signed URL for downloading the current version's file. `null` if no file is attached.",
 258    )
 259    id: str = Field(..., description="Artifact ID (`art_...`).")
 260    image_source: ThreadArtifactsResponseDataItemImageSource | None = Field(
 261        default=None,
 262        description='Image source metadata for rendering the current version\'s file inline. Present only when `content_type` starts with `"image/"`. `null` otherwise.',
 263    )
 264    name: str | None = Field(
 265        default=None,
 266        description='Human-readable name for the artifact, e.g. `"Q2 Report"`. `null` if not set.',
 267    )
 268    org: str | None = Field(
 269        default=None, description="ID of the organization this artifact belongs to (`org_...`)."
 270    )
 271    sandbox: str | None = Field(
 272        default=None,
 273        description="Identifier of the sandbox environment associated with this artifact. `null` if not sandbox-scoped.",
 274    )
 275    team: str | None = Field(
 276        default=None,
 277        description="ID of the team that owns this artifact (`tea_...`). `null` if not team-scoped.",
 278    )
 279    thread: str | None = Field(
 280        default=None,
 281        description="ID of the thread in which this artifact was created (`thr_...`). `null` if not thread-scoped.",
 282    )
 283    updated_at: datetime | None = Field(
 284        default=None, description="When the artifact record was last modified (ISO 8601)."
 285    )
 286    user: str | None = Field(
 287        default=None,
 288        description="ID of the user who created this artifact (`usr_...`). `null` if not user-scoped.",
 289    )
 290    version: int | None = Field(
 291        default=None,
 292        description="Current version number of the artifact. Increments each time a new version is published.",
 293    )
 294
 295
 296class ThreadArtifactsResponse(BaseModel):
 297    """
 298    Successful response
 299    """
 300
 301    data: list[ThreadArtifactsResponseDataItem] = Field(
 302        ..., description="Array of artifact objects produced during the thread's conversation."
 303    )
 304
 305
 306class ThreadMessagesResponseDataMessagesItemAclAddItem(BaseModel):
 307    actions: list[str] = Field(
 308        ...,
 309        description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.',
 310    )
 311    principal: str | None = Field(
 312        default=None,
 313        description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.',
 314    )
 315    principal_type: str = Field(
 316        ...,
 317        description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.',
 318    )
 319
 320
 321class ThreadMessagesResponseDataMessagesItemAclGrantsItem(BaseModel):
 322    actions: list[str] = Field(
 323        ...,
 324        description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.',
 325    )
 326    principal: str | None = Field(
 327        default=None,
 328        description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.',
 329    )
 330    principal_type: str = Field(
 331        ...,
 332        description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.',
 333    )
 334
 335
 336class ThreadMessagesResponseDataMessagesItemAclRemoveItem(BaseModel):
 337    principal: str | None = Field(
 338        default=None,
 339        description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.',
 340    )
 341    principal_type: str = Field(
 342        ...,
 343        description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.',
 344    )
 345
 346
 347class ThreadMessagesResponseDataMessagesItemAcl(BaseModel):
 348    add: list[ThreadMessagesResponseDataMessagesItemAclAddItem] | None = Field(
 349        default=None,
 350        description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.",
 351    )
 352    grants: list[ThreadMessagesResponseDataMessagesItemAclGrantsItem] | None = Field(
 353        default=None,
 354        description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.",
 355    )
 356    remove: list[ThreadMessagesResponseDataMessagesItemAclRemoveItem] | None = Field(
 357        default=None,
 358        description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.",
 359    )
 360
 361
 362class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(BaseModel):
 363    file: str | None = Field(
 364        default=None,
 365        description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.",
 366    )
 367    height: int | None = Field(
 368        default=None, description="Height of the image in pixels. `null` if not known."
 369    )
 370    media: str | None = Field(
 371        default=None,
 372        description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.",
 373    )
 374    mime_type: str | None = Field(
 375        default=None,
 376        description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.',
 377    )
 378    refresh_url: str | None = Field(
 379        default=None,
 380        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.",
 381    )
 382    url: str | None = Field(
 383        default=None,
 384        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.",
 385    )
 386    width: int | None = Field(
 387        default=None, description="Width of the image in pixels. `null` if not known."
 388    )
 389
 390
 391class ThreadMessagesResponseDataMessagesItemActorsItem(BaseModel):
 392    alias: str | None = Field(
 393        default=None,
 394        description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.",
 395    )
 396    id: str | None = Field(
 397        default=None,
 398        description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.',
 399    )
 400    name: str | None = Field(
 401        default=None,
 402        description="Display name of the actor shown in the UI. `null` if no name is set.",
 403    )
 404    profile_picture: ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture | None = Field(
 405        default=None,
 406        description="Profile picture for the actor. `null` if the actor has no profile picture.",
 407    )
 408
 409
 410class ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource(BaseModel):
 411    file: str | None = Field(
 412        default=None,
 413        description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.",
 414    )
 415    height: int | None = Field(
 416        default=None, description="Height of the image in pixels. `null` if not known."
 417    )
 418    media: str | None = Field(
 419        default=None,
 420        description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.",
 421    )
 422    mime_type: str | None = Field(
 423        default=None,
 424        description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.',
 425    )
 426    refresh_url: str | None = Field(
 427        default=None,
 428        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.",
 429    )
 430    url: str | None = Field(
 431        default=None,
 432        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.",
 433    )
 434    width: int | None = Field(
 435        default=None, description="Width of the image in pixels. `null` if not known."
 436    )
 437
 438
 439class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource(BaseModel):
 440    file: str | None = Field(
 441        default=None,
 442        description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.",
 443    )
 444    height: int | None = Field(
 445        default=None, description="Height of the image in pixels. `null` if not known."
 446    )
 447    media: str | None = Field(
 448        default=None,
 449        description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.",
 450    )
 451    mime_type: str | None = Field(
 452        default=None,
 453        description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.',
 454    )
 455    refresh_url: str | None = Field(
 456        default=None,
 457        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.",
 458    )
 459    url: str | None = Field(
 460        default=None,
 461        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.",
 462    )
 463    width: int | None = Field(
 464        default=None, description="Width of the image in pixels. `null` if not known."
 465    )
 466
 467
 468class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem(BaseModel):
 469    content_type: str | None = Field(
 470        default=None,
 471        description='MIME type of this variant\'s file (e.g., `"image/jpeg"`, `"video/mp4"`). `null` if the file is not loaded.',
 472    )
 473    created_at: datetime | None = Field(
 474        default=None, description="When this variant was created (ISO 8601)."
 475    )
 476    file: str | None = Field(
 477        default=None,
 478        description="ID of the underlying storage file that backs this variant (`fil_...`).",
 479    )
 480    filename: str | None = Field(
 481        default=None,
 482        description="Original filename of the uploaded file for this variant. `null` if the file is not loaded.",
 483    )
 484    height: int | None = Field(
 485        default=None, description="Height of this variant in pixels. `null` if not recorded."
 486    )
 487    id: str = Field(..., description="Media variant ID (`mvr_...`).")
 488    image_source: (
 489        ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource | None
 490    ) = Field(
 491        default=None,
 492        description="Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types.",
 493    )
 494    updated_at: datetime | None = Field(
 495        default=None, description="When this variant was last updated (ISO 8601)."
 496    )
 497    url: str | None = Field(
 498        default=None,
 499        description="Signed download URL for this variant, resolved at request time. `null` if the file is unavailable.",
 500    )
 501    variant_key: str | None = Field(
 502        default=None,
 503        description='Identifier for this variant\'s processing tier. Common values include `"original"` (the unmodified upload) and `"thumbnail"` (a resized preview).',
 504    )
 505    width: int | None = Field(
 506        default=None, description="Width of this variant in pixels. `null` if not recorded."
 507    )
 508
 509
 510class ThreadMessagesResponseDataMessagesItemAttachmentsItem(BaseModel):
 511    content_type: str | None = Field(
 512        default=None,
 513        description='MIME type of the attached file, e.g. `"image/png"` or `"application/pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.',
 514    )
 515    description: str | None = Field(
 516        default=None,
 517        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.",
 518    )
 519    filename: str | None = Field(
 520        default=None,
 521        description='Original filename of the attached file, e.g. `"report.pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.',
 522    )
 523    height: int | None = Field(
 524        default=None,
 525        description="Height in pixels of the media item. Present on `media` type only. `null` otherwise.",
 526    )
 527    id: str = Field(..., description="Unique identifier for this attachment within the message.")
 528    image_height: int | None = Field(
 529        default=None,
 530        description="Height in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.",
 531    )
 532    image_source: ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource | None = Field(
 533        default=None,
 534        description="Image source metadata for inline rendering. Present on `file`, `scraped_link`, `artifact`, and `media` types when the content is an image. `null` otherwise.",
 535    )
 536    image_url: str | None = Field(
 537        default=None,
 538        description="URL of the preview image extracted from the scraped page. Present on `scraped_link` type only. `null` otherwise.",
 539    )
 540    image_width: int | None = Field(
 541        default=None,
 542        description="Width in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.",
 543    )
 544    media_type: str | None = Field(
 545        default=None,
 546        description='The media category, e.g. `"video"` or `"audio"`. Present on `media` type only; omitted otherwise.',
 547    )
 548    name: str | None = Field(
 549        default=None,
 550        description="Display name of the media item. Present on `media` type only. `null` otherwise.",
 551    )
 552    object: dict[str, Any] | None = Field(
 553        default=None,
 554        description="The full embedded object payload. For `task` type, contains the task record. For `action` type, contains the action definition. For `chart` type, contains the chart with its inline `spec`. Omitted on other types.",
 555    )
 556    title: str | None = Field(
 557        default=None,
 558        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.",
 559    )
 560    type: str = Field(
 561        ...,
 562        description='The attachment type. One of `"file"`, `"scraped_link"`, `"artifact"`, `"task"`, `"media"`, `"action"`, or `"chart"`. Determines which additional fields are present.',
 563    )
 564    url: str | None = Field(
 565        default=None,
 566        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.",
 567    )
 568    variants: list[ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem] | None = (
 569        Field(
 570            default=None,
 571            description="Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.",
 572        )
 573    )
 574    version: int | None = Field(
 575        default=None,
 576        description="Version number of the attached artifact at the time of attachment. Present on `artifact` type only. `null` otherwise.",
 577    )
 578    width: int | None = Field(
 579        default=None,
 580        description="Width in pixels of the media item. Present on `media` type only. `null` otherwise.",
 581    )
 582
 583
 584class ThreadMessagesResponseDataMessagesItemReactionsItem(BaseModel):
 585    payload: dict[str, Any] | None = Field(
 586        default=None,
 587        description='Type-specific reaction data. For `"emoji_reaction"` reactions, contains an `emoji` key with the Unicode emoji string (e.g., `" "`).',
 588    )
 589    type: str = Field(
 590        ...,
 591        description='Reaction type identifier. Currently always `"emoji_reaction"` for emoji-based reactions.',
 592    )
 593    user: str | None = Field(
 594        default=None, description="Public ID of the user who added the reaction (`usr_...`)."
 595    )
 596
 597
 598class ThreadMessagesResponseDataMessagesItem(BaseModel):
 599    acl: ThreadMessagesResponseDataMessagesItemAcl | None = Field(
 600        default=None,
 601        description="Access control list for private messages (grants with `read` action). Only returned to resource owners (and privileged/org-admin viewers) via server-side `field_redactions: [acl: :owner]`; `null` for everyone else.",
 602    )
 603    actors: list[ThreadMessagesResponseDataMessagesItemActorsItem] | None = Field(
 604        default=None,
 605        description="Resolved actor descriptors for the message sender, combining identity and display metadata. Always contains exactly one entry.",
 606    )
 607    agent: str | None = Field(
 608        default=None,
 609        description="ID of the agent user that sent this message (`agi_...`). `null` for messages sent by human users.",
 610    )
 611    agent_mode: Literal["cli", "embedded"] | None = Field(
 612        default=None,
 613        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.",
 614    )
 615    attachments: list[ThreadMessagesResponseDataMessagesItemAttachmentsItem] | None = Field(
 616        default=None,
 617        description="Files, links, tasks, media, artifacts, and actions attached to this message. Empty array if there are no attachments.",
 618    )
 619    branched_thread: str | None = Field(
 620        default=None,
 621        description="ID of the thread that was branched from this message (`thr_...`). `null` if this message has not spawned a branch thread.",
 622    )
 623    content: str | None = Field(
 624        default=None,
 625        description="Text content of the message. `null` for messages that contain only attachments.",
 626    )
 627    created_at: str | None = Field(
 628        default=None, description="When the message was posted (ISO 8601)."
 629    )
 630    has_replies: bool | None = Field(
 631        default=None,
 632        description="Whether this message has at least one reply. Only present when explicitly requested or computed by the server.",
 633    )
 634    id: str = Field(..., description="Message ID (`msg_...`).")
 635    idempotency_key: str | None = Field(
 636        default=None,
 637        description="Client-supplied idempotency key used to deduplicate message sends. `null` if the sender did not provide one.",
 638    )
 639    is_deleted: bool | None = Field(
 640        default=None,
 641        description="Whether this message is a deletion tombstone. `true` only on the `message_updated` broadcast emitted when a message is deleted: the original content is replaced with a placeholder and the message no longer exists on the server. Always `false` for live messages.",
 642    )
 643    legacy_agent: str | None = Field(
 644        default=None,
 645        description="Identifier of the legacy chat agent that sent this message, if applicable. `null` for messages sent by users or modern agent users.",
 646    )
 647    metadata: dict[str, Any] | None = Field(
 648        default=None,
 649        description="Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.",
 650    )
 651    org: str | None = Field(
 652        default=None, description="ID of the organization that owns this message (`org_...`)."
 653    )
 654    reactions: list[ThreadMessagesResponseDataMessagesItemReactionsItem] | None = Field(
 655        default=None,
 656        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.",
 657    )
 658    rendering_mode: str | None = Field(
 659        default=None,
 660        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.',
 661    )
 662    replies: list[dict[str, Any]] | None = Field(
 663        default=None,
 664        description="Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.",
 665    )
 666    replies_after_cursor: str | None = Field(
 667        default=None,
 668        description="Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.",
 669    )
 670    replies_before_cursor: str | None = Field(
 671        default=None,
 672        description="Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.",
 673    )
 674    reply_count: int | None = Field(
 675        default=None,
 676        description="Total number of direct replies to this message. Only present when explicitly requested or computed by the server.",
 677    )
 678    reply_to: dict[str, Any] | None = Field(
 679        default=None,
 680        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.",
 681    )
 682    root_message_id: str | None = Field(
 683        default=None,
 684        description="ID of the root message in this reply chain (`msg_...`). `null` for a top-level message. The value is persisted when the reply is created, so callers can correlate a multi-turn session without walking parent messages.",
 685    )
 686    sandbox: str | None = Field(
 687        default=None,
 688        description="ID of the developer sandbox this message belongs to (`dsb_...`). `null` for non-sandbox messages.",
 689    )
 690    team: str | None = Field(
 691        default=None,
 692        description="ID of the team this message is scoped to (`tem_...`). `null` if the message is not team-scoped.",
 693    )
 694    thread: str | None = Field(
 695        default=None, description="ID of the thread this message belongs to (`thr_...`)."
 696    )
 697    type: str | None = Field(
 698        default=None,
 699        description="Optional client-defined classification for the message (for example `note` or `status`). Free-form string up to 64 characters. The value `system` is reserved for platform-authored messages and cannot be set by clients. `null` when unset.",
 700    )
 701    user: str | dict[str, Any] | None = Field(
 702        default=None,
 703        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.",
 704    )
 705    visibility: Literal["default", "private"] | None = Field(
 706        default=None,
 707        description="Message-level visibility. `default` is visible to anyone who can see the parent thread. `private` is restricted to the sender and explicit ACL `read` grantees.",
 708    )
 709
 710
 711class ThreadMessagesResponseData(BaseModel):
 712    after_cursor: str | None = Field(
 713        default=None,
 714        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.",
 715    )
 716    anchor: str | None = Field(
 717        default=None,
 718        description="Message ID used as the anchor for a windowed query. `null` for ordinary cursor pagination.",
 719    )
 720    before_cursor: str | None = Field(
 721        default=None,
 722        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.",
 723    )
 724    messages: list[ThreadMessagesResponseDataMessagesItem] = Field(
 725        ..., description="Ordered array of message objects for this page of results."
 726    )
 727
 728
 729class ThreadMessagesResponse(BaseModel):
 730    """
 731    Successful response
 732    """
 733
 734    data: ThreadMessagesResponseData = Field(
 735        ...,
 736        description="Pagination envelope containing the messages for this page along with cursors for adjacent pages.",
 737    )
 738
 739
 740class ThreadSearchResponseDataItem(BaseModel):
 741    agent: str | None = Field(
 742        default=None,
 743        description="Agent sender ID (`agi_...`), or `null` when a human sent the message.",
 744    )
 745    content: str = Field(
 746        ...,
 747        description="A bounded snippet around the first matching occurrence (at most 240 characters).",
 748    )
 749    created_at: datetime = Field(..., description="When the message was posted.")
 750    id: str = Field(..., description="Message ID (`msg_...`).")
 751    similarity_score: float | None = Field(
 752        default=None,
 753        description="Cosine similarity to the query when the result participated in embedding search, or `null` in text mode and for text-only hybrid matches.",
 754    )
 755    user: str | None = Field(
 756        default=None,
 757        description="Human sender ID (`usr_...`), or `null` when an agent sent the message.",
 758    )
 759
 760
 761class ThreadSearchResponse(BaseModel):
 762    """
 763    Successful response
 764    """
 765
 766    after_cursor: str | None = Field(
 767        default=None,
 768        description="Text-mode cursor for the next page of newer matches, or `null` for ranked modes and empty pages.",
 769    )
 770    before_cursor: str | None = Field(
 771        default=None,
 772        description="Text-mode cursor for the next page of older matches, or `null` for ranked modes and empty pages.",
 773    )
 774    data: list[ThreadSearchResponseDataItem] = Field(
 775        ...,
 776        description="Matching messages ordered newest first in text mode and by relevance in embedding or hybrid mode.",
 777    )
 778    has_more: bool = Field(
 779        ..., description="`true` when at least one additional visible match exists."
 780    )
 781
 782
 783class ThreadTrajectoriesResponseDataItem(BaseModel):
 784    agent_message: str | None = Field(
 785        default=None,
 786        description="ID of the agent-authored reply message (`msg_...`). `null` if the trajectory has not yet produced a response message.",
 787    )
 788    created_at: str | None = Field(
 789        default=None, description="When this trajectory link was created (ISO 8601)."
 790    )
 791    id: str = Field(..., description="Thread message trajectory ID (`tmt_...`).")
 792    org: str | None = Field(
 793        default=None, description="ID of the organization this trajectory belongs to (`org_...`)."
 794    )
 795    sandbox: str | None = Field(
 796        default=None,
 797        description="ID of the sandbox environment in which this trajectory was produced (`dsb_...`). `null` in production contexts.",
 798    )
 799    thread: str | None = Field(
 800        default=None, description="ID of the thread containing the linked messages (`thr_...`)."
 801    )
 802    trajectory: str | None = Field(
 803        default=None,
 804        description="ID of the AI trajectory record that captures the full model interaction for this exchange (`trj_...`).",
 805    )
 806    updated_at: str | None = Field(
 807        default=None, description="When this trajectory link was last modified (ISO 8601)."
 808    )
 809    user_message: str | None = Field(
 810        default=None,
 811        description="ID of the user-authored message that triggered the agent response (`msg_...`). `null` if the agent turn was not preceded by a user message.",
 812    )
 813
 814
 815class ThreadTrajectoriesResponse(BaseModel):
 816    """
 817    Successful response
 818    """
 819
 820    after_cursor: str | None = Field(
 821        default=None,
 822        description="Opaque cursor to pass as `after_cursor` to retrieve the next page. `null` when no further pages exist.",
 823    )
 824    before_cursor: str | None = Field(
 825        default=None,
 826        description="Opaque cursor to pass as `before_cursor` to retrieve the previous page. `null` when this is the first page.",
 827    )
 828    data: list[ThreadTrajectoriesResponseDataItem] = Field(
 829        ...,
 830        description="Array of thread message trajectory objects for the current page. Empty when no trajectories match the query.",
 831    )
 832
 833
 834class AsyncThreadMemberResource:
 835    def __init__(self, http: HttpClient):
 836        self._http = http
 837
 838    async def remove(self, thread: str) -> None:
 839        """
 840        Remove a member from a thread
 841        Removes a user or agent from the explicit roster of a private or restricted
 842        thread. Team-visible threads use implicit membership and reject individual
 843        removals. A member may remove themself; removing someone else requires
 844        permission to modify the thread. A successful removal returns HTTP 204 with
 845        no response body.
 846        Supply either `user` or `agent` depending on the value of `type`. Returns 404
 847        if the thread or the membership record does not exist.
 848
 849        Args:
 850            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
 851
 852        Returns:
 853            Empty response body. HTTP 204 on success.
 854        """
 855        await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")
 856
 857    async def list(self, thread: str) -> ThreadMemberListResponse:
 858        """
 859        List members of a thread
 860        Returns all current user and agent members. Private and restricted threads
 861        return their explicit roster; team-visible threads return the owning team's
 862        implicit roster. The authenticated viewer must be able to see the thread.
 863        Results are returned as a flat array in the `data` field. The list is not
 864        paginated all members are returned in a single response.
 865
 866        Args:
 867            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
 868
 869        Returns:
 870            Successful response
 871        """
 872        return await self._http.request(
 873            f"/api/v1/threads/{thread}/members",
 874            response_type=ThreadMemberListResponse,
 875        )
 876
 877    async def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember:
 878        """
 879        Add a member to a thread
 880        Adds a user or agent to the explicit roster of a private or restricted
 881        thread. Team-visible threads use the owning team's implicit roster and reject
 882        explicit additions. On restricted threads, a team member may add themself;
 883        adding anyone else requires permission to modify the thread.
 884        Supply either `user` or `agent` depending on the value of `type`. Targets
 885        must be visible to the caller and, for an ordinary team-owned thread, must
 886        belong to the owning team. On success the membership record is returned with
 887        HTTP 201; repeated agent additions are idempotent.
 888
 889        Args:
 890            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
 891            input: Request body.
 892            input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`.
 893            input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.
 894            input.type: Kind of principal being added. Must be `"user"` or `"agent"`.
 895            input.user: User ID of the principal to add. Required when `type` is `"user"`.
 896
 897        Returns:
 898            The user or agent membership that was added to the thread.
 899        """
 900        return await self._http.request(
 901            f"/api/v1/threads/{thread}/members",
 902            method="POST",
 903            body=input,
 904            response_type=ChatMember,
 905        )
 906
 907
 908class AsyncSettingResource:
 909    def __init__(self, http: HttpClient):
 910        self._http = http
 911
 912    async def list(self, thread: str) -> SettingListResponse:
 913        """
 914        Retrieve thread settings
 915        Returns the current settings for the specified thread. Settings control
 916        per-thread behavior such as whether the AI agent is enabled.
 917        The authenticated user must own the thread or be a member of its workspace.
 918        If settings have never been explicitly configured, defaults are returned
 919        (for example, `agent_enabled` defaults to `true`).
 920
 921        Args:
 922            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
 923
 924        Returns:
 925            Successful response
 926        """
 927        return await self._http.request(
 928            f"/api/v1/threads/{thread}/settings",
 929            response_type=SettingListResponse,
 930        )
 931
 932    async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings:
 933        """
 934        Update thread settings
 935        Updates the settings for the specified thread. Only fields included in
 936        the `settings` map are modified; omitted fields retain their current values.
 937        The authenticated user must own the thread or be a member of its workspace.
 938        Returns the full settings object reflecting the state after the update.
 939        Validation errors are returned as `422 Unprocessable Entity`.
 940
 941        Args:
 942            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
 943            input: Request body.
 944            input.settings: Map of settings fields to update. Include only the keys you want to change.
 945
 946        Returns:
 947            The thread settings object after the update has been applied.
 948        """
 949        return await self._http.request(
 950            f"/api/v1/threads/{thread}/settings",
 951            method="PUT",
 952            body=input,
 953            response_type=ThreadSettings,
 954        )
 955
 956
 957class AsyncTagResource:
 958    def __init__(self, http: HttpClient):
 959        self._http = http
 960
 961    async def remove(self, thread: str) -> Thread:
 962        """
 963        Remove tags from a thread
 964        Removes one or more status tags from the thread and returns the updated
 965        thread. Removing a tag the thread does not have is a no-op.
 966        Any participant of the thread a human member or an agent member may edit
 967        tags. Supply the tags to remove as repeated query parameters, e.g.
 968        `?tags[]=blocked&tags[]=needs-review`.
 969
 970        Args:
 971            thread: Thread ID (`thr_...`) to untag.
 972
 973        Returns:
 974            The thread object after the tags were removed.
 975        """
 976        return await self._http.request(
 977            f"/api/v1/threads/{thread}/tags",
 978            method="DELETE",
 979            response_type=Thread,
 980        )
 981
 982    async def create(self, thread: str, input: TagCreateInput) -> Thread:
 983        """
 984        Add tags to a thread
 985        Adds one or more status tags to the thread and returns the updated thread.
 986        Any participant of the thread a human member or an agent member may edit
 987        tags; this is broader than the owner/admin permission required to update other
 988        thread fields. Adding a tag the thread already has is a no-op. Tags are
 989        normalized (trimmed and lowercased) and may contain only lowercase letters,
 990        numbers, hyphens, and underscores.
 991
 992        Args:
 993            thread: Thread ID (`thr_...`) to untag.
 994            input: Request body.
 995            input.tags: Tags to add to the thread.
 996
 997        Returns:
 998            The thread object after the tags were added.
 999        """
1000        return await self._http.request(
1001            f"/api/v1/threads/{thread}/tags",
1002            method="POST",
1003            body=input,
1004            response_type=Thread,
1005        )
1006
1007    async def replace(self, thread: str, input: TagReplaceInput) -> Thread:
1008        """
1009        Replace a thread's tags
1010        Replaces the thread's entire set of status tags with the provided list and
1011        returns the updated thread. Passing an empty array clears all tags.
1012        Any participant of the thread a human member or an agent member may edit
1013        tags. Tags are normalized (trimmed and lowercased) and may contain only
1014        lowercase letters, numbers, hyphens, and underscores.
1015
1016        Args:
1017            thread: Thread ID (`thr_...`) to untag.
1018            input: Request body.
1019            input.tags: The complete set of tags for the thread. An empty array clears all tags.
1020
1021        Returns:
1022            The thread object after its tags were replaced.
1023        """
1024        return await self._http.request(
1025            f"/api/v1/threads/{thread}/tags",
1026            method="PUT",
1027            body=input,
1028            response_type=Thread,
1029        )
1030
1031
1032class AsyncThreadResource:
1033    def __init__(self, http: HttpClient):
1034        self._http = http
1035        self.members = AsyncThreadMemberResource(http)
1036        self.settings = AsyncSettingResource(http)
1037        self.tags = AsyncTagResource(http)
1038
1039    async def delete(self, thread: str) -> None:
1040        """
1041        Delete a thread
1042        Permanently deletes a thread and all of its messages and artifacts. This action
1043        cannot be undone.
1044        The authenticated user must own the thread or be an owner of the team the thread
1045        belongs to. Attempting to delete a thread owned by another user or team returns 403.
1046
1047        Args:
1048            thread: Thread ID (`thr_...`). The authenticated user must own this thread.
1049
1050        Returns:
1051            Empty response on successful deletion.
1052        """
1053        await self._http.request(f"/api/v1/threads/{thread}", method="DELETE")
1054
1055    async def get(self, thread: str) -> Thread:
1056        """
1057        Retrieve a thread
1058        Returns the full thread record for the given thread ID. The authenticated user
1059        must own the thread or be a member of the workspace it belongs to.
1060        Use this endpoint to fetch the current state of a single thread, including its
1061        title, description, and metadata. To list many threads, use the list endpoint
1062        with cursor-based pagination.
1063
1064        Args:
1065            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1066
1067        Returns:
1068            The requested thread object.
1069        """
1070        return await self._http.request(f"/api/v1/threads/{thread}", response_type=Thread)
1071
1072    async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread:
1073        """
1074        Update a thread
1075        Updates one or more mutable properties of the specified thread and returns
1076        the full thread object with the applied changes. Only the fields you provide
1077        are modified; omitted fields retain their current values.
1078        If `profile_picture` is supplied, the image is uploaded before the other
1079        fields are saved, after all ordinary thread fields have passed validation.
1080        Supplying invalid base64 picture data returns 422 and no other fields are
1081        updated.
1082        Visibility can only widen: `private` may become `restricted` or `team`, and
1083        `restricted` may become `team`. The authenticated viewer must have
1084        permission to modify the thread.
1085        Mirror-thread titles, descriptions, and notification state remain editable
1086        by privileged app viewers. Mirror metadata, visibility, and membership are
1087        provider-managed and cannot be changed through this endpoint.
1088
1089        Args:
1090            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1091            input: Request body.
1092            input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
1093            input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
1094            input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user.
1095            input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
1096            input.title: Human-readable display name for the thread. Replaces the existing title when provided.
1097            input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed.
1098
1099        Returns:
1100            The thread object after the update has been applied.
1101        """
1102        return await self._http.request(
1103            f"/api/v1/threads/{thread}",
1104            method="PUT",
1105            body=input,
1106            response_type=Thread,
1107        )
1108
1109    async def agents(self, thread: str) -> ThreadAgentsResponse:
1110        """
1111        List agents in a thread
1112        Returns the agents participating in the specified thread. Only personal user
1113        threads (threads owned by a single user, not a team) expose agents through
1114        this endpoint; requests for team threads return 404.
1115        The authenticated user must have visibility into the thread. Each agent entry
1116        includes display information such as name and profile picture. Thread-level
1117        overrides (e.g. a custom name or profile picture set for this thread) take
1118        precedence over the agent's default values. When the caller is the thread
1119        owner, each entry also includes an `agent_config` object describing the
1120        agent's message policy and context configuration.
1121
1122        Args:
1123            thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user.
1124
1125        Returns:
1126            Successful response
1127        """
1128        return await self._http.request(
1129            f"/api/v1/threads/{thread}/agents",
1130            response_type=ThreadAgentsResponse,
1131        )
1132
1133    async def artifacts(self, thread: str) -> ThreadArtifactsResponse:
1134        """
1135        List artifacts for a thread
1136        Returns all artifacts produced during a thread's AI conversation. Artifacts are
1137        structured outputs such as code files, documents, or generated assets created
1138        by the AI agent in response to messages in the thread.
1139        The authenticated user must have access to the specified thread. Results are
1140        returned in a single page; there is no cursor-based pagination for this endpoint.
1141
1142        Args:
1143            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user.
1144
1145        Returns:
1146            Successful response
1147        """
1148        return await self._http.request(
1149            f"/api/v1/threads/{thread}/artifacts",
1150            response_type=ThreadArtifactsResponse,
1151        )
1152
1153    async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None:
1154        """
1155        Mark a thread as read
1156        Records that a user has read up to a specific message in the thread. Unread
1157        indicators and badge counts are cleared up to the specified message.
1158        You must supply exactly one of `last_read_message` or `use_latest_message`.
1159        Omitting both returns 400. If `use_latest_message` is `true` and the thread
1160        has no messages, the request succeeds silently with no state change.
1161        For server-to-server (S2S) requests where no user identity is present in the
1162        token, the `user` param is required to identify whose read state to update.
1163
1164        Args:
1165            thread: Thread ID (`thr_...`). The thread to mark as read.
1166            input: Request body.
1167            input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`.
1168            input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`.
1169            input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
1170
1171        Returns:
1172            Empty response on success.
1173        """
1174        await self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input)
1175
1176    async def messages(
1177        self,
1178        thread: str,
1179        *,
1180        before_cursor: str | None = None,
1181        after_cursor: str | None = None,
1182        metadata: dict[str, Any] | None = None,
1183        limit: int | None = None,
1184        anchor: str | None = None,
1185        direction: Literal["before", "after", "around"] | None = None,
1186        before_limit: int | None = None,
1187        after_limit: int | None = None,
1188        include_anchor: bool | None = None,
1189        anchor_agent_mode: Literal["cli", "embedded"] | None = None,
1190        anchor_agent: str | None = None,
1191        include_reply_counts: bool | None = None,
1192    ) -> ThreadMessagesResponse:
1193        """
1194        List messages in a thread
1195        Returns a cursor-paginated list of messages belonging to the specified thread,
1196        ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both
1197        to page through or bound the result set; omit both to receive the most recent page.
1198        Supply `anchor` and `direction` to fetch a window before, after, or around a
1199        specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to
1200        resolve the anchor from the latest embedded-agent message, and add
1201        `anchor_agent` to scope that resolution to a single sender agent.
1202        Supply `metadata` as a JSON-encoded structured expression to filter message
1203        metadata before cursor pagination or anchored window limits are applied.
1204        The authenticated user must have access to the thread's owner (workspace or user).
1205        A 403 is returned if the thread exists but is not accessible to the caller; a 404
1206        is returned if the thread does not exist or is not visible to the authenticated user.
1207        Pass `include_reply_counts: true` to annotate each message with the number of
1208        threaded replies it has received. This adds a small amount of latency and should
1209        be omitted when reply counts are not needed.
1210
1211        Args:
1212            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1213            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.
1214            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.
1215            metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits.
1216            limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
1217            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`.
1218            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`.
1219            before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100.
1220            after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100.
1221            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.
1222            anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode.
1223            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.
1224            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.
1225
1226        Returns:
1227            Successful response
1228        """
1229        query: dict[str, object] = {}
1230        if before_cursor is not None:
1231            query["before_cursor"] = before_cursor
1232        if after_cursor is not None:
1233            query["after_cursor"] = after_cursor
1234        if metadata is not None:
1235            query["metadata"] = metadata
1236        if limit is not None:
1237            query["limit"] = limit
1238        if anchor is not None:
1239            query["anchor"] = anchor
1240        if direction is not None:
1241            query["direction"] = direction
1242        if before_limit is not None:
1243            query["before_limit"] = before_limit
1244        if after_limit is not None:
1245            query["after_limit"] = after_limit
1246        if include_anchor is not None:
1247            query["include_anchor"] = include_anchor
1248        if anchor_agent_mode is not None:
1249            query["anchor_agent_mode"] = anchor_agent_mode
1250        if anchor_agent is not None:
1251            query["anchor_agent"] = anchor_agent
1252        if include_reply_counts is not None:
1253            query["include_reply_counts"] = include_reply_counts
1254        return await self._http.request(
1255            f"/api/v1/threads/{thread}/messages",
1256            query=query,
1257            response_type=ThreadMessagesResponse,
1258        )
1259
1260    async def picture(self, thread: str, input: ThreadPictureInput) -> Thread:
1261        """
1262        Update a thread's profile picture
1263        Uploads a new profile picture for the specified thread and returns the updated
1264        thread object. The image must be supplied as a base64-encoded string with its
1265        MIME type.
1266        The authenticated user must own the thread or be a team owner of the workspace
1267        the thread belongs to. Supplying invalid base64 data returns 422.
1268
1269        Args:
1270            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1271            input: Request body.
1272            input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
1273
1274        Returns:
1275            The thread object after the profile picture has been updated.
1276        """
1277        return await self._http.request(
1278            f"/api/v1/threads/{thread}/picture",
1279            method="PUT",
1280            body=input,
1281            response_type=Thread,
1282        )
1283
1284    async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus:
1285        """
1286        Retrieve a thread's read status
1287        Returns the read status of a thread for the specified user, including the ID
1288        of the last message they have read and the number of unread messages remaining.
1289        For user-authenticated requests, the status is always returned for the
1290        authenticated user and the `user` parameter is ignored. For server-to-server
1291        (S2S) requests, the `user` parameter is required and must be a valid user ID.
1292        Returns 404 if the thread does not exist or the caller does not have access
1293        to it.
1294
1295        Args:
1296            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user.
1297            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.
1298
1299        Returns:
1300            The read status record for the requested thread and user.
1301        """
1302        query: dict[str, object] = {}
1303        if user is not None:
1304            query["user"] = user
1305        return await self._http.request(
1306            f"/api/v1/threads/{thread}/read_status",
1307            query=query,
1308            response_type=ThreadReadStatus,
1309        )
1310
1311    async def search(
1312        self,
1313        thread: str,
1314        q: str,
1315        *,
1316        app: str | None = None,
1317        limit: int | None = None,
1318        mode: Literal["text", "embedding", "hybrid"] | None = None,
1319        before_cursor: str | None = None,
1320        after_cursor: str | None = None,
1321    ) -> ThreadSearchResponse:
1322        """
1323        Search messages in a thread
1324        Searches canonical message content in the specified thread. `"text"` mode
1325        performs the existing case-insensitive substring search, `"embedding"` ranks
1326        stored message embeddings by cosine similarity, and `"hybrid"` combines the
1327        text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages
1328        visible to the authenticated caller are considered.
1329        Results are intentionally lean: each row contains only a bounded content
1330        snippet, sender identity, and timestamp. Attachments, reactions, ACLs, and
1331        metadata are neither hydrated nor serialized. At most 20 results are
1332        returned. Text results support chronological cursor pagination. Embedding and
1333        hybrid results are relevance-ranked single pages and return null cursors.
1334
1335        Args:
1336            thread: Thread ID (`thr_...`). Must be visible to the authenticated caller.
1337            app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount.
1338            q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
1339            limit: Maximum number of results. Defaults to 20 and is capped at 20.
1340            mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings.
1341            before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
1342            after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
1343
1344        Returns:
1345            Successful response
1346        """
1347        query: dict[str, object] = {}
1348        if app is not None:
1349            query["app"] = app
1350        query["q"] = q
1351        if limit is not None:
1352            query["limit"] = limit
1353        if mode is not None:
1354            query["mode"] = mode
1355        if before_cursor is not None:
1356            query["before_cursor"] = before_cursor
1357        if after_cursor is not None:
1358            query["after_cursor"] = after_cursor
1359        return await self._http.request(
1360            f"/api/v1/threads/{thread}/search",
1361            query=query,
1362            response_type=ThreadSearchResponse,
1363        )
1364
1365    async def trajectories(
1366        self,
1367        thread: str,
1368        *,
1369        before_cursor: str | None = None,
1370        after_cursor: str | None = None,
1371        limit: int | None = None,
1372        message: str | None = None,
1373    ) -> ThreadTrajectoriesResponse:
1374        """
1375        List trajectories for a thread
1376        Returns a cursor-paginated list of thread message trajectories associated with the
1377        specified thread. Each trajectory links a user message and its agent response to the
1378        underlying AI trajectory record that captured the model's reasoning steps.
1379        The authenticated user must own the thread or be a member of the workspace it belongs
1380        to. Results are returned in reverse chronological order by default. Use `before_cursor`
1381        and `after_cursor` to navigate pages; provide at most one cursor per request.
1382        Optionally filter results to trajectories produced in response to a specific message
1383        by supplying the `message` parameter. When no trajectories match the query, `data`
1384        is an empty array and both cursor fields are `null`. A cursor that cannot be decoded
1385        returns a 400 `invalid_cursor` error.
1386
1387        Args:
1388            thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace.
1389            before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position.
1390            after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position.
1391            limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
1392            message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message.
1393
1394        Returns:
1395            Successful response
1396        """
1397        query: dict[str, object] = {}
1398        if before_cursor is not None:
1399            query["before_cursor"] = before_cursor
1400        if after_cursor is not None:
1401            query["after_cursor"] = after_cursor
1402        if limit is not None:
1403            query["limit"] = limit
1404        if message is not None:
1405            query["message"] = message
1406        return await self._http.request(
1407            f"/api/v1/threads/{thread}/trajectories",
1408            query=query,
1409            response_type=ThreadTrajectoriesResponse,
1410        )
1411
1412
1413class ThreadMemberResource:
1414    def __init__(self, http: SyncHttpClient):
1415        self._http = http
1416
1417    def remove(self, thread: str) -> None:
1418        """
1419        Remove a member from a thread
1420        Removes a user or agent from the explicit roster of a private or restricted
1421        thread. Team-visible threads use implicit membership and reject individual
1422        removals. A member may remove themself; removing someone else requires
1423        permission to modify the thread. A successful removal returns HTTP 204 with
1424        no response body.
1425        Supply either `user` or `agent` depending on the value of `type`. Returns 404
1426        if the thread or the membership record does not exist.
1427
1428        Args:
1429            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1430
1431        Returns:
1432            Empty response body. HTTP 204 on success.
1433        """
1434        self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")
1435
1436    def list(self, thread: str) -> ThreadMemberListResponse:
1437        """
1438        List members of a thread
1439        Returns all current user and agent members. Private and restricted threads
1440        return their explicit roster; team-visible threads return the owning team's
1441        implicit roster. The authenticated viewer must be able to see the thread.
1442        Results are returned as a flat array in the `data` field. The list is not
1443        paginated all members are returned in a single response.
1444
1445        Args:
1446            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1447
1448        Returns:
1449            Successful response
1450        """
1451        return self._http.request(
1452            f"/api/v1/threads/{thread}/members",
1453            response_type=ThreadMemberListResponse,
1454        )
1455
1456    def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember:
1457        """
1458        Add a member to a thread
1459        Adds a user or agent to the explicit roster of a private or restricted
1460        thread. Team-visible threads use the owning team's implicit roster and reject
1461        explicit additions. On restricted threads, a team member may add themself;
1462        adding anyone else requires permission to modify the thread.
1463        Supply either `user` or `agent` depending on the value of `type`. Targets
1464        must be visible to the caller and, for an ordinary team-owned thread, must
1465        belong to the owning team. On success the membership record is returned with
1466        HTTP 201; repeated agent additions are idempotent.
1467
1468        Args:
1469            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1470            input: Request body.
1471            input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`.
1472            input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.
1473            input.type: Kind of principal being added. Must be `"user"` or `"agent"`.
1474            input.user: User ID of the principal to add. Required when `type` is `"user"`.
1475
1476        Returns:
1477            The user or agent membership that was added to the thread.
1478        """
1479        return self._http.request(
1480            f"/api/v1/threads/{thread}/members",
1481            method="POST",
1482            body=input,
1483            response_type=ChatMember,
1484        )
1485
1486
1487class SettingResource:
1488    def __init__(self, http: SyncHttpClient):
1489        self._http = http
1490
1491    def list(self, thread: str) -> SettingListResponse:
1492        """
1493        Retrieve thread settings
1494        Returns the current settings for the specified thread. Settings control
1495        per-thread behavior such as whether the AI agent is enabled.
1496        The authenticated user must own the thread or be a member of its workspace.
1497        If settings have never been explicitly configured, defaults are returned
1498        (for example, `agent_enabled` defaults to `true`).
1499
1500        Args:
1501            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
1502
1503        Returns:
1504            Successful response
1505        """
1506        return self._http.request(
1507            f"/api/v1/threads/{thread}/settings",
1508            response_type=SettingListResponse,
1509        )
1510
1511    def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings:
1512        """
1513        Update thread settings
1514        Updates the settings for the specified thread. Only fields included in
1515        the `settings` map are modified; omitted fields retain their current values.
1516        The authenticated user must own the thread or be a member of its workspace.
1517        Returns the full settings object reflecting the state after the update.
1518        Validation errors are returned as `422 Unprocessable Entity`.
1519
1520        Args:
1521            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
1522            input: Request body.
1523            input.settings: Map of settings fields to update. Include only the keys you want to change.
1524
1525        Returns:
1526            The thread settings object after the update has been applied.
1527        """
1528        return self._http.request(
1529            f"/api/v1/threads/{thread}/settings",
1530            method="PUT",
1531            body=input,
1532            response_type=ThreadSettings,
1533        )
1534
1535
1536class TagResource:
1537    def __init__(self, http: SyncHttpClient):
1538        self._http = http
1539
1540    def remove(self, thread: str) -> Thread:
1541        """
1542        Remove tags from a thread
1543        Removes one or more status tags from the thread and returns the updated
1544        thread. Removing a tag the thread does not have is a no-op.
1545        Any participant of the thread a human member or an agent member may edit
1546        tags. Supply the tags to remove as repeated query parameters, e.g.
1547        `?tags[]=blocked&tags[]=needs-review`.
1548
1549        Args:
1550            thread: Thread ID (`thr_...`) to untag.
1551
1552        Returns:
1553            The thread object after the tags were removed.
1554        """
1555        return self._http.request(
1556            f"/api/v1/threads/{thread}/tags",
1557            method="DELETE",
1558            response_type=Thread,
1559        )
1560
1561    def create(self, thread: str, input: TagCreateInput) -> Thread:
1562        """
1563        Add tags to a thread
1564        Adds one or more status tags to the thread and returns the updated thread.
1565        Any participant of the thread a human member or an agent member may edit
1566        tags; this is broader than the owner/admin permission required to update other
1567        thread fields. Adding a tag the thread already has is a no-op. Tags are
1568        normalized (trimmed and lowercased) and may contain only lowercase letters,
1569        numbers, hyphens, and underscores.
1570
1571        Args:
1572            thread: Thread ID (`thr_...`) to untag.
1573            input: Request body.
1574            input.tags: Tags to add to the thread.
1575
1576        Returns:
1577            The thread object after the tags were added.
1578        """
1579        return self._http.request(
1580            f"/api/v1/threads/{thread}/tags",
1581            method="POST",
1582            body=input,
1583            response_type=Thread,
1584        )
1585
1586    def replace(self, thread: str, input: TagReplaceInput) -> Thread:
1587        """
1588        Replace a thread's tags
1589        Replaces the thread's entire set of status tags with the provided list and
1590        returns the updated thread. Passing an empty array clears all tags.
1591        Any participant of the thread a human member or an agent member may edit
1592        tags. Tags are normalized (trimmed and lowercased) and may contain only
1593        lowercase letters, numbers, hyphens, and underscores.
1594
1595        Args:
1596            thread: Thread ID (`thr_...`) to untag.
1597            input: Request body.
1598            input.tags: The complete set of tags for the thread. An empty array clears all tags.
1599
1600        Returns:
1601            The thread object after its tags were replaced.
1602        """
1603        return self._http.request(
1604            f"/api/v1/threads/{thread}/tags",
1605            method="PUT",
1606            body=input,
1607            response_type=Thread,
1608        )
1609
1610
1611class ThreadResource:
1612    def __init__(self, http: SyncHttpClient):
1613        self._http = http
1614        self.members = ThreadMemberResource(http)
1615        self.settings = SettingResource(http)
1616        self.tags = TagResource(http)
1617
1618    def delete(self, thread: str) -> None:
1619        """
1620        Delete a thread
1621        Permanently deletes a thread and all of its messages and artifacts. This action
1622        cannot be undone.
1623        The authenticated user must own the thread or be an owner of the team the thread
1624        belongs to. Attempting to delete a thread owned by another user or team returns 403.
1625
1626        Args:
1627            thread: Thread ID (`thr_...`). The authenticated user must own this thread.
1628
1629        Returns:
1630            Empty response on successful deletion.
1631        """
1632        self._http.request(f"/api/v1/threads/{thread}", method="DELETE")
1633
1634    def get(self, thread: str) -> Thread:
1635        """
1636        Retrieve a thread
1637        Returns the full thread record for the given thread ID. The authenticated user
1638        must own the thread or be a member of the workspace it belongs to.
1639        Use this endpoint to fetch the current state of a single thread, including its
1640        title, description, and metadata. To list many threads, use the list endpoint
1641        with cursor-based pagination.
1642
1643        Args:
1644            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1645
1646        Returns:
1647            The requested thread object.
1648        """
1649        return self._http.request(f"/api/v1/threads/{thread}", response_type=Thread)
1650
1651    def replace(self, thread: str, input: ThreadReplaceInput) -> Thread:
1652        """
1653        Update a thread
1654        Updates one or more mutable properties of the specified thread and returns
1655        the full thread object with the applied changes. Only the fields you provide
1656        are modified; omitted fields retain their current values.
1657        If `profile_picture` is supplied, the image is uploaded before the other
1658        fields are saved, after all ordinary thread fields have passed validation.
1659        Supplying invalid base64 picture data returns 422 and no other fields are
1660        updated.
1661        Visibility can only widen: `private` may become `restricted` or `team`, and
1662        `restricted` may become `team`. The authenticated viewer must have
1663        permission to modify the thread.
1664        Mirror-thread titles, descriptions, and notification state remain editable
1665        by privileged app viewers. Mirror metadata, visibility, and membership are
1666        provider-managed and cannot be changed through this endpoint.
1667
1668        Args:
1669            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1670            input: Request body.
1671            input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
1672            input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
1673            input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user.
1674            input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
1675            input.title: Human-readable display name for the thread. Replaces the existing title when provided.
1676            input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed.
1677
1678        Returns:
1679            The thread object after the update has been applied.
1680        """
1681        return self._http.request(
1682            f"/api/v1/threads/{thread}",
1683            method="PUT",
1684            body=input,
1685            response_type=Thread,
1686        )
1687
1688    def agents(self, thread: str) -> ThreadAgentsResponse:
1689        """
1690        List agents in a thread
1691        Returns the agents participating in the specified thread. Only personal user
1692        threads (threads owned by a single user, not a team) expose agents through
1693        this endpoint; requests for team threads return 404.
1694        The authenticated user must have visibility into the thread. Each agent entry
1695        includes display information such as name and profile picture. Thread-level
1696        overrides (e.g. a custom name or profile picture set for this thread) take
1697        precedence over the agent's default values. When the caller is the thread
1698        owner, each entry also includes an `agent_config` object describing the
1699        agent's message policy and context configuration.
1700
1701        Args:
1702            thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user.
1703
1704        Returns:
1705            Successful response
1706        """
1707        return self._http.request(
1708            f"/api/v1/threads/{thread}/agents",
1709            response_type=ThreadAgentsResponse,
1710        )
1711
1712    def artifacts(self, thread: str) -> ThreadArtifactsResponse:
1713        """
1714        List artifacts for a thread
1715        Returns all artifacts produced during a thread's AI conversation. Artifacts are
1716        structured outputs such as code files, documents, or generated assets created
1717        by the AI agent in response to messages in the thread.
1718        The authenticated user must have access to the specified thread. Results are
1719        returned in a single page; there is no cursor-based pagination for this endpoint.
1720
1721        Args:
1722            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user.
1723
1724        Returns:
1725            Successful response
1726        """
1727        return self._http.request(
1728            f"/api/v1/threads/{thread}/artifacts",
1729            response_type=ThreadArtifactsResponse,
1730        )
1731
1732    def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None:
1733        """
1734        Mark a thread as read
1735        Records that a user has read up to a specific message in the thread. Unread
1736        indicators and badge counts are cleared up to the specified message.
1737        You must supply exactly one of `last_read_message` or `use_latest_message`.
1738        Omitting both returns 400. If `use_latest_message` is `true` and the thread
1739        has no messages, the request succeeds silently with no state change.
1740        For server-to-server (S2S) requests where no user identity is present in the
1741        token, the `user` param is required to identify whose read state to update.
1742
1743        Args:
1744            thread: Thread ID (`thr_...`). The thread to mark as read.
1745            input: Request body.
1746            input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`.
1747            input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`.
1748            input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
1749
1750        Returns:
1751            Empty response on success.
1752        """
1753        self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input)
1754
1755    def messages(
1756        self,
1757        thread: str,
1758        *,
1759        before_cursor: str | None = None,
1760        after_cursor: str | None = None,
1761        metadata: dict[str, Any] | None = None,
1762        limit: int | None = None,
1763        anchor: str | None = None,
1764        direction: Literal["before", "after", "around"] | None = None,
1765        before_limit: int | None = None,
1766        after_limit: int | None = None,
1767        include_anchor: bool | None = None,
1768        anchor_agent_mode: Literal["cli", "embedded"] | None = None,
1769        anchor_agent: str | None = None,
1770        include_reply_counts: bool | None = None,
1771    ) -> ThreadMessagesResponse:
1772        """
1773        List messages in a thread
1774        Returns a cursor-paginated list of messages belonging to the specified thread,
1775        ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both
1776        to page through or bound the result set; omit both to receive the most recent page.
1777        Supply `anchor` and `direction` to fetch a window before, after, or around a
1778        specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to
1779        resolve the anchor from the latest embedded-agent message, and add
1780        `anchor_agent` to scope that resolution to a single sender agent.
1781        Supply `metadata` as a JSON-encoded structured expression to filter message
1782        metadata before cursor pagination or anchored window limits are applied.
1783        The authenticated user must have access to the thread's owner (workspace or user).
1784        A 403 is returned if the thread exists but is not accessible to the caller; a 404
1785        is returned if the thread does not exist or is not visible to the authenticated user.
1786        Pass `include_reply_counts: true` to annotate each message with the number of
1787        threaded replies it has received. This adds a small amount of latency and should
1788        be omitted when reply counts are not needed.
1789
1790        Args:
1791            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1792            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.
1793            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.
1794            metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits.
1795            limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
1796            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`.
1797            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`.
1798            before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100.
1799            after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100.
1800            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.
1801            anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode.
1802            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.
1803            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.
1804
1805        Returns:
1806            Successful response
1807        """
1808        query: dict[str, object] = {}
1809        if before_cursor is not None:
1810            query["before_cursor"] = before_cursor
1811        if after_cursor is not None:
1812            query["after_cursor"] = after_cursor
1813        if metadata is not None:
1814            query["metadata"] = metadata
1815        if limit is not None:
1816            query["limit"] = limit
1817        if anchor is not None:
1818            query["anchor"] = anchor
1819        if direction is not None:
1820            query["direction"] = direction
1821        if before_limit is not None:
1822            query["before_limit"] = before_limit
1823        if after_limit is not None:
1824            query["after_limit"] = after_limit
1825        if include_anchor is not None:
1826            query["include_anchor"] = include_anchor
1827        if anchor_agent_mode is not None:
1828            query["anchor_agent_mode"] = anchor_agent_mode
1829        if anchor_agent is not None:
1830            query["anchor_agent"] = anchor_agent
1831        if include_reply_counts is not None:
1832            query["include_reply_counts"] = include_reply_counts
1833        return self._http.request(
1834            f"/api/v1/threads/{thread}/messages",
1835            query=query,
1836            response_type=ThreadMessagesResponse,
1837        )
1838
1839    def picture(self, thread: str, input: ThreadPictureInput) -> Thread:
1840        """
1841        Update a thread's profile picture
1842        Uploads a new profile picture for the specified thread and returns the updated
1843        thread object. The image must be supplied as a base64-encoded string with its
1844        MIME type.
1845        The authenticated user must own the thread or be a team owner of the workspace
1846        the thread belongs to. Supplying invalid base64 data returns 422.
1847
1848        Args:
1849            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1850            input: Request body.
1851            input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
1852
1853        Returns:
1854            The thread object after the profile picture has been updated.
1855        """
1856        return self._http.request(
1857            f"/api/v1/threads/{thread}/picture",
1858            method="PUT",
1859            body=input,
1860            response_type=Thread,
1861        )
1862
1863    def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus:
1864        """
1865        Retrieve a thread's read status
1866        Returns the read status of a thread for the specified user, including the ID
1867        of the last message they have read and the number of unread messages remaining.
1868        For user-authenticated requests, the status is always returned for the
1869        authenticated user and the `user` parameter is ignored. For server-to-server
1870        (S2S) requests, the `user` parameter is required and must be a valid user ID.
1871        Returns 404 if the thread does not exist or the caller does not have access
1872        to it.
1873
1874        Args:
1875            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user.
1876            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.
1877
1878        Returns:
1879            The read status record for the requested thread and user.
1880        """
1881        query: dict[str, object] = {}
1882        if user is not None:
1883            query["user"] = user
1884        return self._http.request(
1885            f"/api/v1/threads/{thread}/read_status",
1886            query=query,
1887            response_type=ThreadReadStatus,
1888        )
1889
1890    def search(
1891        self,
1892        thread: str,
1893        q: str,
1894        *,
1895        app: str | None = None,
1896        limit: int | None = None,
1897        mode: Literal["text", "embedding", "hybrid"] | None = None,
1898        before_cursor: str | None = None,
1899        after_cursor: str | None = None,
1900    ) -> ThreadSearchResponse:
1901        """
1902        Search messages in a thread
1903        Searches canonical message content in the specified thread. `"text"` mode
1904        performs the existing case-insensitive substring search, `"embedding"` ranks
1905        stored message embeddings by cosine similarity, and `"hybrid"` combines the
1906        text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages
1907        visible to the authenticated caller are considered.
1908        Results are intentionally lean: each row contains only a bounded content
1909        snippet, sender identity, and timestamp. Attachments, reactions, ACLs, and
1910        metadata are neither hydrated nor serialized. At most 20 results are
1911        returned. Text results support chronological cursor pagination. Embedding and
1912        hybrid results are relevance-ranked single pages and return null cursors.
1913
1914        Args:
1915            thread: Thread ID (`thr_...`). Must be visible to the authenticated caller.
1916            app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount.
1917            q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
1918            limit: Maximum number of results. Defaults to 20 and is capped at 20.
1919            mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings.
1920            before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
1921            after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
1922
1923        Returns:
1924            Successful response
1925        """
1926        query: dict[str, object] = {}
1927        if app is not None:
1928            query["app"] = app
1929        query["q"] = q
1930        if limit is not None:
1931            query["limit"] = limit
1932        if mode is not None:
1933            query["mode"] = mode
1934        if before_cursor is not None:
1935            query["before_cursor"] = before_cursor
1936        if after_cursor is not None:
1937            query["after_cursor"] = after_cursor
1938        return self._http.request(
1939            f"/api/v1/threads/{thread}/search",
1940            query=query,
1941            response_type=ThreadSearchResponse,
1942        )
1943
1944    def trajectories(
1945        self,
1946        thread: str,
1947        *,
1948        before_cursor: str | None = None,
1949        after_cursor: str | None = None,
1950        limit: int | None = None,
1951        message: str | None = None,
1952    ) -> ThreadTrajectoriesResponse:
1953        """
1954        List trajectories for a thread
1955        Returns a cursor-paginated list of thread message trajectories associated with the
1956        specified thread. Each trajectory links a user message and its agent response to the
1957        underlying AI trajectory record that captured the model's reasoning steps.
1958        The authenticated user must own the thread or be a member of the workspace it belongs
1959        to. Results are returned in reverse chronological order by default. Use `before_cursor`
1960        and `after_cursor` to navigate pages; provide at most one cursor per request.
1961        Optionally filter results to trajectories produced in response to a specific message
1962        by supplying the `message` parameter. When no trajectories match the query, `data`
1963        is an empty array and both cursor fields are `null`. A cursor that cannot be decoded
1964        returns a 400 `invalid_cursor` error.
1965
1966        Args:
1967            thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace.
1968            before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position.
1969            after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position.
1970            limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
1971            message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message.
1972
1973        Returns:
1974            Successful response
1975        """
1976        query: dict[str, object] = {}
1977        if before_cursor is not None:
1978            query["before_cursor"] = before_cursor
1979        if after_cursor is not None:
1980            query["after_cursor"] = after_cursor
1981        if limit is not None:
1982            query["limit"] = limit
1983        if message is not None:
1984            query["message"] = message
1985        return self._http.request(
1986            f"/api/v1/threads/{thread}/trajectories",
1987            query=query,
1988            response_type=ThreadTrajectoriesResponse,
1989        )
class ThreadMemberCreateInput(typing.TypedDict):
18class ThreadMemberCreateInput(TypedDict, total=False):
19    "Add a member to a thread"
20
21    agent: str | None
22    'Agent ID of the principal to add. Required when `type` is `"agent"`.'
23    membership_type: str | None
24    'Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.'
25    type: Required[str]
26    'Kind of principal being added. Must be `"user"` or `"agent"`.'
27    user: str | None
28    '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):
31class SettingReplaceInput(TypedDict):
32    "Update thread settings"
33
34    settings: dict[str, Any]
35    "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 TagCreateInput(typing.TypedDict):
38class TagCreateInput(TypedDict):
39    "Add tags to a thread"
40
41    tags: list[str]
42    "Tags to add to the thread."

Add tags to a thread

tags: list[str]

Tags to add to the thread.

class TagReplaceInput(typing.TypedDict):
45class TagReplaceInput(TypedDict):
46    "Replace a thread's tags"
47
48    tags: list[str]
49    "The complete set of tags for the thread. An empty array clears all tags."

Replace a thread's tags

tags: list[str]

The complete set of tags for the thread. An empty array clears all tags.

class ThreadReplaceInputProfilePicture(typing.TypedDict):
52class ThreadReplaceInputProfilePicture(TypedDict, total=False):
53    data: str | None
54    "Base64-encoded image payload. Must be a valid base64 string."
55    filename: str | None
56    'Original filename of the image, e.g. `"avatar.png"`. Used for storage metadata.'
57    mime_type: str | None
58    '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):
61class ThreadReplaceInput(TypedDict, total=False):
62    "Update a thread"
63
64    description: str | None
65    "Optional longer text describing the thread's purpose. Replaces the existing description when provided."
66    metadata: dict[str, Any] | None
67    "Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata."
68    muted: bool | None
69    "When `true`, suppresses notifications for new messages in this thread for the authenticated user."
70    profile_picture: ThreadReplaceInputProfilePicture | None
71    "New profile picture for the thread. Provide all three inner fields to replace the existing image."
72    title: str | None
73    "Human-readable display name for the thread. Replaces the existing title when provided."
74    visibility: Literal["private", "restricted", "team"] | None
75    "Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed."

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.

visibility: Optional[Literal['team', 'restricted', 'private']]

Widen a team-owned thread: private may become restricted or team, and restricted may become team. Visibility cannot be narrowed.

class ThreadMarkReadInput(typing.TypedDict):
78class ThreadMarkReadInput(TypedDict, total=False):
79    "Mark a thread as read"
80
81    last_read_message: str | None
82    "Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`."
83    use_latest_message: bool | None
84    "When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`."
85    user: str | None
86    "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):
89class ThreadPictureInputPicture(TypedDict):
90    data: str
91    "Base64-encoded binary content of the image file."
92    filename: str
93    'Original filename of the image, e.g. `"avatar.png"`. Used for storage and display.'
94    mime_type: str
95    '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):
 98class ThreadPictureInput(TypedDict):
 99    "Update a thread's profile picture"
100
101    picture: ThreadPictureInputPicture
102    "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 ThreadMemberListResponseDataItemAgent(pydantic.main.BaseModel):
105class ThreadMemberListResponseDataItemAgent(BaseModel):
106    email: str | None = Field(
107        default=None, description="Agent email address. `null` if not configured."
108    )
109    id: str = Field(..., description="Agent ID (`agi_...`).")
110    name: str | None = Field(
111        default=None, description="Human-readable agent name. `null` if not set."
112    )
113    org: str | None = Field(
114        default=None,
115        description="Organization that owns this agent (`org_...`). `null` if not org-scoped.",
116    )
117    team: str | None = Field(
118        default=None,
119        description="Team that owns this agent (`tem_...`). `null` if not team-scoped.",
120    )
121    user: str | None = Field(
122        default=None,
123        description="User that owns this agent (`usr_...`). `null` if not user-scoped.",
124    )

!!! 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.
email: str | None = None

Agent email address. null if not configured.

id: str = PydanticUndefined

Agent ID (agi_...).

name: str | None = None

Human-readable agent name. null if not set.

org: str | None = None

Organization that owns this agent (org_...). null if not org-scoped.

team: str | None = None

Team that owns this agent (tem_...). null if not team-scoped.

user: str | None = None

User that owns this agent (usr_...). null if not user-scoped.

class ThreadMemberListResponseDataItemUser(pydantic.main.BaseModel):
127class ThreadMemberListResponseDataItemUser(BaseModel):
128    email: str | None = Field(default=None, description="User's email address. `null` if not set.")
129    full_name: str | None = Field(
130        default=None, description="Backward-compatible alias of `name`. `null` if not set."
131    )
132    id: str = Field(..., description="User ID (`usr_...`).")
133    name: str | None = Field(
134        default=None, description="Full display name of the user. `null` if not set."
135    )
136    org: str | None = Field(
137        default=None,
138        description="Organization this user belongs to (`org_...`). `null` if the user is not org-scoped.",
139    )

!!! 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.
email: str | None = None

User's email address. null if not set.

full_name: str | None = None

Backward-compatible alias of name. null if not set.

id: str = PydanticUndefined

User ID (usr_...).

name: str | None = None

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

org: str | None = None

Organization this user belongs to (org_...). null if the user is not org-scoped.

class ThreadMemberListResponseDataItem(pydantic.main.BaseModel):
142class ThreadMemberListResponseDataItem(BaseModel):
143    agent: ThreadMemberListResponseDataItemAgent | None = Field(
144        default=None,
145        description="Roster-safe agent identity. Populated for agent members; `null` for users.",
146    )
147    joined_at: datetime | None = Field(
148        default=None, description="When this member joined the thread (ISO 8601)."
149    )
150    member_type: str | None = Field(
151        default=None, description="Backward-compatible alias of `type`."
152    )
153    membership_type: str | None = Field(
154        default=None, description='Role of this member, commonly `"owner"` or `"member"`.'
155    )
156    role: str | None = Field(
157        default=None, description="Backward-compatible alias of `membership_type`."
158    )
159    type: str = Field(..., description='Kind of participant. One of `"user"` or `"agent"`.')
160    user: ThreadMemberListResponseDataItemUser | None = Field(
161        default=None,
162        description="Roster-safe user identity. Populated for user members; `null` for agents.",
163    )

!!! 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.

Roster-safe agent identity. Populated for agent members; null for users.

joined_at: datetime.datetime | None = None

When this member joined the thread (ISO 8601).

member_type: str | None = None

Backward-compatible alias of type.

membership_type: str | None = None

Role of this member, commonly "owner" or "member".

role: str | None = None

Backward-compatible alias of membership_type.

type: str = PydanticUndefined

Kind of participant. One of "user" or "agent".

Roster-safe user identity. Populated for user members; null for agents.

class ThreadMemberListResponse(pydantic.main.BaseModel):
166class ThreadMemberListResponse(BaseModel):
167    """
168    Successful response
169    """
170
171    data: list[ThreadMemberListResponseDataItem] = Field(
172        ...,
173        description="Array of thread member objects representing all current members of the thread.",
174    )

Successful response

data: list[ThreadMemberListResponseDataItem] = PydanticUndefined

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

class SettingListResponse(pydantic.main.BaseModel):
177class SettingListResponse(BaseModel):
178    """
179    Successful response
180    """
181
182    agent_enabled: bool | None = Field(
183        default=None,
184        description="Whether the AI agent is active for this thread. Defaults to `true` when no settings have been explicitly set.",
185    )

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):
188class ThreadAgentsResponse(BaseModel):
189    """
190    Successful response
191    """
192
193    data: list[dict[str, Any]] = Field(
194        ...,
195        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.",
196    )

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):
199class ThreadArtifactsResponseDataItemImageSource(BaseModel):
200    file: str | None = Field(
201        default=None,
202        description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.",
203    )
204    height: int | None = Field(
205        default=None, description="Height of the image in pixels. `null` if not known."
206    )
207    media: str | None = Field(
208        default=None,
209        description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.",
210    )
211    mime_type: str | None = Field(
212        default=None,
213        description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.',
214    )
215    refresh_url: str | None = Field(
216        default=None,
217        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.",
218    )
219    url: str | None = Field(
220        default=None,
221        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.",
222    )
223    width: int | None = Field(
224        default=None, description="Width of the image in pixels. `null` if not known."
225    )

!!! 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):
228class ThreadArtifactsResponseDataItem(BaseModel):
229    agent: str | None = Field(
230        default=None,
231        description="ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.",
232    )
233    content_type: str | None = Field(
234        default=None,
235        description='MIME type of the current version\'s file, e.g. `"text/csv"` or `"image/png"`. `null` if no file is attached.',
236    )
237    created_at: datetime | None = Field(
238        default=None, description="When the artifact was first created (ISO 8601)."
239    )
240    current_version: str | None = Field(
241        default=None,
242        description="ID of the current (latest published) artifact version (`artv_...`). `null` if no version has been published.",
243    )
244    description: str | None = Field(
245        default=None,
246        description="Optional longer description of the artifact's contents or purpose. `null` if not set.",
247    )
248    file: str | None = Field(
249        default=None,
250        description="Storage file ID for the current version (`fil_...`). `null` if no file is attached.",
251    )
252    file_name: str | None = Field(
253        default=None,
254        description='Original filename of the current version\'s file, e.g. `"output.csv"`. `null` if no file is attached.',
255    )
256    file_url: str | None = Field(
257        default=None,
258        description="Short-lived signed URL for downloading the current version's file. `null` if no file is attached.",
259    )
260    id: str = Field(..., description="Artifact ID (`art_...`).")
261    image_source: ThreadArtifactsResponseDataItemImageSource | None = Field(
262        default=None,
263        description='Image source metadata for rendering the current version\'s file inline. Present only when `content_type` starts with `"image/"`. `null` otherwise.',
264    )
265    name: str | None = Field(
266        default=None,
267        description='Human-readable name for the artifact, e.g. `"Q2 Report"`. `null` if not set.',
268    )
269    org: str | None = Field(
270        default=None, description="ID of the organization this artifact belongs to (`org_...`)."
271    )
272    sandbox: str | None = Field(
273        default=None,
274        description="Identifier of the sandbox environment associated with this artifact. `null` if not sandbox-scoped.",
275    )
276    team: str | None = Field(
277        default=None,
278        description="ID of the team that owns this artifact (`tea_...`). `null` if not team-scoped.",
279    )
280    thread: str | None = Field(
281        default=None,
282        description="ID of the thread in which this artifact was created (`thr_...`). `null` if not thread-scoped.",
283    )
284    updated_at: datetime | None = Field(
285        default=None, description="When the artifact record was last modified (ISO 8601)."
286    )
287    user: str | None = Field(
288        default=None,
289        description="ID of the user who created this artifact (`usr_...`). `null` if not user-scoped.",
290    )
291    version: int | None = Field(
292        default=None,
293        description="Current version number of the artifact. Increments each time a new version is published.",
294    )

!!! 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):
297class ThreadArtifactsResponse(BaseModel):
298    """
299    Successful response
300    """
301
302    data: list[ThreadArtifactsResponseDataItem] = Field(
303        ..., description="Array of artifact objects produced during the thread's conversation."
304    )

Successful response

data: list[ThreadArtifactsResponseDataItem] = PydanticUndefined

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

class ThreadMessagesResponseDataMessagesItemAclAddItem(pydantic.main.BaseModel):
307class ThreadMessagesResponseDataMessagesItemAclAddItem(BaseModel):
308    actions: list[str] = Field(
309        ...,
310        description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.',
311    )
312    principal: str | None = Field(
313        default=None,
314        description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.',
315    )
316    principal_type: str = Field(
317        ...,
318        description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.',
319    )

!!! 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.
actions: list[str] = PydanticUndefined

Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.

principal: str | None = None

The identifier of the principal. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role"; omit entirely when principal_type is "everyone".

principal_type: str = PydanticUndefined

The kind of principal receiving the grant. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadMessagesResponseDataMessagesItemAclGrantsItem(pydantic.main.BaseModel):
322class ThreadMessagesResponseDataMessagesItemAclGrantsItem(BaseModel):
323    actions: list[str] = Field(
324        ...,
325        description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.',
326    )
327    principal: str | None = Field(
328        default=None,
329        description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.',
330    )
331    principal_type: str = Field(
332        ...,
333        description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.',
334    )

!!! 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.
actions: list[str] = PydanticUndefined

Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.

principal: str | None = None

The identifier of the principal. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role"; omit entirely when principal_type is "everyone".

principal_type: str = PydanticUndefined

The kind of principal receiving the grant. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadMessagesResponseDataMessagesItemAclRemoveItem(pydantic.main.BaseModel):
337class ThreadMessagesResponseDataMessagesItemAclRemoveItem(BaseModel):
338    principal: str | None = Field(
339        default=None,
340        description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.',
341    )
342    principal_type: str = Field(
343        ...,
344        description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.',
345    )

!!! 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.
principal: str | None = None

The identifier of the principal to remove. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role". Omit when principal_type is "everyone".

principal_type: str = PydanticUndefined

The kind of principal to remove. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadMessagesResponseDataMessagesItemAcl(pydantic.main.BaseModel):
348class ThreadMessagesResponseDataMessagesItemAcl(BaseModel):
349    add: list[ThreadMessagesResponseDataMessagesItemAclAddItem] | None = Field(
350        default=None,
351        description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.",
352    )
353    grants: list[ThreadMessagesResponseDataMessagesItemAclGrantsItem] | None = Field(
354        default=None,
355        description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.",
356    )
357    remove: list[ThreadMessagesResponseDataMessagesItemAclRemoveItem] | None = Field(
358        default=None,
359        description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.",
360    )

!!! 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.

Patch mode: grants to add or merge into the existing list. Cannot be combined with grants.

Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array ([]) to clear all grants. Cannot be combined with add or remove.

Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.

class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(pydantic.main.BaseModel):
363class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(BaseModel):
364    file: str | None = Field(
365        default=None,
366        description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.",
367    )
368    height: int | None = Field(
369        default=None, description="Height of the image in pixels. `null` if not known."
370    )
371    media: str | None = Field(
372        default=None,
373        description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.",
374    )
375    mime_type: str | None = Field(
376        default=None,
377        description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.',
378    )
379    refresh_url: str | None = Field(
380        default=None,
381        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.",
382    )
383    url: str | None = Field(
384        default=None,
385        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.",
386    )
387    width: int | None = Field(
388        default=None, description="Width of the image in pixels. `null` if not known."
389    )

!!! 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):
392class ThreadMessagesResponseDataMessagesItemActorsItem(BaseModel):
393    alias: str | None = Field(
394        default=None,
395        description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.",
396    )
397    id: str | None = Field(
398        default=None,
399        description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.',
400    )
401    name: str | None = Field(
402        default=None,
403        description="Display name of the actor shown in the UI. `null` if no name is set.",
404    )
405    profile_picture: ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture | None = Field(
406        default=None,
407        description="Profile picture for the actor. `null` if the actor has no profile picture.",
408    )

!!! 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):
411class ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource(BaseModel):
412    file: str | None = Field(
413        default=None,
414        description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.",
415    )
416    height: int | None = Field(
417        default=None, description="Height of the image in pixels. `null` if not known."
418    )
419    media: str | None = Field(
420        default=None,
421        description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.",
422    )
423    mime_type: str | None = Field(
424        default=None,
425        description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.',
426    )
427    refresh_url: str | None = Field(
428        default=None,
429        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.",
430    )
431    url: str | None = Field(
432        default=None,
433        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.",
434    )
435    width: int | None = Field(
436        default=None, description="Width of the image in pixels. `null` if not known."
437    )

!!! 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):
440class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource(BaseModel):
441    file: str | None = Field(
442        default=None,
443        description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.",
444    )
445    height: int | None = Field(
446        default=None, description="Height of the image in pixels. `null` if not known."
447    )
448    media: str | None = Field(
449        default=None,
450        description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.",
451    )
452    mime_type: str | None = Field(
453        default=None,
454        description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.',
455    )
456    refresh_url: str | None = Field(
457        default=None,
458        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.",
459    )
460    url: str | None = Field(
461        default=None,
462        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.",
463    )
464    width: int | None = Field(
465        default=None, description="Width of the image in pixels. `null` if not known."
466    )

!!! 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):
469class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem(BaseModel):
470    content_type: str | None = Field(
471        default=None,
472        description='MIME type of this variant\'s file (e.g., `"image/jpeg"`, `"video/mp4"`). `null` if the file is not loaded.',
473    )
474    created_at: datetime | None = Field(
475        default=None, description="When this variant was created (ISO 8601)."
476    )
477    file: str | None = Field(
478        default=None,
479        description="ID of the underlying storage file that backs this variant (`fil_...`).",
480    )
481    filename: str | None = Field(
482        default=None,
483        description="Original filename of the uploaded file for this variant. `null` if the file is not loaded.",
484    )
485    height: int | None = Field(
486        default=None, description="Height of this variant in pixels. `null` if not recorded."
487    )
488    id: str = Field(..., description="Media variant ID (`mvr_...`).")
489    image_source: (
490        ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource | None
491    ) = Field(
492        default=None,
493        description="Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types.",
494    )
495    updated_at: datetime | None = Field(
496        default=None, description="When this variant was last updated (ISO 8601)."
497    )
498    url: str | None = Field(
499        default=None,
500        description="Signed download URL for this variant, resolved at request time. `null` if the file is unavailable.",
501    )
502    variant_key: str | None = Field(
503        default=None,
504        description='Identifier for this variant\'s processing tier. Common values include `"original"` (the unmodified upload) and `"thumbnail"` (a resized preview).',
505    )
506    width: int | None = Field(
507        default=None, description="Width of this variant in pixels. `null` if not recorded."
508    )

!!! 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):
511class ThreadMessagesResponseDataMessagesItemAttachmentsItem(BaseModel):
512    content_type: str | None = Field(
513        default=None,
514        description='MIME type of the attached file, e.g. `"image/png"` or `"application/pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.',
515    )
516    description: str | None = Field(
517        default=None,
518        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.",
519    )
520    filename: str | None = Field(
521        default=None,
522        description='Original filename of the attached file, e.g. `"report.pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.',
523    )
524    height: int | None = Field(
525        default=None,
526        description="Height in pixels of the media item. Present on `media` type only. `null` otherwise.",
527    )
528    id: str = Field(..., description="Unique identifier for this attachment within the message.")
529    image_height: int | None = Field(
530        default=None,
531        description="Height in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.",
532    )
533    image_source: ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource | None = Field(
534        default=None,
535        description="Image source metadata for inline rendering. Present on `file`, `scraped_link`, `artifact`, and `media` types when the content is an image. `null` otherwise.",
536    )
537    image_url: str | None = Field(
538        default=None,
539        description="URL of the preview image extracted from the scraped page. Present on `scraped_link` type only. `null` otherwise.",
540    )
541    image_width: int | None = Field(
542        default=None,
543        description="Width in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.",
544    )
545    media_type: str | None = Field(
546        default=None,
547        description='The media category, e.g. `"video"` or `"audio"`. Present on `media` type only; omitted otherwise.',
548    )
549    name: str | None = Field(
550        default=None,
551        description="Display name of the media item. Present on `media` type only. `null` otherwise.",
552    )
553    object: dict[str, Any] | None = Field(
554        default=None,
555        description="The full embedded object payload. For `task` type, contains the task record. For `action` type, contains the action definition. For `chart` type, contains the chart with its inline `spec`. Omitted on other types.",
556    )
557    title: str | None = Field(
558        default=None,
559        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.",
560    )
561    type: str = Field(
562        ...,
563        description='The attachment type. One of `"file"`, `"scraped_link"`, `"artifact"`, `"task"`, `"media"`, `"action"`, or `"chart"`. Determines which additional fields are present.',
564    )
565    url: str | None = Field(
566        default=None,
567        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.",
568    )
569    variants: list[ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem] | None = (
570        Field(
571            default=None,
572            description="Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.",
573        )
574    )
575    version: int | None = Field(
576        default=None,
577        description="Version number of the attached artifact at the time of attachment. Present on `artifact` type only. `null` otherwise.",
578    )
579    width: int | None = Field(
580        default=None,
581        description="Width in pixels of the media item. Present on `media` type only. `null` otherwise.",
582    )

!!! 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; omitted 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. For chart type, contains the chart with its inline spec. Omitted 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", "action", or "chart". 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; omitted 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):
585class ThreadMessagesResponseDataMessagesItemReactionsItem(BaseModel):
586    payload: dict[str, Any] | None = Field(
587        default=None,
588        description='Type-specific reaction data. For `"emoji_reaction"` reactions, contains an `emoji` key with the Unicode emoji string (e.g., `" "`).',
589    )
590    type: str = Field(
591        ...,
592        description='Reaction type identifier. Currently always `"emoji_reaction"` for emoji-based reactions.',
593    )
594    user: str | None = Field(
595        default=None, description="Public ID of the user who added the reaction (`usr_...`)."
596    )

!!! 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):
599class ThreadMessagesResponseDataMessagesItem(BaseModel):
600    acl: ThreadMessagesResponseDataMessagesItemAcl | None = Field(
601        default=None,
602        description="Access control list for private messages (grants with `read` action). Only returned to resource owners (and privileged/org-admin viewers) via server-side `field_redactions: [acl: :owner]`; `null` for everyone else.",
603    )
604    actors: list[ThreadMessagesResponseDataMessagesItemActorsItem] | None = Field(
605        default=None,
606        description="Resolved actor descriptors for the message sender, combining identity and display metadata. Always contains exactly one entry.",
607    )
608    agent: str | None = Field(
609        default=None,
610        description="ID of the agent user that sent this message (`agi_...`). `null` for messages sent by human users.",
611    )
612    agent_mode: Literal["cli", "embedded"] | None = Field(
613        default=None,
614        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.",
615    )
616    attachments: list[ThreadMessagesResponseDataMessagesItemAttachmentsItem] | None = Field(
617        default=None,
618        description="Files, links, tasks, media, artifacts, and actions attached to this message. Empty array if there are no attachments.",
619    )
620    branched_thread: str | None = Field(
621        default=None,
622        description="ID of the thread that was branched from this message (`thr_...`). `null` if this message has not spawned a branch thread.",
623    )
624    content: str | None = Field(
625        default=None,
626        description="Text content of the message. `null` for messages that contain only attachments.",
627    )
628    created_at: str | None = Field(
629        default=None, description="When the message was posted (ISO 8601)."
630    )
631    has_replies: bool | None = Field(
632        default=None,
633        description="Whether this message has at least one reply. Only present when explicitly requested or computed by the server.",
634    )
635    id: str = Field(..., description="Message ID (`msg_...`).")
636    idempotency_key: str | None = Field(
637        default=None,
638        description="Client-supplied idempotency key used to deduplicate message sends. `null` if the sender did not provide one.",
639    )
640    is_deleted: bool | None = Field(
641        default=None,
642        description="Whether this message is a deletion tombstone. `true` only on the `message_updated` broadcast emitted when a message is deleted: the original content is replaced with a placeholder and the message no longer exists on the server. Always `false` for live messages.",
643    )
644    legacy_agent: str | None = Field(
645        default=None,
646        description="Identifier of the legacy chat agent that sent this message, if applicable. `null` for messages sent by users or modern agent users.",
647    )
648    metadata: dict[str, Any] | None = Field(
649        default=None,
650        description="Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.",
651    )
652    org: str | None = Field(
653        default=None, description="ID of the organization that owns this message (`org_...`)."
654    )
655    reactions: list[ThreadMessagesResponseDataMessagesItemReactionsItem] | None = Field(
656        default=None,
657        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.",
658    )
659    rendering_mode: str | None = Field(
660        default=None,
661        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.',
662    )
663    replies: list[dict[str, Any]] | None = Field(
664        default=None,
665        description="Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.",
666    )
667    replies_after_cursor: str | None = Field(
668        default=None,
669        description="Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.",
670    )
671    replies_before_cursor: str | None = Field(
672        default=None,
673        description="Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.",
674    )
675    reply_count: int | None = Field(
676        default=None,
677        description="Total number of direct replies to this message. Only present when explicitly requested or computed by the server.",
678    )
679    reply_to: dict[str, Any] | None = Field(
680        default=None,
681        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.",
682    )
683    root_message_id: str | None = Field(
684        default=None,
685        description="ID of the root message in this reply chain (`msg_...`). `null` for a top-level message. The value is persisted when the reply is created, so callers can correlate a multi-turn session without walking parent messages.",
686    )
687    sandbox: str | None = Field(
688        default=None,
689        description="ID of the developer sandbox this message belongs to (`dsb_...`). `null` for non-sandbox messages.",
690    )
691    team: str | None = Field(
692        default=None,
693        description="ID of the team this message is scoped to (`tem_...`). `null` if the message is not team-scoped.",
694    )
695    thread: str | None = Field(
696        default=None, description="ID of the thread this message belongs to (`thr_...`)."
697    )
698    type: str | None = Field(
699        default=None,
700        description="Optional client-defined classification for the message (for example `note` or `status`). Free-form string up to 64 characters. The value `system` is reserved for platform-authored messages and cannot be set by clients. `null` when unset.",
701    )
702    user: str | dict[str, Any] | None = Field(
703        default=None,
704        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.",
705    )
706    visibility: Literal["default", "private"] | None = Field(
707        default=None,
708        description="Message-level visibility. `default` is visible to anyone who can see the parent thread. `private` is restricted to the sender and explicit ACL `read` grantees.",
709    )

!!! 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.

Access control list for private messages (grants with read action). Only returned to resource owners (and privileged/org-admin viewers) via server-side field_redactions: [acl: :owner]; null for everyone else.

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: str | 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.

is_deleted: bool | None = None

Whether this message is a deletion tombstone. true only on the message_updated broadcast emitted when a message is deleted: the original content is replaced with a placeholder and the message no longer exists on the server. Always false for live messages.

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.

root_message_id: str | None = None

ID of the root message in this reply chain (msg_...). null for a top-level message. The value is persisted when the reply is created, so callers can correlate a multi-turn session without walking parent messages.

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_...).

type: str | None = None

Optional client-defined classification for the message (for example note or status). Free-form string up to 64 characters. The value system is reserved for platform-authored messages and cannot be set by clients. null when unset.

user: str | dict[str, typing.Any] | 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.

visibility: Optional[Literal['default', 'private']] = None

Message-level visibility. default is visible to anyone who can see the parent thread. private is restricted to the sender and explicit ACL read grantees.

class ThreadMessagesResponseData(pydantic.main.BaseModel):
712class ThreadMessagesResponseData(BaseModel):
713    after_cursor: str | None = Field(
714        default=None,
715        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.",
716    )
717    anchor: str | None = Field(
718        default=None,
719        description="Message ID used as the anchor for a windowed query. `null` for ordinary cursor pagination.",
720    )
721    before_cursor: str | None = Field(
722        default=None,
723        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.",
724    )
725    messages: list[ThreadMessagesResponseDataMessagesItem] = Field(
726        ..., description="Ordered array of message objects for this page of results."
727    )

!!! 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):
730class ThreadMessagesResponse(BaseModel):
731    """
732    Successful response
733    """
734
735    data: ThreadMessagesResponseData = Field(
736        ...,
737        description="Pagination envelope containing the messages for this page along with cursors for adjacent pages.",
738    )

Successful response

data: ThreadMessagesResponseData = PydanticUndefined

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

class ThreadSearchResponseDataItem(pydantic.main.BaseModel):
741class ThreadSearchResponseDataItem(BaseModel):
742    agent: str | None = Field(
743        default=None,
744        description="Agent sender ID (`agi_...`), or `null` when a human sent the message.",
745    )
746    content: str = Field(
747        ...,
748        description="A bounded snippet around the first matching occurrence (at most 240 characters).",
749    )
750    created_at: datetime = Field(..., description="When the message was posted.")
751    id: str = Field(..., description="Message ID (`msg_...`).")
752    similarity_score: float | None = Field(
753        default=None,
754        description="Cosine similarity to the query when the result participated in embedding search, or `null` in text mode and for text-only hybrid matches.",
755    )
756    user: str | None = Field(
757        default=None,
758        description="Human sender ID (`usr_...`), or `null` when an agent sent the message.",
759    )

!!! 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

Agent sender ID (agi_...), or null when a human sent the message.

content: str = PydanticUndefined

A bounded snippet around the first matching occurrence (at most 240 characters).

created_at: datetime.datetime = PydanticUndefined

When the message was posted.

id: str = PydanticUndefined

Message ID (msg_...).

similarity_score: float | None = None

Cosine similarity to the query when the result participated in embedding search, or null in text mode and for text-only hybrid matches.

user: str | None = None

Human sender ID (usr_...), or null when an agent sent the message.

class ThreadSearchResponse(pydantic.main.BaseModel):
762class ThreadSearchResponse(BaseModel):
763    """
764    Successful response
765    """
766
767    after_cursor: str | None = Field(
768        default=None,
769        description="Text-mode cursor for the next page of newer matches, or `null` for ranked modes and empty pages.",
770    )
771    before_cursor: str | None = Field(
772        default=None,
773        description="Text-mode cursor for the next page of older matches, or `null` for ranked modes and empty pages.",
774    )
775    data: list[ThreadSearchResponseDataItem] = Field(
776        ...,
777        description="Matching messages ordered newest first in text mode and by relevance in embedding or hybrid mode.",
778    )
779    has_more: bool = Field(
780        ..., description="`true` when at least one additional visible match exists."
781    )

Successful response

after_cursor: str | None = None

Text-mode cursor for the next page of newer matches, or null for ranked modes and empty pages.

before_cursor: str | None = None

Text-mode cursor for the next page of older matches, or null for ranked modes and empty pages.

data: list[ThreadSearchResponseDataItem] = PydanticUndefined

Matching messages ordered newest first in text mode and by relevance in embedding or hybrid mode.

has_more: bool = PydanticUndefined

true when at least one additional visible match exists.

class ThreadTrajectoriesResponseDataItem(pydantic.main.BaseModel):
784class ThreadTrajectoriesResponseDataItem(BaseModel):
785    agent_message: str | None = Field(
786        default=None,
787        description="ID of the agent-authored reply message (`msg_...`). `null` if the trajectory has not yet produced a response message.",
788    )
789    created_at: str | None = Field(
790        default=None, description="When this trajectory link was created (ISO 8601)."
791    )
792    id: str = Field(..., description="Thread message trajectory ID (`tmt_...`).")
793    org: str | None = Field(
794        default=None, description="ID of the organization this trajectory belongs to (`org_...`)."
795    )
796    sandbox: str | None = Field(
797        default=None,
798        description="ID of the sandbox environment in which this trajectory was produced (`dsb_...`). `null` in production contexts.",
799    )
800    thread: str | None = Field(
801        default=None, description="ID of the thread containing the linked messages (`thr_...`)."
802    )
803    trajectory: str | None = Field(
804        default=None,
805        description="ID of the AI trajectory record that captures the full model interaction for this exchange (`trj_...`).",
806    )
807    updated_at: str | None = Field(
808        default=None, description="When this trajectory link was last modified (ISO 8601)."
809    )
810    user_message: str | None = Field(
811        default=None,
812        description="ID of the user-authored message that triggered the agent response (`msg_...`). `null` if the agent turn was not preceded by a user message.",
813    )

!!! 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_message: str | None = None

ID of the agent-authored reply message (msg_...). null if the trajectory has not yet produced a response message.

created_at: str | None = None

When this trajectory link was created (ISO 8601).

id: str = PydanticUndefined

Thread message trajectory ID (tmt_...).

org: str | None = None

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

sandbox: str | None = None

ID of the sandbox environment in which this trajectory was produced (dsb_...). null in production contexts.

thread: str | None = None

ID of the thread containing the linked messages (thr_...).

trajectory: str | None = None

ID of the AI trajectory record that captures the full model interaction for this exchange (trj_...).

updated_at: str | None = None

When this trajectory link was last modified (ISO 8601).

user_message: str | None = None

ID of the user-authored message that triggered the agent response (msg_...). null if the agent turn was not preceded by a user message.

class ThreadTrajectoriesResponse(pydantic.main.BaseModel):
816class ThreadTrajectoriesResponse(BaseModel):
817    """
818    Successful response
819    """
820
821    after_cursor: str | None = Field(
822        default=None,
823        description="Opaque cursor to pass as `after_cursor` to retrieve the next page. `null` when no further pages exist.",
824    )
825    before_cursor: str | None = Field(
826        default=None,
827        description="Opaque cursor to pass as `before_cursor` to retrieve the previous page. `null` when this is the first page.",
828    )
829    data: list[ThreadTrajectoriesResponseDataItem] = Field(
830        ...,
831        description="Array of thread message trajectory objects for the current page. Empty when no trajectories match the query.",
832    )

Successful response

after_cursor: str | None = None

Opaque cursor to pass as after_cursor to retrieve the next page. null when no further pages exist.

before_cursor: str | None = None

Opaque cursor to pass as before_cursor to retrieve the previous page. null when this is the first page.

data: list[ThreadTrajectoriesResponseDataItem] = PydanticUndefined

Array of thread message trajectory objects for the current page. Empty when no trajectories match the query.

class AsyncThreadMemberResource:
835class AsyncThreadMemberResource:
836    def __init__(self, http: HttpClient):
837        self._http = http
838
839    async def remove(self, thread: str) -> None:
840        """
841        Remove a member from a thread
842        Removes a user or agent from the explicit roster of a private or restricted
843        thread. Team-visible threads use implicit membership and reject individual
844        removals. A member may remove themself; removing someone else requires
845        permission to modify the thread. A successful removal returns HTTP 204 with
846        no response body.
847        Supply either `user` or `agent` depending on the value of `type`. Returns 404
848        if the thread or the membership record does not exist.
849
850        Args:
851            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
852
853        Returns:
854            Empty response body. HTTP 204 on success.
855        """
856        await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")
857
858    async def list(self, thread: str) -> ThreadMemberListResponse:
859        """
860        List members of a thread
861        Returns all current user and agent members. Private and restricted threads
862        return their explicit roster; team-visible threads return the owning team's
863        implicit roster. The authenticated viewer must be able to see the thread.
864        Results are returned as a flat array in the `data` field. The list is not
865        paginated all members are returned in a single response.
866
867        Args:
868            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
869
870        Returns:
871            Successful response
872        """
873        return await self._http.request(
874            f"/api/v1/threads/{thread}/members",
875            response_type=ThreadMemberListResponse,
876        )
877
878    async def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember:
879        """
880        Add a member to a thread
881        Adds a user or agent to the explicit roster of a private or restricted
882        thread. Team-visible threads use the owning team's implicit roster and reject
883        explicit additions. On restricted threads, a team member may add themself;
884        adding anyone else requires permission to modify the thread.
885        Supply either `user` or `agent` depending on the value of `type`. Targets
886        must be visible to the caller and, for an ordinary team-owned thread, must
887        belong to the owning team. On success the membership record is returned with
888        HTTP 201; repeated agent additions are idempotent.
889
890        Args:
891            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
892            input: Request body.
893            input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`.
894            input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.
895            input.type: Kind of principal being added. Must be `"user"` or `"agent"`.
896            input.user: User ID of the principal to add. Required when `type` is `"user"`.
897
898        Returns:
899            The user or agent membership that was added to the thread.
900        """
901        return await self._http.request(
902            f"/api/v1/threads/{thread}/members",
903            method="POST",
904            body=input,
905            response_type=ChatMember,
906        )
AsyncThreadMemberResource(http: archastro.platform.runtime.http_client.HttpClient)
836    def __init__(self, http: HttpClient):
837        self._http = http
async def remove(self, thread: str) -> None:
839    async def remove(self, thread: str) -> None:
840        """
841        Remove a member from a thread
842        Removes a user or agent from the explicit roster of a private or restricted
843        thread. Team-visible threads use implicit membership and reject individual
844        removals. A member may remove themself; removing someone else requires
845        permission to modify the thread. A successful removal returns HTTP 204 with
846        no response body.
847        Supply either `user` or `agent` depending on the value of `type`. Returns 404
848        if the thread or the membership record does not exist.
849
850        Args:
851            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
852
853        Returns:
854            Empty response body. HTTP 204 on success.
855        """
856        await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")

Remove a member from a thread Removes a user or agent from the explicit roster of a private or restricted thread. Team-visible threads use implicit membership and reject individual removals. A member may remove themself; removing someone else requires permission to modify 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:
858    async def list(self, thread: str) -> ThreadMemberListResponse:
859        """
860        List members of a thread
861        Returns all current user and agent members. Private and restricted threads
862        return their explicit roster; team-visible threads return the owning team's
863        implicit roster. The authenticated viewer must be able to see the thread.
864        Results are returned as a flat array in the `data` field. The list is not
865        paginated all members are returned in a single response.
866
867        Args:
868            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
869
870        Returns:
871            Successful response
872        """
873        return await self._http.request(
874            f"/api/v1/threads/{thread}/members",
875            response_type=ThreadMemberListResponse,
876        )

List members of a thread Returns all current user and agent members. Private and restricted threads return their explicit roster; team-visible threads return the owning team's implicit roster. The authenticated viewer must be able to see the thread. 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.chat.ChatMember:
878    async def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember:
879        """
880        Add a member to a thread
881        Adds a user or agent to the explicit roster of a private or restricted
882        thread. Team-visible threads use the owning team's implicit roster and reject
883        explicit additions. On restricted threads, a team member may add themself;
884        adding anyone else requires permission to modify the thread.
885        Supply either `user` or `agent` depending on the value of `type`. Targets
886        must be visible to the caller and, for an ordinary team-owned thread, must
887        belong to the owning team. On success the membership record is returned with
888        HTTP 201; repeated agent additions are idempotent.
889
890        Args:
891            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
892            input: Request body.
893            input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`.
894            input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.
895            input.type: Kind of principal being added. Must be `"user"` or `"agent"`.
896            input.user: User ID of the principal to add. Required when `type` is `"user"`.
897
898        Returns:
899            The user or agent membership that was added to the thread.
900        """
901        return await self._http.request(
902            f"/api/v1/threads/{thread}/members",
903            method="POST",
904            body=input,
905            response_type=ChatMember,
906        )

Add a member to a thread Adds a user or agent to the explicit roster of a private or restricted thread. Team-visible threads use the owning team's implicit roster and reject explicit additions. On restricted threads, a team member may add themself; adding anyone else requires permission to modify the thread. Supply either user or agent depending on the value of type. Targets must be visible to the caller and, for an ordinary team-owned thread, must belong to the owning team. On success the membership record is returned with HTTP 201; repeated agent additions are idempotent.

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 user or agent membership that was added to the thread.

class AsyncSettingResource:
909class AsyncSettingResource:
910    def __init__(self, http: HttpClient):
911        self._http = http
912
913    async def list(self, thread: str) -> SettingListResponse:
914        """
915        Retrieve thread settings
916        Returns the current settings for the specified thread. Settings control
917        per-thread behavior such as whether the AI agent is enabled.
918        The authenticated user must own the thread or be a member of its workspace.
919        If settings have never been explicitly configured, defaults are returned
920        (for example, `agent_enabled` defaults to `true`).
921
922        Args:
923            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
924
925        Returns:
926            Successful response
927        """
928        return await self._http.request(
929            f"/api/v1/threads/{thread}/settings",
930            response_type=SettingListResponse,
931        )
932
933    async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings:
934        """
935        Update thread settings
936        Updates the settings for the specified thread. Only fields included in
937        the `settings` map are modified; omitted fields retain their current values.
938        The authenticated user must own the thread or be a member of its workspace.
939        Returns the full settings object reflecting the state after the update.
940        Validation errors are returned as `422 Unprocessable Entity`.
941
942        Args:
943            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
944            input: Request body.
945            input.settings: Map of settings fields to update. Include only the keys you want to change.
946
947        Returns:
948            The thread settings object after the update has been applied.
949        """
950        return await self._http.request(
951            f"/api/v1/threads/{thread}/settings",
952            method="PUT",
953            body=input,
954            response_type=ThreadSettings,
955        )
AsyncSettingResource(http: archastro.platform.runtime.http_client.HttpClient)
910    def __init__(self, http: HttpClient):
911        self._http = http
async def list( self, thread: str) -> SettingListResponse:
913    async def list(self, thread: str) -> SettingListResponse:
914        """
915        Retrieve thread settings
916        Returns the current settings for the specified thread. Settings control
917        per-thread behavior such as whether the AI agent is enabled.
918        The authenticated user must own the thread or be a member of its workspace.
919        If settings have never been explicitly configured, defaults are returned
920        (for example, `agent_enabled` defaults to `true`).
921
922        Args:
923            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
924
925        Returns:
926            Successful response
927        """
928        return await self._http.request(
929            f"/api/v1/threads/{thread}/settings",
930            response_type=SettingListResponse,
931        )

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:
933    async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings:
934        """
935        Update thread settings
936        Updates the settings for the specified thread. Only fields included in
937        the `settings` map are modified; omitted fields retain their current values.
938        The authenticated user must own the thread or be a member of its workspace.
939        Returns the full settings object reflecting the state after the update.
940        Validation errors are returned as `422 Unprocessable Entity`.
941
942        Args:
943            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
944            input: Request body.
945            input.settings: Map of settings fields to update. Include only the keys you want to change.
946
947        Returns:
948            The thread settings object after the update has been applied.
949        """
950        return await self._http.request(
951            f"/api/v1/threads/{thread}/settings",
952            method="PUT",
953            body=input,
954            response_type=ThreadSettings,
955        )

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 AsyncTagResource:
 958class AsyncTagResource:
 959    def __init__(self, http: HttpClient):
 960        self._http = http
 961
 962    async def remove(self, thread: str) -> Thread:
 963        """
 964        Remove tags from a thread
 965        Removes one or more status tags from the thread and returns the updated
 966        thread. Removing a tag the thread does not have is a no-op.
 967        Any participant of the thread a human member or an agent member may edit
 968        tags. Supply the tags to remove as repeated query parameters, e.g.
 969        `?tags[]=blocked&tags[]=needs-review`.
 970
 971        Args:
 972            thread: Thread ID (`thr_...`) to untag.
 973
 974        Returns:
 975            The thread object after the tags were removed.
 976        """
 977        return await self._http.request(
 978            f"/api/v1/threads/{thread}/tags",
 979            method="DELETE",
 980            response_type=Thread,
 981        )
 982
 983    async def create(self, thread: str, input: TagCreateInput) -> Thread:
 984        """
 985        Add tags to a thread
 986        Adds one or more status tags to the thread and returns the updated thread.
 987        Any participant of the thread a human member or an agent member may edit
 988        tags; this is broader than the owner/admin permission required to update other
 989        thread fields. Adding a tag the thread already has is a no-op. Tags are
 990        normalized (trimmed and lowercased) and may contain only lowercase letters,
 991        numbers, hyphens, and underscores.
 992
 993        Args:
 994            thread: Thread ID (`thr_...`) to untag.
 995            input: Request body.
 996            input.tags: Tags to add to the thread.
 997
 998        Returns:
 999            The thread object after the tags were added.
1000        """
1001        return await self._http.request(
1002            f"/api/v1/threads/{thread}/tags",
1003            method="POST",
1004            body=input,
1005            response_type=Thread,
1006        )
1007
1008    async def replace(self, thread: str, input: TagReplaceInput) -> Thread:
1009        """
1010        Replace a thread's tags
1011        Replaces the thread's entire set of status tags with the provided list and
1012        returns the updated thread. Passing an empty array clears all tags.
1013        Any participant of the thread a human member or an agent member may edit
1014        tags. Tags are normalized (trimmed and lowercased) and may contain only
1015        lowercase letters, numbers, hyphens, and underscores.
1016
1017        Args:
1018            thread: Thread ID (`thr_...`) to untag.
1019            input: Request body.
1020            input.tags: The complete set of tags for the thread. An empty array clears all tags.
1021
1022        Returns:
1023            The thread object after its tags were replaced.
1024        """
1025        return await self._http.request(
1026            f"/api/v1/threads/{thread}/tags",
1027            method="PUT",
1028            body=input,
1029            response_type=Thread,
1030        )
AsyncTagResource(http: archastro.platform.runtime.http_client.HttpClient)
959    def __init__(self, http: HttpClient):
960        self._http = http
async def remove(self, thread: str) -> archastro.platform.types.threads.Thread:
962    async def remove(self, thread: str) -> Thread:
963        """
964        Remove tags from a thread
965        Removes one or more status tags from the thread and returns the updated
966        thread. Removing a tag the thread does not have is a no-op.
967        Any participant of the thread a human member or an agent member may edit
968        tags. Supply the tags to remove as repeated query parameters, e.g.
969        `?tags[]=blocked&tags[]=needs-review`.
970
971        Args:
972            thread: Thread ID (`thr_...`) to untag.
973
974        Returns:
975            The thread object after the tags were removed.
976        """
977        return await self._http.request(
978            f"/api/v1/threads/{thread}/tags",
979            method="DELETE",
980            response_type=Thread,
981        )

Remove tags from a thread Removes one or more status tags from the thread and returns the updated thread. Removing a tag the thread does not have is a no-op. Any participant of the thread a human member or an agent member may edit tags. Supply the tags to remove as repeated query parameters, e.g. ?tags[]=blocked&tags[]=needs-review.

Arguments:
  • thread: Thread ID (thr_...) to untag.
Returns:

The thread object after the tags were removed.

async def create( self, thread: str, input: TagCreateInput) -> archastro.platform.types.threads.Thread:
 983    async def create(self, thread: str, input: TagCreateInput) -> Thread:
 984        """
 985        Add tags to a thread
 986        Adds one or more status tags to the thread and returns the updated thread.
 987        Any participant of the thread a human member or an agent member may edit
 988        tags; this is broader than the owner/admin permission required to update other
 989        thread fields. Adding a tag the thread already has is a no-op. Tags are
 990        normalized (trimmed and lowercased) and may contain only lowercase letters,
 991        numbers, hyphens, and underscores.
 992
 993        Args:
 994            thread: Thread ID (`thr_...`) to untag.
 995            input: Request body.
 996            input.tags: Tags to add to the thread.
 997
 998        Returns:
 999            The thread object after the tags were added.
1000        """
1001        return await self._http.request(
1002            f"/api/v1/threads/{thread}/tags",
1003            method="POST",
1004            body=input,
1005            response_type=Thread,
1006        )

Add tags to a thread Adds one or more status tags to the thread and returns the updated thread. Any participant of the thread a human member or an agent member may edit tags; this is broader than the owner/admin permission required to update other thread fields. Adding a tag the thread already has is a no-op. Tags are normalized (trimmed and lowercased) and may contain only lowercase letters, numbers, hyphens, and underscores.

Arguments:
  • thread: Thread ID (thr_...) to untag.
  • input: Request body.
  • input.tags: Tags to add to the thread.
Returns:

The thread object after the tags were added.

async def replace( self, thread: str, input: TagReplaceInput) -> archastro.platform.types.threads.Thread:
1008    async def replace(self, thread: str, input: TagReplaceInput) -> Thread:
1009        """
1010        Replace a thread's tags
1011        Replaces the thread's entire set of status tags with the provided list and
1012        returns the updated thread. Passing an empty array clears all tags.
1013        Any participant of the thread a human member or an agent member may edit
1014        tags. Tags are normalized (trimmed and lowercased) and may contain only
1015        lowercase letters, numbers, hyphens, and underscores.
1016
1017        Args:
1018            thread: Thread ID (`thr_...`) to untag.
1019            input: Request body.
1020            input.tags: The complete set of tags for the thread. An empty array clears all tags.
1021
1022        Returns:
1023            The thread object after its tags were replaced.
1024        """
1025        return await self._http.request(
1026            f"/api/v1/threads/{thread}/tags",
1027            method="PUT",
1028            body=input,
1029            response_type=Thread,
1030        )

Replace a thread's tags Replaces the thread's entire set of status tags with the provided list and returns the updated thread. Passing an empty array clears all tags. Any participant of the thread a human member or an agent member may edit tags. Tags are normalized (trimmed and lowercased) and may contain only lowercase letters, numbers, hyphens, and underscores.

Arguments:
  • thread: Thread ID (thr_...) to untag.
  • input: Request body.
  • input.tags: The complete set of tags for the thread. An empty array clears all tags.
Returns:

The thread object after its tags were replaced.

class AsyncThreadResource:
1033class AsyncThreadResource:
1034    def __init__(self, http: HttpClient):
1035        self._http = http
1036        self.members = AsyncThreadMemberResource(http)
1037        self.settings = AsyncSettingResource(http)
1038        self.tags = AsyncTagResource(http)
1039
1040    async def delete(self, thread: str) -> None:
1041        """
1042        Delete a thread
1043        Permanently deletes a thread and all of its messages and artifacts. This action
1044        cannot be undone.
1045        The authenticated user must own the thread or be an owner of the team the thread
1046        belongs to. Attempting to delete a thread owned by another user or team returns 403.
1047
1048        Args:
1049            thread: Thread ID (`thr_...`). The authenticated user must own this thread.
1050
1051        Returns:
1052            Empty response on successful deletion.
1053        """
1054        await self._http.request(f"/api/v1/threads/{thread}", method="DELETE")
1055
1056    async def get(self, thread: str) -> Thread:
1057        """
1058        Retrieve a thread
1059        Returns the full thread record for the given thread ID. The authenticated user
1060        must own the thread or be a member of the workspace it belongs to.
1061        Use this endpoint to fetch the current state of a single thread, including its
1062        title, description, and metadata. To list many threads, use the list endpoint
1063        with cursor-based pagination.
1064
1065        Args:
1066            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1067
1068        Returns:
1069            The requested thread object.
1070        """
1071        return await self._http.request(f"/api/v1/threads/{thread}", response_type=Thread)
1072
1073    async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread:
1074        """
1075        Update a thread
1076        Updates one or more mutable properties of the specified thread and returns
1077        the full thread object with the applied changes. Only the fields you provide
1078        are modified; omitted fields retain their current values.
1079        If `profile_picture` is supplied, the image is uploaded before the other
1080        fields are saved, after all ordinary thread fields have passed validation.
1081        Supplying invalid base64 picture data returns 422 and no other fields are
1082        updated.
1083        Visibility can only widen: `private` may become `restricted` or `team`, and
1084        `restricted` may become `team`. The authenticated viewer must have
1085        permission to modify the thread.
1086        Mirror-thread titles, descriptions, and notification state remain editable
1087        by privileged app viewers. Mirror metadata, visibility, and membership are
1088        provider-managed and cannot be changed through this endpoint.
1089
1090        Args:
1091            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1092            input: Request body.
1093            input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
1094            input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
1095            input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user.
1096            input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
1097            input.title: Human-readable display name for the thread. Replaces the existing title when provided.
1098            input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed.
1099
1100        Returns:
1101            The thread object after the update has been applied.
1102        """
1103        return await self._http.request(
1104            f"/api/v1/threads/{thread}",
1105            method="PUT",
1106            body=input,
1107            response_type=Thread,
1108        )
1109
1110    async def agents(self, thread: str) -> ThreadAgentsResponse:
1111        """
1112        List agents in a thread
1113        Returns the agents participating in the specified thread. Only personal user
1114        threads (threads owned by a single user, not a team) expose agents through
1115        this endpoint; requests for team threads return 404.
1116        The authenticated user must have visibility into the thread. Each agent entry
1117        includes display information such as name and profile picture. Thread-level
1118        overrides (e.g. a custom name or profile picture set for this thread) take
1119        precedence over the agent's default values. When the caller is the thread
1120        owner, each entry also includes an `agent_config` object describing the
1121        agent's message policy and context configuration.
1122
1123        Args:
1124            thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user.
1125
1126        Returns:
1127            Successful response
1128        """
1129        return await self._http.request(
1130            f"/api/v1/threads/{thread}/agents",
1131            response_type=ThreadAgentsResponse,
1132        )
1133
1134    async def artifacts(self, thread: str) -> ThreadArtifactsResponse:
1135        """
1136        List artifacts for a thread
1137        Returns all artifacts produced during a thread's AI conversation. Artifacts are
1138        structured outputs such as code files, documents, or generated assets created
1139        by the AI agent in response to messages in the thread.
1140        The authenticated user must have access to the specified thread. Results are
1141        returned in a single page; there is no cursor-based pagination for this endpoint.
1142
1143        Args:
1144            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user.
1145
1146        Returns:
1147            Successful response
1148        """
1149        return await self._http.request(
1150            f"/api/v1/threads/{thread}/artifacts",
1151            response_type=ThreadArtifactsResponse,
1152        )
1153
1154    async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None:
1155        """
1156        Mark a thread as read
1157        Records that a user has read up to a specific message in the thread. Unread
1158        indicators and badge counts are cleared up to the specified message.
1159        You must supply exactly one of `last_read_message` or `use_latest_message`.
1160        Omitting both returns 400. If `use_latest_message` is `true` and the thread
1161        has no messages, the request succeeds silently with no state change.
1162        For server-to-server (S2S) requests where no user identity is present in the
1163        token, the `user` param is required to identify whose read state to update.
1164
1165        Args:
1166            thread: Thread ID (`thr_...`). The thread to mark as read.
1167            input: Request body.
1168            input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`.
1169            input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`.
1170            input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
1171
1172        Returns:
1173            Empty response on success.
1174        """
1175        await self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input)
1176
1177    async def messages(
1178        self,
1179        thread: str,
1180        *,
1181        before_cursor: str | None = None,
1182        after_cursor: str | None = None,
1183        metadata: dict[str, Any] | None = None,
1184        limit: int | None = None,
1185        anchor: str | None = None,
1186        direction: Literal["before", "after", "around"] | None = None,
1187        before_limit: int | None = None,
1188        after_limit: int | None = None,
1189        include_anchor: bool | None = None,
1190        anchor_agent_mode: Literal["cli", "embedded"] | None = None,
1191        anchor_agent: str | None = None,
1192        include_reply_counts: bool | None = None,
1193    ) -> ThreadMessagesResponse:
1194        """
1195        List messages in a thread
1196        Returns a cursor-paginated list of messages belonging to the specified thread,
1197        ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both
1198        to page through or bound the result set; omit both to receive the most recent page.
1199        Supply `anchor` and `direction` to fetch a window before, after, or around a
1200        specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to
1201        resolve the anchor from the latest embedded-agent message, and add
1202        `anchor_agent` to scope that resolution to a single sender agent.
1203        Supply `metadata` as a JSON-encoded structured expression to filter message
1204        metadata before cursor pagination or anchored window limits are applied.
1205        The authenticated user must have access to the thread's owner (workspace or user).
1206        A 403 is returned if the thread exists but is not accessible to the caller; a 404
1207        is returned if the thread does not exist or is not visible to the authenticated user.
1208        Pass `include_reply_counts: true` to annotate each message with the number of
1209        threaded replies it has received. This adds a small amount of latency and should
1210        be omitted when reply counts are not needed.
1211
1212        Args:
1213            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1214            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.
1215            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.
1216            metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits.
1217            limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
1218            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`.
1219            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`.
1220            before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100.
1221            after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100.
1222            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.
1223            anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode.
1224            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.
1225            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.
1226
1227        Returns:
1228            Successful response
1229        """
1230        query: dict[str, object] = {}
1231        if before_cursor is not None:
1232            query["before_cursor"] = before_cursor
1233        if after_cursor is not None:
1234            query["after_cursor"] = after_cursor
1235        if metadata is not None:
1236            query["metadata"] = metadata
1237        if limit is not None:
1238            query["limit"] = limit
1239        if anchor is not None:
1240            query["anchor"] = anchor
1241        if direction is not None:
1242            query["direction"] = direction
1243        if before_limit is not None:
1244            query["before_limit"] = before_limit
1245        if after_limit is not None:
1246            query["after_limit"] = after_limit
1247        if include_anchor is not None:
1248            query["include_anchor"] = include_anchor
1249        if anchor_agent_mode is not None:
1250            query["anchor_agent_mode"] = anchor_agent_mode
1251        if anchor_agent is not None:
1252            query["anchor_agent"] = anchor_agent
1253        if include_reply_counts is not None:
1254            query["include_reply_counts"] = include_reply_counts
1255        return await self._http.request(
1256            f"/api/v1/threads/{thread}/messages",
1257            query=query,
1258            response_type=ThreadMessagesResponse,
1259        )
1260
1261    async def picture(self, thread: str, input: ThreadPictureInput) -> Thread:
1262        """
1263        Update a thread's profile picture
1264        Uploads a new profile picture for the specified thread and returns the updated
1265        thread object. The image must be supplied as a base64-encoded string with its
1266        MIME type.
1267        The authenticated user must own the thread or be a team owner of the workspace
1268        the thread belongs to. Supplying invalid base64 data returns 422.
1269
1270        Args:
1271            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1272            input: Request body.
1273            input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
1274
1275        Returns:
1276            The thread object after the profile picture has been updated.
1277        """
1278        return await self._http.request(
1279            f"/api/v1/threads/{thread}/picture",
1280            method="PUT",
1281            body=input,
1282            response_type=Thread,
1283        )
1284
1285    async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus:
1286        """
1287        Retrieve a thread's read status
1288        Returns the read status of a thread for the specified user, including the ID
1289        of the last message they have read and the number of unread messages remaining.
1290        For user-authenticated requests, the status is always returned for the
1291        authenticated user and the `user` parameter is ignored. For server-to-server
1292        (S2S) requests, the `user` parameter is required and must be a valid user ID.
1293        Returns 404 if the thread does not exist or the caller does not have access
1294        to it.
1295
1296        Args:
1297            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user.
1298            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.
1299
1300        Returns:
1301            The read status record for the requested thread and user.
1302        """
1303        query: dict[str, object] = {}
1304        if user is not None:
1305            query["user"] = user
1306        return await self._http.request(
1307            f"/api/v1/threads/{thread}/read_status",
1308            query=query,
1309            response_type=ThreadReadStatus,
1310        )
1311
1312    async def search(
1313        self,
1314        thread: str,
1315        q: str,
1316        *,
1317        app: str | None = None,
1318        limit: int | None = None,
1319        mode: Literal["text", "embedding", "hybrid"] | None = None,
1320        before_cursor: str | None = None,
1321        after_cursor: str | None = None,
1322    ) -> ThreadSearchResponse:
1323        """
1324        Search messages in a thread
1325        Searches canonical message content in the specified thread. `"text"` mode
1326        performs the existing case-insensitive substring search, `"embedding"` ranks
1327        stored message embeddings by cosine similarity, and `"hybrid"` combines the
1328        text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages
1329        visible to the authenticated caller are considered.
1330        Results are intentionally lean: each row contains only a bounded content
1331        snippet, sender identity, and timestamp. Attachments, reactions, ACLs, and
1332        metadata are neither hydrated nor serialized. At most 20 results are
1333        returned. Text results support chronological cursor pagination. Embedding and
1334        hybrid results are relevance-ranked single pages and return null cursors.
1335
1336        Args:
1337            thread: Thread ID (`thr_...`). Must be visible to the authenticated caller.
1338            app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount.
1339            q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
1340            limit: Maximum number of results. Defaults to 20 and is capped at 20.
1341            mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings.
1342            before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
1343            after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
1344
1345        Returns:
1346            Successful response
1347        """
1348        query: dict[str, object] = {}
1349        if app is not None:
1350            query["app"] = app
1351        query["q"] = q
1352        if limit is not None:
1353            query["limit"] = limit
1354        if mode is not None:
1355            query["mode"] = mode
1356        if before_cursor is not None:
1357            query["before_cursor"] = before_cursor
1358        if after_cursor is not None:
1359            query["after_cursor"] = after_cursor
1360        return await self._http.request(
1361            f"/api/v1/threads/{thread}/search",
1362            query=query,
1363            response_type=ThreadSearchResponse,
1364        )
1365
1366    async def trajectories(
1367        self,
1368        thread: str,
1369        *,
1370        before_cursor: str | None = None,
1371        after_cursor: str | None = None,
1372        limit: int | None = None,
1373        message: str | None = None,
1374    ) -> ThreadTrajectoriesResponse:
1375        """
1376        List trajectories for a thread
1377        Returns a cursor-paginated list of thread message trajectories associated with the
1378        specified thread. Each trajectory links a user message and its agent response to the
1379        underlying AI trajectory record that captured the model's reasoning steps.
1380        The authenticated user must own the thread or be a member of the workspace it belongs
1381        to. Results are returned in reverse chronological order by default. Use `before_cursor`
1382        and `after_cursor` to navigate pages; provide at most one cursor per request.
1383        Optionally filter results to trajectories produced in response to a specific message
1384        by supplying the `message` parameter. When no trajectories match the query, `data`
1385        is an empty array and both cursor fields are `null`. A cursor that cannot be decoded
1386        returns a 400 `invalid_cursor` error.
1387
1388        Args:
1389            thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace.
1390            before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position.
1391            after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position.
1392            limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
1393            message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message.
1394
1395        Returns:
1396            Successful response
1397        """
1398        query: dict[str, object] = {}
1399        if before_cursor is not None:
1400            query["before_cursor"] = before_cursor
1401        if after_cursor is not None:
1402            query["after_cursor"] = after_cursor
1403        if limit is not None:
1404            query["limit"] = limit
1405        if message is not None:
1406            query["message"] = message
1407        return await self._http.request(
1408            f"/api/v1/threads/{thread}/trajectories",
1409            query=query,
1410            response_type=ThreadTrajectoriesResponse,
1411        )
AsyncThreadResource(http: archastro.platform.runtime.http_client.HttpClient)
1034    def __init__(self, http: HttpClient):
1035        self._http = http
1036        self.members = AsyncThreadMemberResource(http)
1037        self.settings = AsyncSettingResource(http)
1038        self.tags = AsyncTagResource(http)
members
settings
tags
async def delete(self, thread: str) -> None:
1040    async def delete(self, thread: str) -> None:
1041        """
1042        Delete a thread
1043        Permanently deletes a thread and all of its messages and artifacts. This action
1044        cannot be undone.
1045        The authenticated user must own the thread or be an owner of the team the thread
1046        belongs to. Attempting to delete a thread owned by another user or team returns 403.
1047
1048        Args:
1049            thread: Thread ID (`thr_...`). The authenticated user must own this thread.
1050
1051        Returns:
1052            Empty response on successful deletion.
1053        """
1054        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:
1056    async def get(self, thread: str) -> Thread:
1057        """
1058        Retrieve a thread
1059        Returns the full thread record for the given thread ID. The authenticated user
1060        must own the thread or be a member of the workspace it belongs to.
1061        Use this endpoint to fetch the current state of a single thread, including its
1062        title, description, and metadata. To list many threads, use the list endpoint
1063        with cursor-based pagination.
1064
1065        Args:
1066            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1067
1068        Returns:
1069            The requested thread object.
1070        """
1071        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:
1073    async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread:
1074        """
1075        Update a thread
1076        Updates one or more mutable properties of the specified thread and returns
1077        the full thread object with the applied changes. Only the fields you provide
1078        are modified; omitted fields retain their current values.
1079        If `profile_picture` is supplied, the image is uploaded before the other
1080        fields are saved, after all ordinary thread fields have passed validation.
1081        Supplying invalid base64 picture data returns 422 and no other fields are
1082        updated.
1083        Visibility can only widen: `private` may become `restricted` or `team`, and
1084        `restricted` may become `team`. The authenticated viewer must have
1085        permission to modify the thread.
1086        Mirror-thread titles, descriptions, and notification state remain editable
1087        by privileged app viewers. Mirror metadata, visibility, and membership are
1088        provider-managed and cannot be changed through this endpoint.
1089
1090        Args:
1091            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1092            input: Request body.
1093            input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
1094            input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
1095            input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user.
1096            input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
1097            input.title: Human-readable display name for the thread. Replaces the existing title when provided.
1098            input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed.
1099
1100        Returns:
1101            The thread object after the update has been applied.
1102        """
1103        return await self._http.request(
1104            f"/api/v1/threads/{thread}",
1105            method="PUT",
1106            body=input,
1107            response_type=Thread,
1108        )

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, after all ordinary thread fields have passed validation. Supplying invalid base64 picture data returns 422 and no other fields are updated. Visibility can only widen: private may become restricted or team, and restricted may become team. The authenticated viewer must have permission to modify the thread. Mirror-thread titles, descriptions, and notification state remain editable by privileged app viewers. Mirror metadata, visibility, and membership are provider-managed and cannot be changed through this endpoint.

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.
  • input.visibility: Widen a team-owned thread: private may become restricted or team, and restricted may become team. Visibility cannot be narrowed.
Returns:

The thread object after the update has been applied.

async def agents( self, thread: str) -> ThreadAgentsResponse:
1110    async def agents(self, thread: str) -> ThreadAgentsResponse:
1111        """
1112        List agents in a thread
1113        Returns the agents participating in the specified thread. Only personal user
1114        threads (threads owned by a single user, not a team) expose agents through
1115        this endpoint; requests for team threads return 404.
1116        The authenticated user must have visibility into the thread. Each agent entry
1117        includes display information such as name and profile picture. Thread-level
1118        overrides (e.g. a custom name or profile picture set for this thread) take
1119        precedence over the agent's default values. When the caller is the thread
1120        owner, each entry also includes an `agent_config` object describing the
1121        agent's message policy and context configuration.
1122
1123        Args:
1124            thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user.
1125
1126        Returns:
1127            Successful response
1128        """
1129        return await self._http.request(
1130            f"/api/v1/threads/{thread}/agents",
1131            response_type=ThreadAgentsResponse,
1132        )

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:
1134    async def artifacts(self, thread: str) -> ThreadArtifactsResponse:
1135        """
1136        List artifacts for a thread
1137        Returns all artifacts produced during a thread's AI conversation. Artifacts are
1138        structured outputs such as code files, documents, or generated assets created
1139        by the AI agent in response to messages in the thread.
1140        The authenticated user must have access to the specified thread. Results are
1141        returned in a single page; there is no cursor-based pagination for this endpoint.
1142
1143        Args:
1144            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user.
1145
1146        Returns:
1147            Successful response
1148        """
1149        return await self._http.request(
1150            f"/api/v1/threads/{thread}/artifacts",
1151            response_type=ThreadArtifactsResponse,
1152        )

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:
1154    async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None:
1155        """
1156        Mark a thread as read
1157        Records that a user has read up to a specific message in the thread. Unread
1158        indicators and badge counts are cleared up to the specified message.
1159        You must supply exactly one of `last_read_message` or `use_latest_message`.
1160        Omitting both returns 400. If `use_latest_message` is `true` and the thread
1161        has no messages, the request succeeds silently with no state change.
1162        For server-to-server (S2S) requests where no user identity is present in the
1163        token, the `user` param is required to identify whose read state to update.
1164
1165        Args:
1166            thread: Thread ID (`thr_...`). The thread to mark as read.
1167            input: Request body.
1168            input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`.
1169            input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`.
1170            input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
1171
1172        Returns:
1173            Empty response on success.
1174        """
1175        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, metadata: dict[str, typing.Any] | 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:
1177    async def messages(
1178        self,
1179        thread: str,
1180        *,
1181        before_cursor: str | None = None,
1182        after_cursor: str | None = None,
1183        metadata: dict[str, Any] | None = None,
1184        limit: int | None = None,
1185        anchor: str | None = None,
1186        direction: Literal["before", "after", "around"] | None = None,
1187        before_limit: int | None = None,
1188        after_limit: int | None = None,
1189        include_anchor: bool | None = None,
1190        anchor_agent_mode: Literal["cli", "embedded"] | None = None,
1191        anchor_agent: str | None = None,
1192        include_reply_counts: bool | None = None,
1193    ) -> ThreadMessagesResponse:
1194        """
1195        List messages in a thread
1196        Returns a cursor-paginated list of messages belonging to the specified thread,
1197        ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both
1198        to page through or bound the result set; omit both to receive the most recent page.
1199        Supply `anchor` and `direction` to fetch a window before, after, or around a
1200        specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to
1201        resolve the anchor from the latest embedded-agent message, and add
1202        `anchor_agent` to scope that resolution to a single sender agent.
1203        Supply `metadata` as a JSON-encoded structured expression to filter message
1204        metadata before cursor pagination or anchored window limits are applied.
1205        The authenticated user must have access to the thread's owner (workspace or user).
1206        A 403 is returned if the thread exists but is not accessible to the caller; a 404
1207        is returned if the thread does not exist or is not visible to the authenticated user.
1208        Pass `include_reply_counts: true` to annotate each message with the number of
1209        threaded replies it has received. This adds a small amount of latency and should
1210        be omitted when reply counts are not needed.
1211
1212        Args:
1213            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1214            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.
1215            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.
1216            metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits.
1217            limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
1218            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`.
1219            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`.
1220            before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100.
1221            after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100.
1222            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.
1223            anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode.
1224            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.
1225            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.
1226
1227        Returns:
1228            Successful response
1229        """
1230        query: dict[str, object] = {}
1231        if before_cursor is not None:
1232            query["before_cursor"] = before_cursor
1233        if after_cursor is not None:
1234            query["after_cursor"] = after_cursor
1235        if metadata is not None:
1236            query["metadata"] = metadata
1237        if limit is not None:
1238            query["limit"] = limit
1239        if anchor is not None:
1240            query["anchor"] = anchor
1241        if direction is not None:
1242            query["direction"] = direction
1243        if before_limit is not None:
1244            query["before_limit"] = before_limit
1245        if after_limit is not None:
1246            query["after_limit"] = after_limit
1247        if include_anchor is not None:
1248            query["include_anchor"] = include_anchor
1249        if anchor_agent_mode is not None:
1250            query["anchor_agent_mode"] = anchor_agent_mode
1251        if anchor_agent is not None:
1252            query["anchor_agent"] = anchor_agent
1253        if include_reply_counts is not None:
1254            query["include_reply_counts"] = include_reply_counts
1255        return await self._http.request(
1256            f"/api/v1/threads/{thread}/messages",
1257            query=query,
1258            response_type=ThreadMessagesResponse,
1259        )

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. Supply metadata as a JSON-encoded structured expression to filter message metadata before cursor pagination or anchored window limits are applied. 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.
  • metadata: Structured metadata filter expression. Only messages whose metadata object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits.
  • limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
  • 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; maximum is 100.
  • after_limit: For direction=around, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100.
  • 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:
1261    async def picture(self, thread: str, input: ThreadPictureInput) -> Thread:
1262        """
1263        Update a thread's profile picture
1264        Uploads a new profile picture for the specified thread and returns the updated
1265        thread object. The image must be supplied as a base64-encoded string with its
1266        MIME type.
1267        The authenticated user must own the thread or be a team owner of the workspace
1268        the thread belongs to. Supplying invalid base64 data returns 422.
1269
1270        Args:
1271            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1272            input: Request body.
1273            input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
1274
1275        Returns:
1276            The thread object after the profile picture has been updated.
1277        """
1278        return await self._http.request(
1279            f"/api/v1/threads/{thread}/picture",
1280            method="PUT",
1281            body=input,
1282            response_type=Thread,
1283        )

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:
1285    async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus:
1286        """
1287        Retrieve a thread's read status
1288        Returns the read status of a thread for the specified user, including the ID
1289        of the last message they have read and the number of unread messages remaining.
1290        For user-authenticated requests, the status is always returned for the
1291        authenticated user and the `user` parameter is ignored. For server-to-server
1292        (S2S) requests, the `user` parameter is required and must be a valid user ID.
1293        Returns 404 if the thread does not exist or the caller does not have access
1294        to it.
1295
1296        Args:
1297            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user.
1298            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.
1299
1300        Returns:
1301            The read status record for the requested thread and user.
1302        """
1303        query: dict[str, object] = {}
1304        if user is not None:
1305            query["user"] = user
1306        return await self._http.request(
1307            f"/api/v1/threads/{thread}/read_status",
1308            query=query,
1309            response_type=ThreadReadStatus,
1310        )

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, *, app: str | None = None, limit: int | None = None, mode: Optional[Literal['text', 'embedding', 'hybrid']] = None, before_cursor: str | None = None, after_cursor: str | None = None) -> ThreadSearchResponse:
1312    async def search(
1313        self,
1314        thread: str,
1315        q: str,
1316        *,
1317        app: str | None = None,
1318        limit: int | None = None,
1319        mode: Literal["text", "embedding", "hybrid"] | None = None,
1320        before_cursor: str | None = None,
1321        after_cursor: str | None = None,
1322    ) -> ThreadSearchResponse:
1323        """
1324        Search messages in a thread
1325        Searches canonical message content in the specified thread. `"text"` mode
1326        performs the existing case-insensitive substring search, `"embedding"` ranks
1327        stored message embeddings by cosine similarity, and `"hybrid"` combines the
1328        text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages
1329        visible to the authenticated caller are considered.
1330        Results are intentionally lean: each row contains only a bounded content
1331        snippet, sender identity, and timestamp. Attachments, reactions, ACLs, and
1332        metadata are neither hydrated nor serialized. At most 20 results are
1333        returned. Text results support chronological cursor pagination. Embedding and
1334        hybrid results are relevance-ranked single pages and return null cursors.
1335
1336        Args:
1337            thread: Thread ID (`thr_...`). Must be visible to the authenticated caller.
1338            app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount.
1339            q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
1340            limit: Maximum number of results. Defaults to 20 and is capped at 20.
1341            mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings.
1342            before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
1343            after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
1344
1345        Returns:
1346            Successful response
1347        """
1348        query: dict[str, object] = {}
1349        if app is not None:
1350            query["app"] = app
1351        query["q"] = q
1352        if limit is not None:
1353            query["limit"] = limit
1354        if mode is not None:
1355            query["mode"] = mode
1356        if before_cursor is not None:
1357            query["before_cursor"] = before_cursor
1358        if after_cursor is not None:
1359            query["after_cursor"] = after_cursor
1360        return await self._http.request(
1361            f"/api/v1/threads/{thread}/search",
1362            query=query,
1363            response_type=ThreadSearchResponse,
1364        )

Search messages in a thread Searches canonical message content in the specified thread. "text" mode performs the existing case-insensitive substring search, "embedding" ranks stored message embeddings by cosine similarity, and "hybrid" combines the text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages visible to the authenticated caller are considered. Results are intentionally lean: each row contains only a bounded content snippet, sender identity, and timestamp. Attachments, reactions, ACLs, and metadata are neither hydrated nor serialized. At most 20 results are returned. Text results support chronological cursor pagination. Embedding and hybrid results are relevance-ranked single pages and return null cursors.

Arguments:
  • thread: Thread ID (thr_...). Must be visible to the authenticated caller.
  • app: App ID (app_...). Required by the protected developer mount and omitted from the public mount.
  • q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
  • limit: Maximum number of results. Defaults to 20 and is capped at 20.
  • mode: Search algorithm: text for substring matching, embedding for cosine similarity, or hybrid for RRF over both rankings.
  • before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
  • after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
Returns:

Successful response

async def trajectories( self, thread: str, *, before_cursor: str | None = None, after_cursor: str | None = None, limit: int | None = None, message: str | None = None) -> ThreadTrajectoriesResponse:
1366    async def trajectories(
1367        self,
1368        thread: str,
1369        *,
1370        before_cursor: str | None = None,
1371        after_cursor: str | None = None,
1372        limit: int | None = None,
1373        message: str | None = None,
1374    ) -> ThreadTrajectoriesResponse:
1375        """
1376        List trajectories for a thread
1377        Returns a cursor-paginated list of thread message trajectories associated with the
1378        specified thread. Each trajectory links a user message and its agent response to the
1379        underlying AI trajectory record that captured the model's reasoning steps.
1380        The authenticated user must own the thread or be a member of the workspace it belongs
1381        to. Results are returned in reverse chronological order by default. Use `before_cursor`
1382        and `after_cursor` to navigate pages; provide at most one cursor per request.
1383        Optionally filter results to trajectories produced in response to a specific message
1384        by supplying the `message` parameter. When no trajectories match the query, `data`
1385        is an empty array and both cursor fields are `null`. A cursor that cannot be decoded
1386        returns a 400 `invalid_cursor` error.
1387
1388        Args:
1389            thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace.
1390            before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position.
1391            after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position.
1392            limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
1393            message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message.
1394
1395        Returns:
1396            Successful response
1397        """
1398        query: dict[str, object] = {}
1399        if before_cursor is not None:
1400            query["before_cursor"] = before_cursor
1401        if after_cursor is not None:
1402            query["after_cursor"] = after_cursor
1403        if limit is not None:
1404            query["limit"] = limit
1405        if message is not None:
1406            query["message"] = message
1407        return await self._http.request(
1408            f"/api/v1/threads/{thread}/trajectories",
1409            query=query,
1410            response_type=ThreadTrajectoriesResponse,
1411        )

List trajectories for a thread Returns a cursor-paginated list of thread message trajectories associated with the specified thread. Each trajectory links a user message and its agent response to the underlying AI trajectory record that captured the model's reasoning steps. The authenticated user must own the thread or be a member of the workspace it belongs to. Results are returned in reverse chronological order by default. Use before_cursor and after_cursor to navigate pages; provide at most one cursor per request. Optionally filter results to trajectories produced in response to a specific message by supplying the message parameter. When no trajectories match the query, data is an empty array and both cursor fields are null. A cursor that cannot be decoded returns a 400 invalid_cursor error.

Arguments:
  • thread: Thread ID (thr_...). The authenticated user must own this thread or belong to its workspace.
  • before_cursor: Opaque cursor from a previous response's before_cursor field. Returns the page of results preceding that cursor position.
  • after_cursor: Opaque cursor from a previous response's after_cursor field. Returns the page of results following that cursor position.
  • limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
  • message: Message ID (msg_...). When provided, limits results to trajectories associated with this specific message.
Returns:

Successful response

class ThreadMemberResource:
1414class ThreadMemberResource:
1415    def __init__(self, http: SyncHttpClient):
1416        self._http = http
1417
1418    def remove(self, thread: str) -> None:
1419        """
1420        Remove a member from a thread
1421        Removes a user or agent from the explicit roster of a private or restricted
1422        thread. Team-visible threads use implicit membership and reject individual
1423        removals. A member may remove themself; removing someone else requires
1424        permission to modify the thread. A successful removal returns HTTP 204 with
1425        no response body.
1426        Supply either `user` or `agent` depending on the value of `type`. Returns 404
1427        if the thread or the membership record does not exist.
1428
1429        Args:
1430            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1431
1432        Returns:
1433            Empty response body. HTTP 204 on success.
1434        """
1435        self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")
1436
1437    def list(self, thread: str) -> ThreadMemberListResponse:
1438        """
1439        List members of a thread
1440        Returns all current user and agent members. Private and restricted threads
1441        return their explicit roster; team-visible threads return the owning team's
1442        implicit roster. The authenticated viewer must be able to see the thread.
1443        Results are returned as a flat array in the `data` field. The list is not
1444        paginated all members are returned in a single response.
1445
1446        Args:
1447            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1448
1449        Returns:
1450            Successful response
1451        """
1452        return self._http.request(
1453            f"/api/v1/threads/{thread}/members",
1454            response_type=ThreadMemberListResponse,
1455        )
1456
1457    def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember:
1458        """
1459        Add a member to a thread
1460        Adds a user or agent to the explicit roster of a private or restricted
1461        thread. Team-visible threads use the owning team's implicit roster and reject
1462        explicit additions. On restricted threads, a team member may add themself;
1463        adding anyone else requires permission to modify the thread.
1464        Supply either `user` or `agent` depending on the value of `type`. Targets
1465        must be visible to the caller and, for an ordinary team-owned thread, must
1466        belong to the owning team. On success the membership record is returned with
1467        HTTP 201; repeated agent additions are idempotent.
1468
1469        Args:
1470            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1471            input: Request body.
1472            input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`.
1473            input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.
1474            input.type: Kind of principal being added. Must be `"user"` or `"agent"`.
1475            input.user: User ID of the principal to add. Required when `type` is `"user"`.
1476
1477        Returns:
1478            The user or agent membership that was added to the thread.
1479        """
1480        return self._http.request(
1481            f"/api/v1/threads/{thread}/members",
1482            method="POST",
1483            body=input,
1484            response_type=ChatMember,
1485        )
ThreadMemberResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1415    def __init__(self, http: SyncHttpClient):
1416        self._http = http
def remove(self, thread: str) -> None:
1418    def remove(self, thread: str) -> None:
1419        """
1420        Remove a member from a thread
1421        Removes a user or agent from the explicit roster of a private or restricted
1422        thread. Team-visible threads use implicit membership and reject individual
1423        removals. A member may remove themself; removing someone else requires
1424        permission to modify the thread. A successful removal returns HTTP 204 with
1425        no response body.
1426        Supply either `user` or `agent` depending on the value of `type`. Returns 404
1427        if the thread or the membership record does not exist.
1428
1429        Args:
1430            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1431
1432        Returns:
1433            Empty response body. HTTP 204 on success.
1434        """
1435        self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")

Remove a member from a thread Removes a user or agent from the explicit roster of a private or restricted thread. Team-visible threads use implicit membership and reject individual removals. A member may remove themself; removing someone else requires permission to modify 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:
1437    def list(self, thread: str) -> ThreadMemberListResponse:
1438        """
1439        List members of a thread
1440        Returns all current user and agent members. Private and restricted threads
1441        return their explicit roster; team-visible threads return the owning team's
1442        implicit roster. The authenticated viewer must be able to see the thread.
1443        Results are returned as a flat array in the `data` field. The list is not
1444        paginated all members are returned in a single response.
1445
1446        Args:
1447            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1448
1449        Returns:
1450            Successful response
1451        """
1452        return self._http.request(
1453            f"/api/v1/threads/{thread}/members",
1454            response_type=ThreadMemberListResponse,
1455        )

List members of a thread Returns all current user and agent members. Private and restricted threads return their explicit roster; team-visible threads return the owning team's implicit roster. The authenticated viewer must be able to see the thread. 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.chat.ChatMember:
1457    def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember:
1458        """
1459        Add a member to a thread
1460        Adds a user or agent to the explicit roster of a private or restricted
1461        thread. Team-visible threads use the owning team's implicit roster and reject
1462        explicit additions. On restricted threads, a team member may add themself;
1463        adding anyone else requires permission to modify the thread.
1464        Supply either `user` or `agent` depending on the value of `type`. Targets
1465        must be visible to the caller and, for an ordinary team-owned thread, must
1466        belong to the owning team. On success the membership record is returned with
1467        HTTP 201; repeated agent additions are idempotent.
1468
1469        Args:
1470            thread: Thread ID (`thr_...`) identifying the thread to remove the member from.
1471            input: Request body.
1472            input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`.
1473            input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.
1474            input.type: Kind of principal being added. Must be `"user"` or `"agent"`.
1475            input.user: User ID of the principal to add. Required when `type` is `"user"`.
1476
1477        Returns:
1478            The user or agent membership that was added to the thread.
1479        """
1480        return self._http.request(
1481            f"/api/v1/threads/{thread}/members",
1482            method="POST",
1483            body=input,
1484            response_type=ChatMember,
1485        )

Add a member to a thread Adds a user or agent to the explicit roster of a private or restricted thread. Team-visible threads use the owning team's implicit roster and reject explicit additions. On restricted threads, a team member may add themself; adding anyone else requires permission to modify the thread. Supply either user or agent depending on the value of type. Targets must be visible to the caller and, for an ordinary team-owned thread, must belong to the owning team. On success the membership record is returned with HTTP 201; repeated agent additions are idempotent.

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 user or agent membership that was added to the thread.

class SettingResource:
1488class SettingResource:
1489    def __init__(self, http: SyncHttpClient):
1490        self._http = http
1491
1492    def list(self, thread: str) -> SettingListResponse:
1493        """
1494        Retrieve thread settings
1495        Returns the current settings for the specified thread. Settings control
1496        per-thread behavior such as whether the AI agent is enabled.
1497        The authenticated user must own the thread or be a member of its workspace.
1498        If settings have never been explicitly configured, defaults are returned
1499        (for example, `agent_enabled` defaults to `true`).
1500
1501        Args:
1502            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
1503
1504        Returns:
1505            Successful response
1506        """
1507        return self._http.request(
1508            f"/api/v1/threads/{thread}/settings",
1509            response_type=SettingListResponse,
1510        )
1511
1512    def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings:
1513        """
1514        Update thread settings
1515        Updates the settings for the specified thread. Only fields included in
1516        the `settings` map are modified; omitted fields retain their current values.
1517        The authenticated user must own the thread or be a member of its workspace.
1518        Returns the full settings object reflecting the state after the update.
1519        Validation errors are returned as `422 Unprocessable Entity`.
1520
1521        Args:
1522            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
1523            input: Request body.
1524            input.settings: Map of settings fields to update. Include only the keys you want to change.
1525
1526        Returns:
1527            The thread settings object after the update has been applied.
1528        """
1529        return self._http.request(
1530            f"/api/v1/threads/{thread}/settings",
1531            method="PUT",
1532            body=input,
1533            response_type=ThreadSettings,
1534        )
SettingResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1489    def __init__(self, http: SyncHttpClient):
1490        self._http = http
def list( self, thread: str) -> SettingListResponse:
1492    def list(self, thread: str) -> SettingListResponse:
1493        """
1494        Retrieve thread settings
1495        Returns the current settings for the specified thread. Settings control
1496        per-thread behavior such as whether the AI agent is enabled.
1497        The authenticated user must own the thread or be a member of its workspace.
1498        If settings have never been explicitly configured, defaults are returned
1499        (for example, `agent_enabled` defaults to `true`).
1500
1501        Args:
1502            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
1503
1504        Returns:
1505            Successful response
1506        """
1507        return self._http.request(
1508            f"/api/v1/threads/{thread}/settings",
1509            response_type=SettingListResponse,
1510        )

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:
1512    def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings:
1513        """
1514        Update thread settings
1515        Updates the settings for the specified thread. Only fields included in
1516        the `settings` map are modified; omitted fields retain their current values.
1517        The authenticated user must own the thread or be a member of its workspace.
1518        Returns the full settings object reflecting the state after the update.
1519        Validation errors are returned as `422 Unprocessable Entity`.
1520
1521        Args:
1522            thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace.
1523            input: Request body.
1524            input.settings: Map of settings fields to update. Include only the keys you want to change.
1525
1526        Returns:
1527            The thread settings object after the update has been applied.
1528        """
1529        return self._http.request(
1530            f"/api/v1/threads/{thread}/settings",
1531            method="PUT",
1532            body=input,
1533            response_type=ThreadSettings,
1534        )

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 TagResource:
1537class TagResource:
1538    def __init__(self, http: SyncHttpClient):
1539        self._http = http
1540
1541    def remove(self, thread: str) -> Thread:
1542        """
1543        Remove tags from a thread
1544        Removes one or more status tags from the thread and returns the updated
1545        thread. Removing a tag the thread does not have is a no-op.
1546        Any participant of the thread a human member or an agent member may edit
1547        tags. Supply the tags to remove as repeated query parameters, e.g.
1548        `?tags[]=blocked&tags[]=needs-review`.
1549
1550        Args:
1551            thread: Thread ID (`thr_...`) to untag.
1552
1553        Returns:
1554            The thread object after the tags were removed.
1555        """
1556        return self._http.request(
1557            f"/api/v1/threads/{thread}/tags",
1558            method="DELETE",
1559            response_type=Thread,
1560        )
1561
1562    def create(self, thread: str, input: TagCreateInput) -> Thread:
1563        """
1564        Add tags to a thread
1565        Adds one or more status tags to the thread and returns the updated thread.
1566        Any participant of the thread a human member or an agent member may edit
1567        tags; this is broader than the owner/admin permission required to update other
1568        thread fields. Adding a tag the thread already has is a no-op. Tags are
1569        normalized (trimmed and lowercased) and may contain only lowercase letters,
1570        numbers, hyphens, and underscores.
1571
1572        Args:
1573            thread: Thread ID (`thr_...`) to untag.
1574            input: Request body.
1575            input.tags: Tags to add to the thread.
1576
1577        Returns:
1578            The thread object after the tags were added.
1579        """
1580        return self._http.request(
1581            f"/api/v1/threads/{thread}/tags",
1582            method="POST",
1583            body=input,
1584            response_type=Thread,
1585        )
1586
1587    def replace(self, thread: str, input: TagReplaceInput) -> Thread:
1588        """
1589        Replace a thread's tags
1590        Replaces the thread's entire set of status tags with the provided list and
1591        returns the updated thread. Passing an empty array clears all tags.
1592        Any participant of the thread a human member or an agent member may edit
1593        tags. Tags are normalized (trimmed and lowercased) and may contain only
1594        lowercase letters, numbers, hyphens, and underscores.
1595
1596        Args:
1597            thread: Thread ID (`thr_...`) to untag.
1598            input: Request body.
1599            input.tags: The complete set of tags for the thread. An empty array clears all tags.
1600
1601        Returns:
1602            The thread object after its tags were replaced.
1603        """
1604        return self._http.request(
1605            f"/api/v1/threads/{thread}/tags",
1606            method="PUT",
1607            body=input,
1608            response_type=Thread,
1609        )
1538    def __init__(self, http: SyncHttpClient):
1539        self._http = http
def remove(self, thread: str) -> archastro.platform.types.threads.Thread:
1541    def remove(self, thread: str) -> Thread:
1542        """
1543        Remove tags from a thread
1544        Removes one or more status tags from the thread and returns the updated
1545        thread. Removing a tag the thread does not have is a no-op.
1546        Any participant of the thread a human member or an agent member may edit
1547        tags. Supply the tags to remove as repeated query parameters, e.g.
1548        `?tags[]=blocked&tags[]=needs-review`.
1549
1550        Args:
1551            thread: Thread ID (`thr_...`) to untag.
1552
1553        Returns:
1554            The thread object after the tags were removed.
1555        """
1556        return self._http.request(
1557            f"/api/v1/threads/{thread}/tags",
1558            method="DELETE",
1559            response_type=Thread,
1560        )

Remove tags from a thread Removes one or more status tags from the thread and returns the updated thread. Removing a tag the thread does not have is a no-op. Any participant of the thread a human member or an agent member may edit tags. Supply the tags to remove as repeated query parameters, e.g. ?tags[]=blocked&tags[]=needs-review.

Arguments:
  • thread: Thread ID (thr_...) to untag.
Returns:

The thread object after the tags were removed.

def create( self, thread: str, input: TagCreateInput) -> archastro.platform.types.threads.Thread:
1562    def create(self, thread: str, input: TagCreateInput) -> Thread:
1563        """
1564        Add tags to a thread
1565        Adds one or more status tags to the thread and returns the updated thread.
1566        Any participant of the thread a human member or an agent member may edit
1567        tags; this is broader than the owner/admin permission required to update other
1568        thread fields. Adding a tag the thread already has is a no-op. Tags are
1569        normalized (trimmed and lowercased) and may contain only lowercase letters,
1570        numbers, hyphens, and underscores.
1571
1572        Args:
1573            thread: Thread ID (`thr_...`) to untag.
1574            input: Request body.
1575            input.tags: Tags to add to the thread.
1576
1577        Returns:
1578            The thread object after the tags were added.
1579        """
1580        return self._http.request(
1581            f"/api/v1/threads/{thread}/tags",
1582            method="POST",
1583            body=input,
1584            response_type=Thread,
1585        )

Add tags to a thread Adds one or more status tags to the thread and returns the updated thread. Any participant of the thread a human member or an agent member may edit tags; this is broader than the owner/admin permission required to update other thread fields. Adding a tag the thread already has is a no-op. Tags are normalized (trimmed and lowercased) and may contain only lowercase letters, numbers, hyphens, and underscores.

Arguments:
  • thread: Thread ID (thr_...) to untag.
  • input: Request body.
  • input.tags: Tags to add to the thread.
Returns:

The thread object after the tags were added.

def replace( self, thread: str, input: TagReplaceInput) -> archastro.platform.types.threads.Thread:
1587    def replace(self, thread: str, input: TagReplaceInput) -> Thread:
1588        """
1589        Replace a thread's tags
1590        Replaces the thread's entire set of status tags with the provided list and
1591        returns the updated thread. Passing an empty array clears all tags.
1592        Any participant of the thread a human member or an agent member may edit
1593        tags. Tags are normalized (trimmed and lowercased) and may contain only
1594        lowercase letters, numbers, hyphens, and underscores.
1595
1596        Args:
1597            thread: Thread ID (`thr_...`) to untag.
1598            input: Request body.
1599            input.tags: The complete set of tags for the thread. An empty array clears all tags.
1600
1601        Returns:
1602            The thread object after its tags were replaced.
1603        """
1604        return self._http.request(
1605            f"/api/v1/threads/{thread}/tags",
1606            method="PUT",
1607            body=input,
1608            response_type=Thread,
1609        )

Replace a thread's tags Replaces the thread's entire set of status tags with the provided list and returns the updated thread. Passing an empty array clears all tags. Any participant of the thread a human member or an agent member may edit tags. Tags are normalized (trimmed and lowercased) and may contain only lowercase letters, numbers, hyphens, and underscores.

Arguments:
  • thread: Thread ID (thr_...) to untag.
  • input: Request body.
  • input.tags: The complete set of tags for the thread. An empty array clears all tags.
Returns:

The thread object after its tags were replaced.

class ThreadResource:
1612class ThreadResource:
1613    def __init__(self, http: SyncHttpClient):
1614        self._http = http
1615        self.members = ThreadMemberResource(http)
1616        self.settings = SettingResource(http)
1617        self.tags = TagResource(http)
1618
1619    def delete(self, thread: str) -> None:
1620        """
1621        Delete a thread
1622        Permanently deletes a thread and all of its messages and artifacts. This action
1623        cannot be undone.
1624        The authenticated user must own the thread or be an owner of the team the thread
1625        belongs to. Attempting to delete a thread owned by another user or team returns 403.
1626
1627        Args:
1628            thread: Thread ID (`thr_...`). The authenticated user must own this thread.
1629
1630        Returns:
1631            Empty response on successful deletion.
1632        """
1633        self._http.request(f"/api/v1/threads/{thread}", method="DELETE")
1634
1635    def get(self, thread: str) -> Thread:
1636        """
1637        Retrieve a thread
1638        Returns the full thread record for the given thread ID. The authenticated user
1639        must own the thread or be a member of the workspace it belongs to.
1640        Use this endpoint to fetch the current state of a single thread, including its
1641        title, description, and metadata. To list many threads, use the list endpoint
1642        with cursor-based pagination.
1643
1644        Args:
1645            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1646
1647        Returns:
1648            The requested thread object.
1649        """
1650        return self._http.request(f"/api/v1/threads/{thread}", response_type=Thread)
1651
1652    def replace(self, thread: str, input: ThreadReplaceInput) -> Thread:
1653        """
1654        Update a thread
1655        Updates one or more mutable properties of the specified thread and returns
1656        the full thread object with the applied changes. Only the fields you provide
1657        are modified; omitted fields retain their current values.
1658        If `profile_picture` is supplied, the image is uploaded before the other
1659        fields are saved, after all ordinary thread fields have passed validation.
1660        Supplying invalid base64 picture data returns 422 and no other fields are
1661        updated.
1662        Visibility can only widen: `private` may become `restricted` or `team`, and
1663        `restricted` may become `team`. The authenticated viewer must have
1664        permission to modify the thread.
1665        Mirror-thread titles, descriptions, and notification state remain editable
1666        by privileged app viewers. Mirror metadata, visibility, and membership are
1667        provider-managed and cannot be changed through this endpoint.
1668
1669        Args:
1670            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1671            input: Request body.
1672            input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
1673            input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
1674            input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user.
1675            input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
1676            input.title: Human-readable display name for the thread. Replaces the existing title when provided.
1677            input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed.
1678
1679        Returns:
1680            The thread object after the update has been applied.
1681        """
1682        return self._http.request(
1683            f"/api/v1/threads/{thread}",
1684            method="PUT",
1685            body=input,
1686            response_type=Thread,
1687        )
1688
1689    def agents(self, thread: str) -> ThreadAgentsResponse:
1690        """
1691        List agents in a thread
1692        Returns the agents participating in the specified thread. Only personal user
1693        threads (threads owned by a single user, not a team) expose agents through
1694        this endpoint; requests for team threads return 404.
1695        The authenticated user must have visibility into the thread. Each agent entry
1696        includes display information such as name and profile picture. Thread-level
1697        overrides (e.g. a custom name or profile picture set for this thread) take
1698        precedence over the agent's default values. When the caller is the thread
1699        owner, each entry also includes an `agent_config` object describing the
1700        agent's message policy and context configuration.
1701
1702        Args:
1703            thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user.
1704
1705        Returns:
1706            Successful response
1707        """
1708        return self._http.request(
1709            f"/api/v1/threads/{thread}/agents",
1710            response_type=ThreadAgentsResponse,
1711        )
1712
1713    def artifacts(self, thread: str) -> ThreadArtifactsResponse:
1714        """
1715        List artifacts for a thread
1716        Returns all artifacts produced during a thread's AI conversation. Artifacts are
1717        structured outputs such as code files, documents, or generated assets created
1718        by the AI agent in response to messages in the thread.
1719        The authenticated user must have access to the specified thread. Results are
1720        returned in a single page; there is no cursor-based pagination for this endpoint.
1721
1722        Args:
1723            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user.
1724
1725        Returns:
1726            Successful response
1727        """
1728        return self._http.request(
1729            f"/api/v1/threads/{thread}/artifacts",
1730            response_type=ThreadArtifactsResponse,
1731        )
1732
1733    def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None:
1734        """
1735        Mark a thread as read
1736        Records that a user has read up to a specific message in the thread. Unread
1737        indicators and badge counts are cleared up to the specified message.
1738        You must supply exactly one of `last_read_message` or `use_latest_message`.
1739        Omitting both returns 400. If `use_latest_message` is `true` and the thread
1740        has no messages, the request succeeds silently with no state change.
1741        For server-to-server (S2S) requests where no user identity is present in the
1742        token, the `user` param is required to identify whose read state to update.
1743
1744        Args:
1745            thread: Thread ID (`thr_...`). The thread to mark as read.
1746            input: Request body.
1747            input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`.
1748            input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`.
1749            input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
1750
1751        Returns:
1752            Empty response on success.
1753        """
1754        self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input)
1755
1756    def messages(
1757        self,
1758        thread: str,
1759        *,
1760        before_cursor: str | None = None,
1761        after_cursor: str | None = None,
1762        metadata: dict[str, Any] | None = None,
1763        limit: int | None = None,
1764        anchor: str | None = None,
1765        direction: Literal["before", "after", "around"] | None = None,
1766        before_limit: int | None = None,
1767        after_limit: int | None = None,
1768        include_anchor: bool | None = None,
1769        anchor_agent_mode: Literal["cli", "embedded"] | None = None,
1770        anchor_agent: str | None = None,
1771        include_reply_counts: bool | None = None,
1772    ) -> ThreadMessagesResponse:
1773        """
1774        List messages in a thread
1775        Returns a cursor-paginated list of messages belonging to the specified thread,
1776        ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both
1777        to page through or bound the result set; omit both to receive the most recent page.
1778        Supply `anchor` and `direction` to fetch a window before, after, or around a
1779        specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to
1780        resolve the anchor from the latest embedded-agent message, and add
1781        `anchor_agent` to scope that resolution to a single sender agent.
1782        Supply `metadata` as a JSON-encoded structured expression to filter message
1783        metadata before cursor pagination or anchored window limits are applied.
1784        The authenticated user must have access to the thread's owner (workspace or user).
1785        A 403 is returned if the thread exists but is not accessible to the caller; a 404
1786        is returned if the thread does not exist or is not visible to the authenticated user.
1787        Pass `include_reply_counts: true` to annotate each message with the number of
1788        threaded replies it has received. This adds a small amount of latency and should
1789        be omitted when reply counts are not needed.
1790
1791        Args:
1792            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1793            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.
1794            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.
1795            metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits.
1796            limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
1797            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`.
1798            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`.
1799            before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100.
1800            after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100.
1801            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.
1802            anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode.
1803            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.
1804            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.
1805
1806        Returns:
1807            Successful response
1808        """
1809        query: dict[str, object] = {}
1810        if before_cursor is not None:
1811            query["before_cursor"] = before_cursor
1812        if after_cursor is not None:
1813            query["after_cursor"] = after_cursor
1814        if metadata is not None:
1815            query["metadata"] = metadata
1816        if limit is not None:
1817            query["limit"] = limit
1818        if anchor is not None:
1819            query["anchor"] = anchor
1820        if direction is not None:
1821            query["direction"] = direction
1822        if before_limit is not None:
1823            query["before_limit"] = before_limit
1824        if after_limit is not None:
1825            query["after_limit"] = after_limit
1826        if include_anchor is not None:
1827            query["include_anchor"] = include_anchor
1828        if anchor_agent_mode is not None:
1829            query["anchor_agent_mode"] = anchor_agent_mode
1830        if anchor_agent is not None:
1831            query["anchor_agent"] = anchor_agent
1832        if include_reply_counts is not None:
1833            query["include_reply_counts"] = include_reply_counts
1834        return self._http.request(
1835            f"/api/v1/threads/{thread}/messages",
1836            query=query,
1837            response_type=ThreadMessagesResponse,
1838        )
1839
1840    def picture(self, thread: str, input: ThreadPictureInput) -> Thread:
1841        """
1842        Update a thread's profile picture
1843        Uploads a new profile picture for the specified thread and returns the updated
1844        thread object. The image must be supplied as a base64-encoded string with its
1845        MIME type.
1846        The authenticated user must own the thread or be a team owner of the workspace
1847        the thread belongs to. Supplying invalid base64 data returns 422.
1848
1849        Args:
1850            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1851            input: Request body.
1852            input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
1853
1854        Returns:
1855            The thread object after the profile picture has been updated.
1856        """
1857        return self._http.request(
1858            f"/api/v1/threads/{thread}/picture",
1859            method="PUT",
1860            body=input,
1861            response_type=Thread,
1862        )
1863
1864    def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus:
1865        """
1866        Retrieve a thread's read status
1867        Returns the read status of a thread for the specified user, including the ID
1868        of the last message they have read and the number of unread messages remaining.
1869        For user-authenticated requests, the status is always returned for the
1870        authenticated user and the `user` parameter is ignored. For server-to-server
1871        (S2S) requests, the `user` parameter is required and must be a valid user ID.
1872        Returns 404 if the thread does not exist or the caller does not have access
1873        to it.
1874
1875        Args:
1876            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user.
1877            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.
1878
1879        Returns:
1880            The read status record for the requested thread and user.
1881        """
1882        query: dict[str, object] = {}
1883        if user is not None:
1884            query["user"] = user
1885        return self._http.request(
1886            f"/api/v1/threads/{thread}/read_status",
1887            query=query,
1888            response_type=ThreadReadStatus,
1889        )
1890
1891    def search(
1892        self,
1893        thread: str,
1894        q: str,
1895        *,
1896        app: str | None = None,
1897        limit: int | None = None,
1898        mode: Literal["text", "embedding", "hybrid"] | None = None,
1899        before_cursor: str | None = None,
1900        after_cursor: str | None = None,
1901    ) -> ThreadSearchResponse:
1902        """
1903        Search messages in a thread
1904        Searches canonical message content in the specified thread. `"text"` mode
1905        performs the existing case-insensitive substring search, `"embedding"` ranks
1906        stored message embeddings by cosine similarity, and `"hybrid"` combines the
1907        text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages
1908        visible to the authenticated caller are considered.
1909        Results are intentionally lean: each row contains only a bounded content
1910        snippet, sender identity, and timestamp. Attachments, reactions, ACLs, and
1911        metadata are neither hydrated nor serialized. At most 20 results are
1912        returned. Text results support chronological cursor pagination. Embedding and
1913        hybrid results are relevance-ranked single pages and return null cursors.
1914
1915        Args:
1916            thread: Thread ID (`thr_...`). Must be visible to the authenticated caller.
1917            app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount.
1918            q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
1919            limit: Maximum number of results. Defaults to 20 and is capped at 20.
1920            mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings.
1921            before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
1922            after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
1923
1924        Returns:
1925            Successful response
1926        """
1927        query: dict[str, object] = {}
1928        if app is not None:
1929            query["app"] = app
1930        query["q"] = q
1931        if limit is not None:
1932            query["limit"] = limit
1933        if mode is not None:
1934            query["mode"] = mode
1935        if before_cursor is not None:
1936            query["before_cursor"] = before_cursor
1937        if after_cursor is not None:
1938            query["after_cursor"] = after_cursor
1939        return self._http.request(
1940            f"/api/v1/threads/{thread}/search",
1941            query=query,
1942            response_type=ThreadSearchResponse,
1943        )
1944
1945    def trajectories(
1946        self,
1947        thread: str,
1948        *,
1949        before_cursor: str | None = None,
1950        after_cursor: str | None = None,
1951        limit: int | None = None,
1952        message: str | None = None,
1953    ) -> ThreadTrajectoriesResponse:
1954        """
1955        List trajectories for a thread
1956        Returns a cursor-paginated list of thread message trajectories associated with the
1957        specified thread. Each trajectory links a user message and its agent response to the
1958        underlying AI trajectory record that captured the model's reasoning steps.
1959        The authenticated user must own the thread or be a member of the workspace it belongs
1960        to. Results are returned in reverse chronological order by default. Use `before_cursor`
1961        and `after_cursor` to navigate pages; provide at most one cursor per request.
1962        Optionally filter results to trajectories produced in response to a specific message
1963        by supplying the `message` parameter. When no trajectories match the query, `data`
1964        is an empty array and both cursor fields are `null`. A cursor that cannot be decoded
1965        returns a 400 `invalid_cursor` error.
1966
1967        Args:
1968            thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace.
1969            before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position.
1970            after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position.
1971            limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
1972            message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message.
1973
1974        Returns:
1975            Successful response
1976        """
1977        query: dict[str, object] = {}
1978        if before_cursor is not None:
1979            query["before_cursor"] = before_cursor
1980        if after_cursor is not None:
1981            query["after_cursor"] = after_cursor
1982        if limit is not None:
1983            query["limit"] = limit
1984        if message is not None:
1985            query["message"] = message
1986        return self._http.request(
1987            f"/api/v1/threads/{thread}/trajectories",
1988            query=query,
1989            response_type=ThreadTrajectoriesResponse,
1990        )
ThreadResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1613    def __init__(self, http: SyncHttpClient):
1614        self._http = http
1615        self.members = ThreadMemberResource(http)
1616        self.settings = SettingResource(http)
1617        self.tags = TagResource(http)
members
settings
tags
def delete(self, thread: str) -> None:
1619    def delete(self, thread: str) -> None:
1620        """
1621        Delete a thread
1622        Permanently deletes a thread and all of its messages and artifacts. This action
1623        cannot be undone.
1624        The authenticated user must own the thread or be an owner of the team the thread
1625        belongs to. Attempting to delete a thread owned by another user or team returns 403.
1626
1627        Args:
1628            thread: Thread ID (`thr_...`). The authenticated user must own this thread.
1629
1630        Returns:
1631            Empty response on successful deletion.
1632        """
1633        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:
1635    def get(self, thread: str) -> Thread:
1636        """
1637        Retrieve a thread
1638        Returns the full thread record for the given thread ID. The authenticated user
1639        must own the thread or be a member of the workspace it belongs to.
1640        Use this endpoint to fetch the current state of a single thread, including its
1641        title, description, and metadata. To list many threads, use the list endpoint
1642        with cursor-based pagination.
1643
1644        Args:
1645            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1646
1647        Returns:
1648            The requested thread object.
1649        """
1650        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:
1652    def replace(self, thread: str, input: ThreadReplaceInput) -> Thread:
1653        """
1654        Update a thread
1655        Updates one or more mutable properties of the specified thread and returns
1656        the full thread object with the applied changes. Only the fields you provide
1657        are modified; omitted fields retain their current values.
1658        If `profile_picture` is supplied, the image is uploaded before the other
1659        fields are saved, after all ordinary thread fields have passed validation.
1660        Supplying invalid base64 picture data returns 422 and no other fields are
1661        updated.
1662        Visibility can only widen: `private` may become `restricted` or `team`, and
1663        `restricted` may become `team`. The authenticated viewer must have
1664        permission to modify the thread.
1665        Mirror-thread titles, descriptions, and notification state remain editable
1666        by privileged app viewers. Mirror metadata, visibility, and membership are
1667        provider-managed and cannot be changed through this endpoint.
1668
1669        Args:
1670            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1671            input: Request body.
1672            input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
1673            input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
1674            input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user.
1675            input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
1676            input.title: Human-readable display name for the thread. Replaces the existing title when provided.
1677            input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed.
1678
1679        Returns:
1680            The thread object after the update has been applied.
1681        """
1682        return self._http.request(
1683            f"/api/v1/threads/{thread}",
1684            method="PUT",
1685            body=input,
1686            response_type=Thread,
1687        )

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, after all ordinary thread fields have passed validation. Supplying invalid base64 picture data returns 422 and no other fields are updated. Visibility can only widen: private may become restricted or team, and restricted may become team. The authenticated viewer must have permission to modify the thread. Mirror-thread titles, descriptions, and notification state remain editable by privileged app viewers. Mirror metadata, visibility, and membership are provider-managed and cannot be changed through this endpoint.

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.
  • input.visibility: Widen a team-owned thread: private may become restricted or team, and restricted may become team. Visibility cannot be narrowed.
Returns:

The thread object after the update has been applied.

def agents( self, thread: str) -> ThreadAgentsResponse:
1689    def agents(self, thread: str) -> ThreadAgentsResponse:
1690        """
1691        List agents in a thread
1692        Returns the agents participating in the specified thread. Only personal user
1693        threads (threads owned by a single user, not a team) expose agents through
1694        this endpoint; requests for team threads return 404.
1695        The authenticated user must have visibility into the thread. Each agent entry
1696        includes display information such as name and profile picture. Thread-level
1697        overrides (e.g. a custom name or profile picture set for this thread) take
1698        precedence over the agent's default values. When the caller is the thread
1699        owner, each entry also includes an `agent_config` object describing the
1700        agent's message policy and context configuration.
1701
1702        Args:
1703            thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user.
1704
1705        Returns:
1706            Successful response
1707        """
1708        return self._http.request(
1709            f"/api/v1/threads/{thread}/agents",
1710            response_type=ThreadAgentsResponse,
1711        )

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:
1713    def artifacts(self, thread: str) -> ThreadArtifactsResponse:
1714        """
1715        List artifacts for a thread
1716        Returns all artifacts produced during a thread's AI conversation. Artifacts are
1717        structured outputs such as code files, documents, or generated assets created
1718        by the AI agent in response to messages in the thread.
1719        The authenticated user must have access to the specified thread. Results are
1720        returned in a single page; there is no cursor-based pagination for this endpoint.
1721
1722        Args:
1723            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user.
1724
1725        Returns:
1726            Successful response
1727        """
1728        return self._http.request(
1729            f"/api/v1/threads/{thread}/artifacts",
1730            response_type=ThreadArtifactsResponse,
1731        )

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:
1733    def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None:
1734        """
1735        Mark a thread as read
1736        Records that a user has read up to a specific message in the thread. Unread
1737        indicators and badge counts are cleared up to the specified message.
1738        You must supply exactly one of `last_read_message` or `use_latest_message`.
1739        Omitting both returns 400. If `use_latest_message` is `true` and the thread
1740        has no messages, the request succeeds silently with no state change.
1741        For server-to-server (S2S) requests where no user identity is present in the
1742        token, the `user` param is required to identify whose read state to update.
1743
1744        Args:
1745            thread: Thread ID (`thr_...`). The thread to mark as read.
1746            input: Request body.
1747            input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`.
1748            input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`.
1749            input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
1750
1751        Returns:
1752            Empty response on success.
1753        """
1754        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, metadata: dict[str, typing.Any] | 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:
1756    def messages(
1757        self,
1758        thread: str,
1759        *,
1760        before_cursor: str | None = None,
1761        after_cursor: str | None = None,
1762        metadata: dict[str, Any] | None = None,
1763        limit: int | None = None,
1764        anchor: str | None = None,
1765        direction: Literal["before", "after", "around"] | None = None,
1766        before_limit: int | None = None,
1767        after_limit: int | None = None,
1768        include_anchor: bool | None = None,
1769        anchor_agent_mode: Literal["cli", "embedded"] | None = None,
1770        anchor_agent: str | None = None,
1771        include_reply_counts: bool | None = None,
1772    ) -> ThreadMessagesResponse:
1773        """
1774        List messages in a thread
1775        Returns a cursor-paginated list of messages belonging to the specified thread,
1776        ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both
1777        to page through or bound the result set; omit both to receive the most recent page.
1778        Supply `anchor` and `direction` to fetch a window before, after, or around a
1779        specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to
1780        resolve the anchor from the latest embedded-agent message, and add
1781        `anchor_agent` to scope that resolution to a single sender agent.
1782        Supply `metadata` as a JSON-encoded structured expression to filter message
1783        metadata before cursor pagination or anchored window limits are applied.
1784        The authenticated user must have access to the thread's owner (workspace or user).
1785        A 403 is returned if the thread exists but is not accessible to the caller; a 404
1786        is returned if the thread does not exist or is not visible to the authenticated user.
1787        Pass `include_reply_counts: true` to annotate each message with the number of
1788        threaded replies it has received. This adds a small amount of latency and should
1789        be omitted when reply counts are not needed.
1790
1791        Args:
1792            thread: Thread ID (`thr_...`). The authenticated user must have access to this thread.
1793            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.
1794            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.
1795            metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits.
1796            limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
1797            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`.
1798            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`.
1799            before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100.
1800            after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100.
1801            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.
1802            anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode.
1803            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.
1804            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.
1805
1806        Returns:
1807            Successful response
1808        """
1809        query: dict[str, object] = {}
1810        if before_cursor is not None:
1811            query["before_cursor"] = before_cursor
1812        if after_cursor is not None:
1813            query["after_cursor"] = after_cursor
1814        if metadata is not None:
1815            query["metadata"] = metadata
1816        if limit is not None:
1817            query["limit"] = limit
1818        if anchor is not None:
1819            query["anchor"] = anchor
1820        if direction is not None:
1821            query["direction"] = direction
1822        if before_limit is not None:
1823            query["before_limit"] = before_limit
1824        if after_limit is not None:
1825            query["after_limit"] = after_limit
1826        if include_anchor is not None:
1827            query["include_anchor"] = include_anchor
1828        if anchor_agent_mode is not None:
1829            query["anchor_agent_mode"] = anchor_agent_mode
1830        if anchor_agent is not None:
1831            query["anchor_agent"] = anchor_agent
1832        if include_reply_counts is not None:
1833            query["include_reply_counts"] = include_reply_counts
1834        return self._http.request(
1835            f"/api/v1/threads/{thread}/messages",
1836            query=query,
1837            response_type=ThreadMessagesResponse,
1838        )

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. Supply metadata as a JSON-encoded structured expression to filter message metadata before cursor pagination or anchored window limits are applied. 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.
  • metadata: Structured metadata filter expression. Only messages whose metadata object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits.
  • limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
  • 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; maximum is 100.
  • after_limit: For direction=around, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100.
  • 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:
1840    def picture(self, thread: str, input: ThreadPictureInput) -> Thread:
1841        """
1842        Update a thread's profile picture
1843        Uploads a new profile picture for the specified thread and returns the updated
1844        thread object. The image must be supplied as a base64-encoded string with its
1845        MIME type.
1846        The authenticated user must own the thread or be a team owner of the workspace
1847        the thread belongs to. Supplying invalid base64 data returns 422.
1848
1849        Args:
1850            thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread.
1851            input: Request body.
1852            input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
1853
1854        Returns:
1855            The thread object after the profile picture has been updated.
1856        """
1857        return self._http.request(
1858            f"/api/v1/threads/{thread}/picture",
1859            method="PUT",
1860            body=input,
1861            response_type=Thread,
1862        )

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:
1864    def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus:
1865        """
1866        Retrieve a thread's read status
1867        Returns the read status of a thread for the specified user, including the ID
1868        of the last message they have read and the number of unread messages remaining.
1869        For user-authenticated requests, the status is always returned for the
1870        authenticated user and the `user` parameter is ignored. For server-to-server
1871        (S2S) requests, the `user` parameter is required and must be a valid user ID.
1872        Returns 404 if the thread does not exist or the caller does not have access
1873        to it.
1874
1875        Args:
1876            thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user.
1877            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.
1878
1879        Returns:
1880            The read status record for the requested thread and user.
1881        """
1882        query: dict[str, object] = {}
1883        if user is not None:
1884            query["user"] = user
1885        return self._http.request(
1886            f"/api/v1/threads/{thread}/read_status",
1887            query=query,
1888            response_type=ThreadReadStatus,
1889        )

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, *, app: str | None = None, limit: int | None = None, mode: Optional[Literal['text', 'embedding', 'hybrid']] = None, before_cursor: str | None = None, after_cursor: str | None = None) -> ThreadSearchResponse:
1891    def search(
1892        self,
1893        thread: str,
1894        q: str,
1895        *,
1896        app: str | None = None,
1897        limit: int | None = None,
1898        mode: Literal["text", "embedding", "hybrid"] | None = None,
1899        before_cursor: str | None = None,
1900        after_cursor: str | None = None,
1901    ) -> ThreadSearchResponse:
1902        """
1903        Search messages in a thread
1904        Searches canonical message content in the specified thread. `"text"` mode
1905        performs the existing case-insensitive substring search, `"embedding"` ranks
1906        stored message embeddings by cosine similarity, and `"hybrid"` combines the
1907        text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages
1908        visible to the authenticated caller are considered.
1909        Results are intentionally lean: each row contains only a bounded content
1910        snippet, sender identity, and timestamp. Attachments, reactions, ACLs, and
1911        metadata are neither hydrated nor serialized. At most 20 results are
1912        returned. Text results support chronological cursor pagination. Embedding and
1913        hybrid results are relevance-ranked single pages and return null cursors.
1914
1915        Args:
1916            thread: Thread ID (`thr_...`). Must be visible to the authenticated caller.
1917            app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount.
1918            q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
1919            limit: Maximum number of results. Defaults to 20 and is capped at 20.
1920            mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings.
1921            before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
1922            after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
1923
1924        Returns:
1925            Successful response
1926        """
1927        query: dict[str, object] = {}
1928        if app is not None:
1929            query["app"] = app
1930        query["q"] = q
1931        if limit is not None:
1932            query["limit"] = limit
1933        if mode is not None:
1934            query["mode"] = mode
1935        if before_cursor is not None:
1936            query["before_cursor"] = before_cursor
1937        if after_cursor is not None:
1938            query["after_cursor"] = after_cursor
1939        return self._http.request(
1940            f"/api/v1/threads/{thread}/search",
1941            query=query,
1942            response_type=ThreadSearchResponse,
1943        )

Search messages in a thread Searches canonical message content in the specified thread. "text" mode performs the existing case-insensitive substring search, "embedding" ranks stored message embeddings by cosine similarity, and "hybrid" combines the text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages visible to the authenticated caller are considered. Results are intentionally lean: each row contains only a bounded content snippet, sender identity, and timestamp. Attachments, reactions, ACLs, and metadata are neither hydrated nor serialized. At most 20 results are returned. Text results support chronological cursor pagination. Embedding and hybrid results are relevance-ranked single pages and return null cursors.

Arguments:
  • thread: Thread ID (thr_...). Must be visible to the authenticated caller.
  • app: App ID (app_...). Required by the protected developer mount and omitted from the public mount.
  • q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
  • limit: Maximum number of results. Defaults to 20 and is capped at 20.
  • mode: Search algorithm: text for substring matching, embedding for cosine similarity, or hybrid for RRF over both rankings.
  • before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
  • after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
Returns:

Successful response

def trajectories( self, thread: str, *, before_cursor: str | None = None, after_cursor: str | None = None, limit: int | None = None, message: str | None = None) -> ThreadTrajectoriesResponse:
1945    def trajectories(
1946        self,
1947        thread: str,
1948        *,
1949        before_cursor: str | None = None,
1950        after_cursor: str | None = None,
1951        limit: int | None = None,
1952        message: str | None = None,
1953    ) -> ThreadTrajectoriesResponse:
1954        """
1955        List trajectories for a thread
1956        Returns a cursor-paginated list of thread message trajectories associated with the
1957        specified thread. Each trajectory links a user message and its agent response to the
1958        underlying AI trajectory record that captured the model's reasoning steps.
1959        The authenticated user must own the thread or be a member of the workspace it belongs
1960        to. Results are returned in reverse chronological order by default. Use `before_cursor`
1961        and `after_cursor` to navigate pages; provide at most one cursor per request.
1962        Optionally filter results to trajectories produced in response to a specific message
1963        by supplying the `message` parameter. When no trajectories match the query, `data`
1964        is an empty array and both cursor fields are `null`. A cursor that cannot be decoded
1965        returns a 400 `invalid_cursor` error.
1966
1967        Args:
1968            thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace.
1969            before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position.
1970            after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position.
1971            limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
1972            message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message.
1973
1974        Returns:
1975            Successful response
1976        """
1977        query: dict[str, object] = {}
1978        if before_cursor is not None:
1979            query["before_cursor"] = before_cursor
1980        if after_cursor is not None:
1981            query["after_cursor"] = after_cursor
1982        if limit is not None:
1983            query["limit"] = limit
1984        if message is not None:
1985            query["message"] = message
1986        return self._http.request(
1987            f"/api/v1/threads/{thread}/trajectories",
1988            query=query,
1989            response_type=ThreadTrajectoriesResponse,
1990        )

List trajectories for a thread Returns a cursor-paginated list of thread message trajectories associated with the specified thread. Each trajectory links a user message and its agent response to the underlying AI trajectory record that captured the model's reasoning steps. The authenticated user must own the thread or be a member of the workspace it belongs to. Results are returned in reverse chronological order by default. Use before_cursor and after_cursor to navigate pages; provide at most one cursor per request. Optionally filter results to trajectories produced in response to a specific message by supplying the message parameter. When no trajectories match the query, data is an empty array and both cursor fields are null. A cursor that cannot be decoded returns a 400 invalid_cursor error.

Arguments:
  • thread: Thread ID (thr_...). The authenticated user must own this thread or belong to its workspace.
  • before_cursor: Opaque cursor from a previous response's before_cursor field. Returns the page of results preceding that cursor position.
  • after_cursor: Opaque cursor from a previous response's after_cursor field. Returns the page of results following that cursor position.
  • limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
  • message: Message ID (msg_...). When provided, limits results to trajectories associated with this specific message.
Returns:

Successful response