archastro.platform.v1.resources.artifacts
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: 6a317c2bbbbe 4 5from __future__ import annotations 6 7from typing import Any, Literal, Required, TypedDict 8 9from ...runtime.http_client import HttpClient, SyncHttpClient 10from ...types.artifacts import Artifact 11 12 13class ArtifactCreateInputAclAddItem(TypedDict, total=False): 14 actions: Required[list[str]] 15 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 16 principal: str | None 17 '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"`.' 18 principal_type: Required[str] 19 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 20 21 22class ArtifactCreateInputAclGrantsItem(TypedDict, total=False): 23 actions: Required[list[str]] 24 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 25 principal: str | None 26 '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"`.' 27 principal_type: Required[str] 28 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 29 30 31class ArtifactCreateInputAclRemoveItem(TypedDict, total=False): 32 principal: str | None 33 '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"`.' 34 principal_type: Required[str] 35 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 36 37 38class ArtifactCreateInputAcl(TypedDict, total=False): 39 add: list[ArtifactCreateInputAclAddItem] | None 40 "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." 41 grants: list[ArtifactCreateInputAclGrantsItem] | None 42 "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`." 43 remove: list[ArtifactCreateInputAclRemoveItem] | None 44 "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." 45 46 47class ArtifactCreateInputFile(TypedDict, total=False): 48 data: Required[str] 49 "File content encoded according to file.encoding (base64 by default)." 50 encoding: Literal["base64", "utf8"] | None 51 "Data encoding; defaults to base64. Use utf8 for script-generated text." 52 filename: str | None 53 "Original filename." 54 mime_type: str | None 55 "MIME type for the file." 56 57 58class ArtifactCreateInput(TypedDict, total=False): 59 "Create an artifact" 60 61 acl: ArtifactCreateInputAcl | None 62 "Initial access control list. Grants add read or write access beyond the owner." 63 agent: str | None 64 "Agent ID (`agt_...`) to associate with the artifact." 65 artifact: dict[str, Any] | None 66 "Legacy wrapper object containing artifact attributes. Prefer top-level fields." 67 description: str | None 68 "Optional longer artifact description." 69 file: ArtifactCreateInputFile | None 70 "File payload for the initial artifact version." 71 group_key: str | None 72 "Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity." 73 idempotency_key: str | None 74 "Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact." 75 name: str | None 76 "Human-readable artifact name." 77 org: str | None 78 "Organization owning a system artifact. Requires an organization admin or system viewer." 79 system: bool | None 80 "When true, create a system-owned artifact. Mutually exclusive with `team` and `user`." 81 team: str | None 82 "Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`." 83 thread: str | None 84 "Thread ID (`thr_...`) to associate with the artifact." 85 user: str | None 86 "User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied." 87 88 89class ArtifactReplaceInputAclAddItem(TypedDict, total=False): 90 actions: Required[list[str]] 91 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 92 principal: str | None 93 '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"`.' 94 principal_type: Required[str] 95 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 96 97 98class ArtifactReplaceInputAclGrantsItem(TypedDict, total=False): 99 actions: Required[list[str]] 100 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 101 principal: str | None 102 '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"`.' 103 principal_type: Required[str] 104 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 105 106 107class ArtifactReplaceInputAclRemoveItem(TypedDict, total=False): 108 principal: str | None 109 '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"`.' 110 principal_type: Required[str] 111 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 112 113 114class ArtifactReplaceInputAcl(TypedDict, total=False): 115 add: list[ArtifactReplaceInputAclAddItem] | None 116 "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." 117 grants: list[ArtifactReplaceInputAclGrantsItem] | None 118 "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`." 119 remove: list[ArtifactReplaceInputAclRemoveItem] | None 120 "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." 121 122 123class ArtifactReplaceInputFile(TypedDict, total=False): 124 data: Required[str] 125 "File content encoded according to file.encoding." 126 encoding: Literal["base64", "utf8"] | None 127 "Data encoding; defaults to base64. Use utf8 for script-generated text." 128 filename: str | None 129 "Original filename for the uploaded file." 130 mime_type: str | None 131 "MIME type of the uploaded file." 132 133 134class ArtifactReplaceInput(TypedDict, total=False): 135 "Update an artifact" 136 137 acl: ArtifactReplaceInputAcl | None 138 "Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version." 139 description: str | None 140 "New description for the artifact. Omit to leave the existing description unchanged." 141 file: ArtifactReplaceInputFile | None 142 "Replacement file payload. Omit to leave the current file unchanged." 143 file_content: str | None 144 "Legacy flat Base64 file content. Prefer `file.data`." 145 file_content_type: str | None 146 "Legacy flat MIME type. Prefer `file.mime_type`." 147 file_name: str | None 148 "Legacy flat filename. Prefer `file.filename`." 149 from_version: Required[int] 150 "The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version." 151 group_key: str | None 152 "Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates." 153 name: str | None 154 "New display name for the artifact. Omit to leave the existing name unchanged." 155 156 157class AsyncArtifactResource: 158 def __init__(self, http: HttpClient): 159 self._http = http 160 161 async def create(self, input: ArtifactCreateInput) -> Artifact: 162 """ 163 Create an artifact 164 Creates a new artifact and stores its file content. A file payload is required; 165 supply it via the `file.data` (Base64-encoded by default), `file.filename`, and 166 `file.mime_type` fields. The artifact is scoped to the owner resolved from the 167 request body either a team, a user, or an explicit system owner. When no 168 owner is supplied and the viewer is an authenticated user, the artifact 169 defaults to that user. 170 For company-readable snapshots, pass `system: true` and `org`. Organization 171 members can read these artifacts; organization admins and system viewers can 172 create them. Scripts may supply text directly using `file.encoding: "utf8"`. 173 Optionally associate the artifact with an existing thread or agent by passing 174 `thread` or `agent`. Legacy requests that wrap fields in an `artifact` object 175 are still accepted. 176 177 Args: 178 input: Request body. 179 input.acl: Initial access control list. Grants add read or write access beyond the owner. 180 input.agent: Agent ID (`agt_...`) to associate with the artifact. 181 input.artifact: Legacy wrapper object containing artifact attributes. Prefer top-level fields. 182 input.description: Optional longer artifact description. 183 input.file: File payload for the initial artifact version. 184 input.group_key: Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity. 185 input.idempotency_key: Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact. 186 input.name: Human-readable artifact name. 187 input.org: Organization owning a system artifact. Requires an organization admin or system viewer. 188 input.system: When true, create a system-owned artifact. Mutually exclusive with `team` and `user`. 189 input.team: Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`. 190 input.thread: Thread ID (`thr_...`) to associate with the artifact. 191 input.user: User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied. 192 193 Returns: 194 The newly created artifact. 195 """ 196 return await self._http.request( 197 "/api/v1/artifacts", 198 method="POST", 199 body=input, 200 response_type=Artifact, 201 ) 202 203 async def delete(self, artifact: str) -> None: 204 """ 205 Delete an artifact 206 Permanently deletes the artifact and all associated file versions. This 207 operation is irreversible deleted artifacts and their file content cannot 208 be recovered. 209 The authenticated user must have write access to the artifact's owning team 210 or organization. Returns 404 if the artifact does not exist or is not 211 accessible to the caller. 212 213 Args: 214 artifact: Artifact ID (`art_...`) of the artifact to delete. 215 216 Returns: 217 Empty body. HTTP 204 indicates the artifact and all associated file versions were permanently deleted. 218 """ 219 await self._http.request(f"/api/v1/artifacts/{artifact}", method="DELETE") 220 221 async def get(self, artifact: str) -> Artifact: 222 """ 223 Retrieve an artifact 224 Returns the artifact identified by `artifact`. The response includes metadata 225 such as name, description, version, and a signed `file_url` for downloading 226 the current file version. Image artifacts also include an `image_source` object 227 with display-ready metadata. 228 The authenticated user must have read access to the artifact's owning team or 229 organization. Returns 404 if the artifact does not exist or is not accessible 230 to the caller. 231 232 Args: 233 artifact: Artifact ID (`art_...`) of the artifact to retrieve. 234 235 Returns: 236 The requested artifact, including its current version's file metadata and signed download URL. 237 """ 238 return await self._http.request(f"/api/v1/artifacts/{artifact}", response_type=Artifact) 239 240 async def replace(self, artifact: str, input: ArtifactReplaceInput) -> Artifact: 241 """ 242 Update an artifact 243 Updates the metadata and, optionally, the file content of an existing artifact. 244 This endpoint uses optimistic concurrency control: you must supply the artifact's 245 current `version` number as `from_version`. If another update has incremented the 246 version since you last fetched the artifact, the request returns 409. 247 To replace the artifact's file, include a nested `file` object with Base64 248 `data`, `filename`, and `mime_type`. Omitting `file` leaves the existing file 249 unchanged. The authenticated user or developer must have write access to the 250 artifact's owner. 251 252 Args: 253 artifact: Artifact ID (`art_...`) of the artifact to update. 254 input: Request body. 255 input.acl: Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. 256 input.description: New description for the artifact. Omit to leave the existing description unchanged. 257 input.file: Replacement file payload. Omit to leave the current file unchanged. 258 input.file_content: Legacy flat Base64 file content. Prefer `file.data`. 259 input.file_content_type: Legacy flat MIME type. Prefer `file.mime_type`. 260 input.file_name: Legacy flat filename. Prefer `file.filename`. 261 input.from_version: The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version. 262 input.group_key: Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates. 263 input.name: New display name for the artifact. Omit to leave the existing name unchanged. 264 265 Returns: 266 The artifact after applying the update, reflecting the new version number and any changed metadata or file. 267 """ 268 return await self._http.request( 269 f"/api/v1/artifacts/{artifact}", 270 method="PUT", 271 body=input, 272 response_type=Artifact, 273 ) 274 275 async def archive(self, artifact: str) -> None: 276 """ 277 Archive an artifact 278 Soft-deletes the artifact identified by `artifact`. The artifact record is 279 retained in storage but is no longer returned by the list or show endpoints. 280 The authenticated user must have write access to the artifact's owning team or 281 organization. Attempting to archive an artifact you do not own returns 403. 282 Attempting to archive an artifact that does not exist or is already archived 283 returns 404. 284 285 Args: 286 artifact: Artifact ID (`art_...`) of the artifact to archive. 287 288 Returns: 289 Returns 204 No Content on success. The artifact is soft-deleted and no longer accessible through the API. 290 """ 291 await self._http.request(f"/api/v1/artifacts/{artifact}/archive", method="POST") 292 293 async def content(self, artifact: str, *, version: int | None = None) -> dict[str, str]: 294 """ 295 Retrieve raw artifact file content 296 Returns the raw binary content of the file stored for the specified artifact. 297 The response `Content-Type` header reflects the artifact file's MIME type, so 298 you can pipe the response body directly to disk or display it in a browser. 299 By default the endpoint serves the artifact's current version. Pass the 300 `version` parameter to retrieve a specific historical version. The authenticated 301 user must have read access to the artifact's owning team or organization. 302 303 Args: 304 artifact: Artifact ID (`art_...`) of the artifact whose content to retrieve. 305 version: Version number to retrieve. Omit to return the artifact's current version. 306 307 Returns: 308 Raw binary content of the artifact file. The `Content-Type` header is set to the artifact's stored MIME type. 309 """ 310 query: dict[str, object] = {} 311 if version is not None: 312 query["version"] = version 313 return await self._http.request_raw(f"/api/v1/artifacts/{artifact}/content", query=query) 314 315 316class ArtifactResource: 317 def __init__(self, http: SyncHttpClient): 318 self._http = http 319 320 def create(self, input: ArtifactCreateInput) -> Artifact: 321 """ 322 Create an artifact 323 Creates a new artifact and stores its file content. A file payload is required; 324 supply it via the `file.data` (Base64-encoded by default), `file.filename`, and 325 `file.mime_type` fields. The artifact is scoped to the owner resolved from the 326 request body either a team, a user, or an explicit system owner. When no 327 owner is supplied and the viewer is an authenticated user, the artifact 328 defaults to that user. 329 For company-readable snapshots, pass `system: true` and `org`. Organization 330 members can read these artifacts; organization admins and system viewers can 331 create them. Scripts may supply text directly using `file.encoding: "utf8"`. 332 Optionally associate the artifact with an existing thread or agent by passing 333 `thread` or `agent`. Legacy requests that wrap fields in an `artifact` object 334 are still accepted. 335 336 Args: 337 input: Request body. 338 input.acl: Initial access control list. Grants add read or write access beyond the owner. 339 input.agent: Agent ID (`agt_...`) to associate with the artifact. 340 input.artifact: Legacy wrapper object containing artifact attributes. Prefer top-level fields. 341 input.description: Optional longer artifact description. 342 input.file: File payload for the initial artifact version. 343 input.group_key: Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity. 344 input.idempotency_key: Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact. 345 input.name: Human-readable artifact name. 346 input.org: Organization owning a system artifact. Requires an organization admin or system viewer. 347 input.system: When true, create a system-owned artifact. Mutually exclusive with `team` and `user`. 348 input.team: Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`. 349 input.thread: Thread ID (`thr_...`) to associate with the artifact. 350 input.user: User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied. 351 352 Returns: 353 The newly created artifact. 354 """ 355 return self._http.request( 356 "/api/v1/artifacts", 357 method="POST", 358 body=input, 359 response_type=Artifact, 360 ) 361 362 def delete(self, artifact: str) -> None: 363 """ 364 Delete an artifact 365 Permanently deletes the artifact and all associated file versions. This 366 operation is irreversible deleted artifacts and their file content cannot 367 be recovered. 368 The authenticated user must have write access to the artifact's owning team 369 or organization. Returns 404 if the artifact does not exist or is not 370 accessible to the caller. 371 372 Args: 373 artifact: Artifact ID (`art_...`) of the artifact to delete. 374 375 Returns: 376 Empty body. HTTP 204 indicates the artifact and all associated file versions were permanently deleted. 377 """ 378 self._http.request(f"/api/v1/artifacts/{artifact}", method="DELETE") 379 380 def get(self, artifact: str) -> Artifact: 381 """ 382 Retrieve an artifact 383 Returns the artifact identified by `artifact`. The response includes metadata 384 such as name, description, version, and a signed `file_url` for downloading 385 the current file version. Image artifacts also include an `image_source` object 386 with display-ready metadata. 387 The authenticated user must have read access to the artifact's owning team or 388 organization. Returns 404 if the artifact does not exist or is not accessible 389 to the caller. 390 391 Args: 392 artifact: Artifact ID (`art_...`) of the artifact to retrieve. 393 394 Returns: 395 The requested artifact, including its current version's file metadata and signed download URL. 396 """ 397 return self._http.request(f"/api/v1/artifacts/{artifact}", response_type=Artifact) 398 399 def replace(self, artifact: str, input: ArtifactReplaceInput) -> Artifact: 400 """ 401 Update an artifact 402 Updates the metadata and, optionally, the file content of an existing artifact. 403 This endpoint uses optimistic concurrency control: you must supply the artifact's 404 current `version` number as `from_version`. If another update has incremented the 405 version since you last fetched the artifact, the request returns 409. 406 To replace the artifact's file, include a nested `file` object with Base64 407 `data`, `filename`, and `mime_type`. Omitting `file` leaves the existing file 408 unchanged. The authenticated user or developer must have write access to the 409 artifact's owner. 410 411 Args: 412 artifact: Artifact ID (`art_...`) of the artifact to update. 413 input: Request body. 414 input.acl: Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. 415 input.description: New description for the artifact. Omit to leave the existing description unchanged. 416 input.file: Replacement file payload. Omit to leave the current file unchanged. 417 input.file_content: Legacy flat Base64 file content. Prefer `file.data`. 418 input.file_content_type: Legacy flat MIME type. Prefer `file.mime_type`. 419 input.file_name: Legacy flat filename. Prefer `file.filename`. 420 input.from_version: The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version. 421 input.group_key: Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates. 422 input.name: New display name for the artifact. Omit to leave the existing name unchanged. 423 424 Returns: 425 The artifact after applying the update, reflecting the new version number and any changed metadata or file. 426 """ 427 return self._http.request( 428 f"/api/v1/artifacts/{artifact}", 429 method="PUT", 430 body=input, 431 response_type=Artifact, 432 ) 433 434 def archive(self, artifact: str) -> None: 435 """ 436 Archive an artifact 437 Soft-deletes the artifact identified by `artifact`. The artifact record is 438 retained in storage but is no longer returned by the list or show endpoints. 439 The authenticated user must have write access to the artifact's owning team or 440 organization. Attempting to archive an artifact you do not own returns 403. 441 Attempting to archive an artifact that does not exist or is already archived 442 returns 404. 443 444 Args: 445 artifact: Artifact ID (`art_...`) of the artifact to archive. 446 447 Returns: 448 Returns 204 No Content on success. The artifact is soft-deleted and no longer accessible through the API. 449 """ 450 self._http.request(f"/api/v1/artifacts/{artifact}/archive", method="POST") 451 452 def content(self, artifact: str, *, version: int | None = None) -> dict[str, str]: 453 """ 454 Retrieve raw artifact file content 455 Returns the raw binary content of the file stored for the specified artifact. 456 The response `Content-Type` header reflects the artifact file's MIME type, so 457 you can pipe the response body directly to disk or display it in a browser. 458 By default the endpoint serves the artifact's current version. Pass the 459 `version` parameter to retrieve a specific historical version. The authenticated 460 user must have read access to the artifact's owning team or organization. 461 462 Args: 463 artifact: Artifact ID (`art_...`) of the artifact whose content to retrieve. 464 version: Version number to retrieve. Omit to return the artifact's current version. 465 466 Returns: 467 Raw binary content of the artifact file. The `Content-Type` header is set to the artifact's stored MIME type. 468 """ 469 query: dict[str, object] = {} 470 if version is not None: 471 query["version"] = version 472 return self._http.request_raw(f"/api/v1/artifacts/{artifact}/content", query=query)
14class ArtifactCreateInputAclAddItem(TypedDict, total=False): 15 actions: Required[list[str]] 16 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 17 principal: str | None 18 '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"`.' 19 principal_type: Required[str] 20 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
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".
23class ArtifactCreateInputAclGrantsItem(TypedDict, total=False): 24 actions: Required[list[str]] 25 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 26 principal: str | None 27 '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"`.' 28 principal_type: Required[str] 29 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
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".
32class ArtifactCreateInputAclRemoveItem(TypedDict, total=False): 33 principal: str | None 34 '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"`.' 35 principal_type: Required[str] 36 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
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".
39class ArtifactCreateInputAcl(TypedDict, total=False): 40 add: list[ArtifactCreateInputAclAddItem] | None 41 "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." 42 grants: list[ArtifactCreateInputAclGrantsItem] | None 43 "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`." 44 remove: list[ArtifactCreateInputAclRemoveItem] | None 45 "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`."
Patch mode: grants to add or merge into the existing list. Cannot be combined with grants.
Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.
48class ArtifactCreateInputFile(TypedDict, total=False): 49 data: Required[str] 50 "File content encoded according to file.encoding (base64 by default)." 51 encoding: Literal["base64", "utf8"] | None 52 "Data encoding; defaults to base64. Use utf8 for script-generated text." 53 filename: str | None 54 "Original filename." 55 mime_type: str | None 56 "MIME type for the file."
59class ArtifactCreateInput(TypedDict, total=False): 60 "Create an artifact" 61 62 acl: ArtifactCreateInputAcl | None 63 "Initial access control list. Grants add read or write access beyond the owner." 64 agent: str | None 65 "Agent ID (`agt_...`) to associate with the artifact." 66 artifact: dict[str, Any] | None 67 "Legacy wrapper object containing artifact attributes. Prefer top-level fields." 68 description: str | None 69 "Optional longer artifact description." 70 file: ArtifactCreateInputFile | None 71 "File payload for the initial artifact version." 72 group_key: str | None 73 "Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity." 74 idempotency_key: str | None 75 "Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact." 76 name: str | None 77 "Human-readable artifact name." 78 org: str | None 79 "Organization owning a system artifact. Requires an organization admin or system viewer." 80 system: bool | None 81 "When true, create a system-owned artifact. Mutually exclusive with `team` and `user`." 82 team: str | None 83 "Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`." 84 thread: str | None 85 "Thread ID (`thr_...`) to associate with the artifact." 86 user: str | None 87 "User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied."
Create an artifact
Initial access control list. Grants add read or write access beyond the owner.
Legacy wrapper object containing artifact attributes. Prefer top-level fields.
Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity.
Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact.
Organization owning a system artifact. Requires an organization admin or system viewer.
90class ArtifactReplaceInputAclAddItem(TypedDict, total=False): 91 actions: Required[list[str]] 92 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 93 principal: str | None 94 '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"`.' 95 principal_type: Required[str] 96 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
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".
99class ArtifactReplaceInputAclGrantsItem(TypedDict, total=False): 100 actions: Required[list[str]] 101 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 102 principal: str | None 103 '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"`.' 104 principal_type: Required[str] 105 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
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".
108class ArtifactReplaceInputAclRemoveItem(TypedDict, total=False): 109 principal: str | None 110 '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"`.' 111 principal_type: Required[str] 112 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
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".
115class ArtifactReplaceInputAcl(TypedDict, total=False): 116 add: list[ArtifactReplaceInputAclAddItem] | None 117 "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." 118 grants: list[ArtifactReplaceInputAclGrantsItem] | None 119 "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`." 120 remove: list[ArtifactReplaceInputAclRemoveItem] | None 121 "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`."
Patch mode: grants to add or merge into the existing list. Cannot be combined with grants.
Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.
124class ArtifactReplaceInputFile(TypedDict, total=False): 125 data: Required[str] 126 "File content encoded according to file.encoding." 127 encoding: Literal["base64", "utf8"] | None 128 "Data encoding; defaults to base64. Use utf8 for script-generated text." 129 filename: str | None 130 "Original filename for the uploaded file." 131 mime_type: str | None 132 "MIME type of the uploaded file."
135class ArtifactReplaceInput(TypedDict, total=False): 136 "Update an artifact" 137 138 acl: ArtifactReplaceInputAcl | None 139 "Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version." 140 description: str | None 141 "New description for the artifact. Omit to leave the existing description unchanged." 142 file: ArtifactReplaceInputFile | None 143 "Replacement file payload. Omit to leave the current file unchanged." 144 file_content: str | None 145 "Legacy flat Base64 file content. Prefer `file.data`." 146 file_content_type: str | None 147 "Legacy flat MIME type. Prefer `file.mime_type`." 148 file_name: str | None 149 "Legacy flat filename. Prefer `file.filename`." 150 from_version: Required[int] 151 "The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version." 152 group_key: str | None 153 "Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates." 154 name: str | None 155 "New display name for the artifact. Omit to leave the existing name unchanged."
Update an artifact
Access control list replacement (grants) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version.
New description for the artifact. Omit to leave the existing description unchanged.
Replacement file payload. Omit to leave the current file unchanged.
The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version.
158class AsyncArtifactResource: 159 def __init__(self, http: HttpClient): 160 self._http = http 161 162 async def create(self, input: ArtifactCreateInput) -> Artifact: 163 """ 164 Create an artifact 165 Creates a new artifact and stores its file content. A file payload is required; 166 supply it via the `file.data` (Base64-encoded by default), `file.filename`, and 167 `file.mime_type` fields. The artifact is scoped to the owner resolved from the 168 request body either a team, a user, or an explicit system owner. When no 169 owner is supplied and the viewer is an authenticated user, the artifact 170 defaults to that user. 171 For company-readable snapshots, pass `system: true` and `org`. Organization 172 members can read these artifacts; organization admins and system viewers can 173 create them. Scripts may supply text directly using `file.encoding: "utf8"`. 174 Optionally associate the artifact with an existing thread or agent by passing 175 `thread` or `agent`. Legacy requests that wrap fields in an `artifact` object 176 are still accepted. 177 178 Args: 179 input: Request body. 180 input.acl: Initial access control list. Grants add read or write access beyond the owner. 181 input.agent: Agent ID (`agt_...`) to associate with the artifact. 182 input.artifact: Legacy wrapper object containing artifact attributes. Prefer top-level fields. 183 input.description: Optional longer artifact description. 184 input.file: File payload for the initial artifact version. 185 input.group_key: Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity. 186 input.idempotency_key: Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact. 187 input.name: Human-readable artifact name. 188 input.org: Organization owning a system artifact. Requires an organization admin or system viewer. 189 input.system: When true, create a system-owned artifact. Mutually exclusive with `team` and `user`. 190 input.team: Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`. 191 input.thread: Thread ID (`thr_...`) to associate with the artifact. 192 input.user: User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied. 193 194 Returns: 195 The newly created artifact. 196 """ 197 return await self._http.request( 198 "/api/v1/artifacts", 199 method="POST", 200 body=input, 201 response_type=Artifact, 202 ) 203 204 async def delete(self, artifact: str) -> None: 205 """ 206 Delete an artifact 207 Permanently deletes the artifact and all associated file versions. This 208 operation is irreversible deleted artifacts and their file content cannot 209 be recovered. 210 The authenticated user must have write access to the artifact's owning team 211 or organization. Returns 404 if the artifact does not exist or is not 212 accessible to the caller. 213 214 Args: 215 artifact: Artifact ID (`art_...`) of the artifact to delete. 216 217 Returns: 218 Empty body. HTTP 204 indicates the artifact and all associated file versions were permanently deleted. 219 """ 220 await self._http.request(f"/api/v1/artifacts/{artifact}", method="DELETE") 221 222 async def get(self, artifact: str) -> Artifact: 223 """ 224 Retrieve an artifact 225 Returns the artifact identified by `artifact`. The response includes metadata 226 such as name, description, version, and a signed `file_url` for downloading 227 the current file version. Image artifacts also include an `image_source` object 228 with display-ready metadata. 229 The authenticated user must have read access to the artifact's owning team or 230 organization. Returns 404 if the artifact does not exist or is not accessible 231 to the caller. 232 233 Args: 234 artifact: Artifact ID (`art_...`) of the artifact to retrieve. 235 236 Returns: 237 The requested artifact, including its current version's file metadata and signed download URL. 238 """ 239 return await self._http.request(f"/api/v1/artifacts/{artifact}", response_type=Artifact) 240 241 async def replace(self, artifact: str, input: ArtifactReplaceInput) -> Artifact: 242 """ 243 Update an artifact 244 Updates the metadata and, optionally, the file content of an existing artifact. 245 This endpoint uses optimistic concurrency control: you must supply the artifact's 246 current `version` number as `from_version`. If another update has incremented the 247 version since you last fetched the artifact, the request returns 409. 248 To replace the artifact's file, include a nested `file` object with Base64 249 `data`, `filename`, and `mime_type`. Omitting `file` leaves the existing file 250 unchanged. The authenticated user or developer must have write access to the 251 artifact's owner. 252 253 Args: 254 artifact: Artifact ID (`art_...`) of the artifact to update. 255 input: Request body. 256 input.acl: Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. 257 input.description: New description for the artifact. Omit to leave the existing description unchanged. 258 input.file: Replacement file payload. Omit to leave the current file unchanged. 259 input.file_content: Legacy flat Base64 file content. Prefer `file.data`. 260 input.file_content_type: Legacy flat MIME type. Prefer `file.mime_type`. 261 input.file_name: Legacy flat filename. Prefer `file.filename`. 262 input.from_version: The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version. 263 input.group_key: Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates. 264 input.name: New display name for the artifact. Omit to leave the existing name unchanged. 265 266 Returns: 267 The artifact after applying the update, reflecting the new version number and any changed metadata or file. 268 """ 269 return await self._http.request( 270 f"/api/v1/artifacts/{artifact}", 271 method="PUT", 272 body=input, 273 response_type=Artifact, 274 ) 275 276 async def archive(self, artifact: str) -> None: 277 """ 278 Archive an artifact 279 Soft-deletes the artifact identified by `artifact`. The artifact record is 280 retained in storage but is no longer returned by the list or show endpoints. 281 The authenticated user must have write access to the artifact's owning team or 282 organization. Attempting to archive an artifact you do not own returns 403. 283 Attempting to archive an artifact that does not exist or is already archived 284 returns 404. 285 286 Args: 287 artifact: Artifact ID (`art_...`) of the artifact to archive. 288 289 Returns: 290 Returns 204 No Content on success. The artifact is soft-deleted and no longer accessible through the API. 291 """ 292 await self._http.request(f"/api/v1/artifacts/{artifact}/archive", method="POST") 293 294 async def content(self, artifact: str, *, version: int | None = None) -> dict[str, str]: 295 """ 296 Retrieve raw artifact file content 297 Returns the raw binary content of the file stored for the specified artifact. 298 The response `Content-Type` header reflects the artifact file's MIME type, so 299 you can pipe the response body directly to disk or display it in a browser. 300 By default the endpoint serves the artifact's current version. Pass the 301 `version` parameter to retrieve a specific historical version. The authenticated 302 user must have read access to the artifact's owning team or organization. 303 304 Args: 305 artifact: Artifact ID (`art_...`) of the artifact whose content to retrieve. 306 version: Version number to retrieve. Omit to return the artifact's current version. 307 308 Returns: 309 Raw binary content of the artifact file. The `Content-Type` header is set to the artifact's stored MIME type. 310 """ 311 query: dict[str, object] = {} 312 if version is not None: 313 query["version"] = version 314 return await self._http.request_raw(f"/api/v1/artifacts/{artifact}/content", query=query)
162 async def create(self, input: ArtifactCreateInput) -> Artifact: 163 """ 164 Create an artifact 165 Creates a new artifact and stores its file content. A file payload is required; 166 supply it via the `file.data` (Base64-encoded by default), `file.filename`, and 167 `file.mime_type` fields. The artifact is scoped to the owner resolved from the 168 request body either a team, a user, or an explicit system owner. When no 169 owner is supplied and the viewer is an authenticated user, the artifact 170 defaults to that user. 171 For company-readable snapshots, pass `system: true` and `org`. Organization 172 members can read these artifacts; organization admins and system viewers can 173 create them. Scripts may supply text directly using `file.encoding: "utf8"`. 174 Optionally associate the artifact with an existing thread or agent by passing 175 `thread` or `agent`. Legacy requests that wrap fields in an `artifact` object 176 are still accepted. 177 178 Args: 179 input: Request body. 180 input.acl: Initial access control list. Grants add read or write access beyond the owner. 181 input.agent: Agent ID (`agt_...`) to associate with the artifact. 182 input.artifact: Legacy wrapper object containing artifact attributes. Prefer top-level fields. 183 input.description: Optional longer artifact description. 184 input.file: File payload for the initial artifact version. 185 input.group_key: Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity. 186 input.idempotency_key: Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact. 187 input.name: Human-readable artifact name. 188 input.org: Organization owning a system artifact. Requires an organization admin or system viewer. 189 input.system: When true, create a system-owned artifact. Mutually exclusive with `team` and `user`. 190 input.team: Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`. 191 input.thread: Thread ID (`thr_...`) to associate with the artifact. 192 input.user: User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied. 193 194 Returns: 195 The newly created artifact. 196 """ 197 return await self._http.request( 198 "/api/v1/artifacts", 199 method="POST", 200 body=input, 201 response_type=Artifact, 202 )
Create an artifact
Creates a new artifact and stores its file content. A file payload is required;
supply it via the file.data (Base64-encoded by default), file.filename, and
file.mime_type fields. The artifact is scoped to the owner resolved from the
request body either a team, a user, or an explicit system owner. When no
owner is supplied and the viewer is an authenticated user, the artifact
defaults to that user.
For company-readable snapshots, pass system: true and org. Organization
members can read these artifacts; organization admins and system viewers can
create them. Scripts may supply text directly using file.encoding: "utf8".
Optionally associate the artifact with an existing thread or agent by passing
thread or agent. Legacy requests that wrap fields in an artifact object
are still accepted.
Arguments:
- input: Request body.
- input.acl: Initial access control list. Grants add read or write access beyond the owner.
- input.agent: Agent ID (
agt_...) to associate with the artifact. - input.artifact: Legacy wrapper object containing artifact attributes. Prefer top-level fields.
- input.description: Optional longer artifact description.
- input.file: File payload for the initial artifact version.
- input.group_key: Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity.
- input.idempotency_key: Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact.
- input.name: Human-readable artifact name.
- input.org: Organization owning a system artifact. Requires an organization admin or system viewer.
- input.system: When true, create a system-owned artifact. Mutually exclusive with
teamanduser. - input.team: Team ID (
tem_...) that should own the artifact. Mutually exclusive withuser. - input.thread: Thread ID (
thr_...) to associate with the artifact. - input.user: User ID (
usr_...) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied.
Returns:
The newly created artifact.
204 async def delete(self, artifact: str) -> None: 205 """ 206 Delete an artifact 207 Permanently deletes the artifact and all associated file versions. This 208 operation is irreversible deleted artifacts and their file content cannot 209 be recovered. 210 The authenticated user must have write access to the artifact's owning team 211 or organization. Returns 404 if the artifact does not exist or is not 212 accessible to the caller. 213 214 Args: 215 artifact: Artifact ID (`art_...`) of the artifact to delete. 216 217 Returns: 218 Empty body. HTTP 204 indicates the artifact and all associated file versions were permanently deleted. 219 """ 220 await self._http.request(f"/api/v1/artifacts/{artifact}", method="DELETE")
Delete an artifact Permanently deletes the artifact and all associated file versions. This operation is irreversible deleted artifacts and their file content cannot be recovered. The authenticated user must have write access to the artifact's owning team or organization. Returns 404 if the artifact does not exist or is not accessible to the caller.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact to delete.
Returns:
Empty body. HTTP 204 indicates the artifact and all associated file versions were permanently deleted.
222 async def get(self, artifact: str) -> Artifact: 223 """ 224 Retrieve an artifact 225 Returns the artifact identified by `artifact`. The response includes metadata 226 such as name, description, version, and a signed `file_url` for downloading 227 the current file version. Image artifacts also include an `image_source` object 228 with display-ready metadata. 229 The authenticated user must have read access to the artifact's owning team or 230 organization. Returns 404 if the artifact does not exist or is not accessible 231 to the caller. 232 233 Args: 234 artifact: Artifact ID (`art_...`) of the artifact to retrieve. 235 236 Returns: 237 The requested artifact, including its current version's file metadata and signed download URL. 238 """ 239 return await self._http.request(f"/api/v1/artifacts/{artifact}", response_type=Artifact)
Retrieve an artifact
Returns the artifact identified by artifact. The response includes metadata
such as name, description, version, and a signed file_url for downloading
the current file version. Image artifacts also include an image_source object
with display-ready metadata.
The authenticated user must have read access to the artifact's owning team or
organization. Returns 404 if the artifact does not exist or is not accessible
to the caller.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact to retrieve.
Returns:
The requested artifact, including its current version's file metadata and signed download URL.
241 async def replace(self, artifact: str, input: ArtifactReplaceInput) -> Artifact: 242 """ 243 Update an artifact 244 Updates the metadata and, optionally, the file content of an existing artifact. 245 This endpoint uses optimistic concurrency control: you must supply the artifact's 246 current `version` number as `from_version`. If another update has incremented the 247 version since you last fetched the artifact, the request returns 409. 248 To replace the artifact's file, include a nested `file` object with Base64 249 `data`, `filename`, and `mime_type`. Omitting `file` leaves the existing file 250 unchanged. The authenticated user or developer must have write access to the 251 artifact's owner. 252 253 Args: 254 artifact: Artifact ID (`art_...`) of the artifact to update. 255 input: Request body. 256 input.acl: Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. 257 input.description: New description for the artifact. Omit to leave the existing description unchanged. 258 input.file: Replacement file payload. Omit to leave the current file unchanged. 259 input.file_content: Legacy flat Base64 file content. Prefer `file.data`. 260 input.file_content_type: Legacy flat MIME type. Prefer `file.mime_type`. 261 input.file_name: Legacy flat filename. Prefer `file.filename`. 262 input.from_version: The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version. 263 input.group_key: Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates. 264 input.name: New display name for the artifact. Omit to leave the existing name unchanged. 265 266 Returns: 267 The artifact after applying the update, reflecting the new version number and any changed metadata or file. 268 """ 269 return await self._http.request( 270 f"/api/v1/artifacts/{artifact}", 271 method="PUT", 272 body=input, 273 response_type=Artifact, 274 )
Update an artifact
Updates the metadata and, optionally, the file content of an existing artifact.
This endpoint uses optimistic concurrency control: you must supply the artifact's
current version number as from_version. If another update has incremented the
version since you last fetched the artifact, the request returns 409.
To replace the artifact's file, include a nested file object with Base64
data, filename, and mime_type. Omitting file leaves the existing file
unchanged. The authenticated user or developer must have write access to the
artifact's owner.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact to update. - input: Request body.
- input.acl: Access control list replacement (
grants) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. - input.description: New description for the artifact. Omit to leave the existing description unchanged.
- input.file: Replacement file payload. Omit to leave the current file unchanged.
- input.file_content: Legacy flat Base64 file content. Prefer
file.data. - input.file_content_type: Legacy flat MIME type. Prefer
file.mime_type. - input.file_name: Legacy flat filename. Prefer
file.filename. - input.from_version: The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version.
- input.group_key: Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates.
- input.name: New display name for the artifact. Omit to leave the existing name unchanged.
Returns:
The artifact after applying the update, reflecting the new version number and any changed metadata or file.
276 async def archive(self, artifact: str) -> None: 277 """ 278 Archive an artifact 279 Soft-deletes the artifact identified by `artifact`. The artifact record is 280 retained in storage but is no longer returned by the list or show endpoints. 281 The authenticated user must have write access to the artifact's owning team or 282 organization. Attempting to archive an artifact you do not own returns 403. 283 Attempting to archive an artifact that does not exist or is already archived 284 returns 404. 285 286 Args: 287 artifact: Artifact ID (`art_...`) of the artifact to archive. 288 289 Returns: 290 Returns 204 No Content on success. The artifact is soft-deleted and no longer accessible through the API. 291 """ 292 await self._http.request(f"/api/v1/artifacts/{artifact}/archive", method="POST")
Archive an artifact
Soft-deletes the artifact identified by artifact. The artifact record is
retained in storage but is no longer returned by the list or show endpoints.
The authenticated user must have write access to the artifact's owning team or
organization. Attempting to archive an artifact you do not own returns 403.
Attempting to archive an artifact that does not exist or is already archived
returns 404.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact to archive.
Returns:
Returns 204 No Content on success. The artifact is soft-deleted and no longer accessible through the API.
294 async def content(self, artifact: str, *, version: int | None = None) -> dict[str, str]: 295 """ 296 Retrieve raw artifact file content 297 Returns the raw binary content of the file stored for the specified artifact. 298 The response `Content-Type` header reflects the artifact file's MIME type, so 299 you can pipe the response body directly to disk or display it in a browser. 300 By default the endpoint serves the artifact's current version. Pass the 301 `version` parameter to retrieve a specific historical version. The authenticated 302 user must have read access to the artifact's owning team or organization. 303 304 Args: 305 artifact: Artifact ID (`art_...`) of the artifact whose content to retrieve. 306 version: Version number to retrieve. Omit to return the artifact's current version. 307 308 Returns: 309 Raw binary content of the artifact file. The `Content-Type` header is set to the artifact's stored MIME type. 310 """ 311 query: dict[str, object] = {} 312 if version is not None: 313 query["version"] = version 314 return await self._http.request_raw(f"/api/v1/artifacts/{artifact}/content", query=query)
Retrieve raw artifact file content
Returns the raw binary content of the file stored for the specified artifact.
The response Content-Type header reflects the artifact file's MIME type, so
you can pipe the response body directly to disk or display it in a browser.
By default the endpoint serves the artifact's current version. Pass the
version parameter to retrieve a specific historical version. The authenticated
user must have read access to the artifact's owning team or organization.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact whose content to retrieve. - version: Version number to retrieve. Omit to return the artifact's current version.
Returns:
Raw binary content of the artifact file. The
Content-Typeheader is set to the artifact's stored MIME type.
317class ArtifactResource: 318 def __init__(self, http: SyncHttpClient): 319 self._http = http 320 321 def create(self, input: ArtifactCreateInput) -> Artifact: 322 """ 323 Create an artifact 324 Creates a new artifact and stores its file content. A file payload is required; 325 supply it via the `file.data` (Base64-encoded by default), `file.filename`, and 326 `file.mime_type` fields. The artifact is scoped to the owner resolved from the 327 request body either a team, a user, or an explicit system owner. When no 328 owner is supplied and the viewer is an authenticated user, the artifact 329 defaults to that user. 330 For company-readable snapshots, pass `system: true` and `org`. Organization 331 members can read these artifacts; organization admins and system viewers can 332 create them. Scripts may supply text directly using `file.encoding: "utf8"`. 333 Optionally associate the artifact with an existing thread or agent by passing 334 `thread` or `agent`. Legacy requests that wrap fields in an `artifact` object 335 are still accepted. 336 337 Args: 338 input: Request body. 339 input.acl: Initial access control list. Grants add read or write access beyond the owner. 340 input.agent: Agent ID (`agt_...`) to associate with the artifact. 341 input.artifact: Legacy wrapper object containing artifact attributes. Prefer top-level fields. 342 input.description: Optional longer artifact description. 343 input.file: File payload for the initial artifact version. 344 input.group_key: Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity. 345 input.idempotency_key: Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact. 346 input.name: Human-readable artifact name. 347 input.org: Organization owning a system artifact. Requires an organization admin or system viewer. 348 input.system: When true, create a system-owned artifact. Mutually exclusive with `team` and `user`. 349 input.team: Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`. 350 input.thread: Thread ID (`thr_...`) to associate with the artifact. 351 input.user: User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied. 352 353 Returns: 354 The newly created artifact. 355 """ 356 return self._http.request( 357 "/api/v1/artifacts", 358 method="POST", 359 body=input, 360 response_type=Artifact, 361 ) 362 363 def delete(self, artifact: str) -> None: 364 """ 365 Delete an artifact 366 Permanently deletes the artifact and all associated file versions. This 367 operation is irreversible deleted artifacts and their file content cannot 368 be recovered. 369 The authenticated user must have write access to the artifact's owning team 370 or organization. Returns 404 if the artifact does not exist or is not 371 accessible to the caller. 372 373 Args: 374 artifact: Artifact ID (`art_...`) of the artifact to delete. 375 376 Returns: 377 Empty body. HTTP 204 indicates the artifact and all associated file versions were permanently deleted. 378 """ 379 self._http.request(f"/api/v1/artifacts/{artifact}", method="DELETE") 380 381 def get(self, artifact: str) -> Artifact: 382 """ 383 Retrieve an artifact 384 Returns the artifact identified by `artifact`. The response includes metadata 385 such as name, description, version, and a signed `file_url` for downloading 386 the current file version. Image artifacts also include an `image_source` object 387 with display-ready metadata. 388 The authenticated user must have read access to the artifact's owning team or 389 organization. Returns 404 if the artifact does not exist or is not accessible 390 to the caller. 391 392 Args: 393 artifact: Artifact ID (`art_...`) of the artifact to retrieve. 394 395 Returns: 396 The requested artifact, including its current version's file metadata and signed download URL. 397 """ 398 return self._http.request(f"/api/v1/artifacts/{artifact}", response_type=Artifact) 399 400 def replace(self, artifact: str, input: ArtifactReplaceInput) -> Artifact: 401 """ 402 Update an artifact 403 Updates the metadata and, optionally, the file content of an existing artifact. 404 This endpoint uses optimistic concurrency control: you must supply the artifact's 405 current `version` number as `from_version`. If another update has incremented the 406 version since you last fetched the artifact, the request returns 409. 407 To replace the artifact's file, include a nested `file` object with Base64 408 `data`, `filename`, and `mime_type`. Omitting `file` leaves the existing file 409 unchanged. The authenticated user or developer must have write access to the 410 artifact's owner. 411 412 Args: 413 artifact: Artifact ID (`art_...`) of the artifact to update. 414 input: Request body. 415 input.acl: Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. 416 input.description: New description for the artifact. Omit to leave the existing description unchanged. 417 input.file: Replacement file payload. Omit to leave the current file unchanged. 418 input.file_content: Legacy flat Base64 file content. Prefer `file.data`. 419 input.file_content_type: Legacy flat MIME type. Prefer `file.mime_type`. 420 input.file_name: Legacy flat filename. Prefer `file.filename`. 421 input.from_version: The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version. 422 input.group_key: Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates. 423 input.name: New display name for the artifact. Omit to leave the existing name unchanged. 424 425 Returns: 426 The artifact after applying the update, reflecting the new version number and any changed metadata or file. 427 """ 428 return self._http.request( 429 f"/api/v1/artifacts/{artifact}", 430 method="PUT", 431 body=input, 432 response_type=Artifact, 433 ) 434 435 def archive(self, artifact: str) -> None: 436 """ 437 Archive an artifact 438 Soft-deletes the artifact identified by `artifact`. The artifact record is 439 retained in storage but is no longer returned by the list or show endpoints. 440 The authenticated user must have write access to the artifact's owning team or 441 organization. Attempting to archive an artifact you do not own returns 403. 442 Attempting to archive an artifact that does not exist or is already archived 443 returns 404. 444 445 Args: 446 artifact: Artifact ID (`art_...`) of the artifact to archive. 447 448 Returns: 449 Returns 204 No Content on success. The artifact is soft-deleted and no longer accessible through the API. 450 """ 451 self._http.request(f"/api/v1/artifacts/{artifact}/archive", method="POST") 452 453 def content(self, artifact: str, *, version: int | None = None) -> dict[str, str]: 454 """ 455 Retrieve raw artifact file content 456 Returns the raw binary content of the file stored for the specified artifact. 457 The response `Content-Type` header reflects the artifact file's MIME type, so 458 you can pipe the response body directly to disk or display it in a browser. 459 By default the endpoint serves the artifact's current version. Pass the 460 `version` parameter to retrieve a specific historical version. The authenticated 461 user must have read access to the artifact's owning team or organization. 462 463 Args: 464 artifact: Artifact ID (`art_...`) of the artifact whose content to retrieve. 465 version: Version number to retrieve. Omit to return the artifact's current version. 466 467 Returns: 468 Raw binary content of the artifact file. The `Content-Type` header is set to the artifact's stored MIME type. 469 """ 470 query: dict[str, object] = {} 471 if version is not None: 472 query["version"] = version 473 return self._http.request_raw(f"/api/v1/artifacts/{artifact}/content", query=query)
321 def create(self, input: ArtifactCreateInput) -> Artifact: 322 """ 323 Create an artifact 324 Creates a new artifact and stores its file content. A file payload is required; 325 supply it via the `file.data` (Base64-encoded by default), `file.filename`, and 326 `file.mime_type` fields. The artifact is scoped to the owner resolved from the 327 request body either a team, a user, or an explicit system owner. When no 328 owner is supplied and the viewer is an authenticated user, the artifact 329 defaults to that user. 330 For company-readable snapshots, pass `system: true` and `org`. Organization 331 members can read these artifacts; organization admins and system viewers can 332 create them. Scripts may supply text directly using `file.encoding: "utf8"`. 333 Optionally associate the artifact with an existing thread or agent by passing 334 `thread` or `agent`. Legacy requests that wrap fields in an `artifact` object 335 are still accepted. 336 337 Args: 338 input: Request body. 339 input.acl: Initial access control list. Grants add read or write access beyond the owner. 340 input.agent: Agent ID (`agt_...`) to associate with the artifact. 341 input.artifact: Legacy wrapper object containing artifact attributes. Prefer top-level fields. 342 input.description: Optional longer artifact description. 343 input.file: File payload for the initial artifact version. 344 input.group_key: Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity. 345 input.idempotency_key: Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact. 346 input.name: Human-readable artifact name. 347 input.org: Organization owning a system artifact. Requires an organization admin or system viewer. 348 input.system: When true, create a system-owned artifact. Mutually exclusive with `team` and `user`. 349 input.team: Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`. 350 input.thread: Thread ID (`thr_...`) to associate with the artifact. 351 input.user: User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied. 352 353 Returns: 354 The newly created artifact. 355 """ 356 return self._http.request( 357 "/api/v1/artifacts", 358 method="POST", 359 body=input, 360 response_type=Artifact, 361 )
Create an artifact
Creates a new artifact and stores its file content. A file payload is required;
supply it via the file.data (Base64-encoded by default), file.filename, and
file.mime_type fields. The artifact is scoped to the owner resolved from the
request body either a team, a user, or an explicit system owner. When no
owner is supplied and the viewer is an authenticated user, the artifact
defaults to that user.
For company-readable snapshots, pass system: true and org. Organization
members can read these artifacts; organization admins and system viewers can
create them. Scripts may supply text directly using file.encoding: "utf8".
Optionally associate the artifact with an existing thread or agent by passing
thread or agent. Legacy requests that wrap fields in an artifact object
are still accepted.
Arguments:
- input: Request body.
- input.acl: Initial access control list. Grants add read or write access beyond the owner.
- input.agent: Agent ID (
agt_...) to associate with the artifact. - input.artifact: Legacy wrapper object containing artifact attributes. Prefer top-level fields.
- input.description: Optional longer artifact description.
- input.file: File payload for the initial artifact version.
- input.group_key: Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Artifact ID remains identity.
- input.idempotency_key: Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact.
- input.name: Human-readable artifact name.
- input.org: Organization owning a system artifact. Requires an organization admin or system viewer.
- input.system: When true, create a system-owned artifact. Mutually exclusive with
teamanduser. - input.team: Team ID (
tem_...) that should own the artifact. Mutually exclusive withuser. - input.thread: Thread ID (
thr_...) to associate with the artifact. - input.user: User ID (
usr_...) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied.
Returns:
The newly created artifact.
363 def delete(self, artifact: str) -> None: 364 """ 365 Delete an artifact 366 Permanently deletes the artifact and all associated file versions. This 367 operation is irreversible deleted artifacts and their file content cannot 368 be recovered. 369 The authenticated user must have write access to the artifact's owning team 370 or organization. Returns 404 if the artifact does not exist or is not 371 accessible to the caller. 372 373 Args: 374 artifact: Artifact ID (`art_...`) of the artifact to delete. 375 376 Returns: 377 Empty body. HTTP 204 indicates the artifact and all associated file versions were permanently deleted. 378 """ 379 self._http.request(f"/api/v1/artifacts/{artifact}", method="DELETE")
Delete an artifact Permanently deletes the artifact and all associated file versions. This operation is irreversible deleted artifacts and their file content cannot be recovered. The authenticated user must have write access to the artifact's owning team or organization. Returns 404 if the artifact does not exist or is not accessible to the caller.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact to delete.
Returns:
Empty body. HTTP 204 indicates the artifact and all associated file versions were permanently deleted.
381 def get(self, artifact: str) -> Artifact: 382 """ 383 Retrieve an artifact 384 Returns the artifact identified by `artifact`. The response includes metadata 385 such as name, description, version, and a signed `file_url` for downloading 386 the current file version. Image artifacts also include an `image_source` object 387 with display-ready metadata. 388 The authenticated user must have read access to the artifact's owning team or 389 organization. Returns 404 if the artifact does not exist or is not accessible 390 to the caller. 391 392 Args: 393 artifact: Artifact ID (`art_...`) of the artifact to retrieve. 394 395 Returns: 396 The requested artifact, including its current version's file metadata and signed download URL. 397 """ 398 return self._http.request(f"/api/v1/artifacts/{artifact}", response_type=Artifact)
Retrieve an artifact
Returns the artifact identified by artifact. The response includes metadata
such as name, description, version, and a signed file_url for downloading
the current file version. Image artifacts also include an image_source object
with display-ready metadata.
The authenticated user must have read access to the artifact's owning team or
organization. Returns 404 if the artifact does not exist or is not accessible
to the caller.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact to retrieve.
Returns:
The requested artifact, including its current version's file metadata and signed download URL.
400 def replace(self, artifact: str, input: ArtifactReplaceInput) -> Artifact: 401 """ 402 Update an artifact 403 Updates the metadata and, optionally, the file content of an existing artifact. 404 This endpoint uses optimistic concurrency control: you must supply the artifact's 405 current `version` number as `from_version`. If another update has incremented the 406 version since you last fetched the artifact, the request returns 409. 407 To replace the artifact's file, include a nested `file` object with Base64 408 `data`, `filename`, and `mime_type`. Omitting `file` leaves the existing file 409 unchanged. The authenticated user or developer must have write access to the 410 artifact's owner. 411 412 Args: 413 artifact: Artifact ID (`art_...`) of the artifact to update. 414 input: Request body. 415 input.acl: Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. 416 input.description: New description for the artifact. Omit to leave the existing description unchanged. 417 input.file: Replacement file payload. Omit to leave the current file unchanged. 418 input.file_content: Legacy flat Base64 file content. Prefer `file.data`. 419 input.file_content_type: Legacy flat MIME type. Prefer `file.mime_type`. 420 input.file_name: Legacy flat filename. Prefer `file.filename`. 421 input.from_version: The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version. 422 input.group_key: Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates. 423 input.name: New display name for the artifact. Omit to leave the existing name unchanged. 424 425 Returns: 426 The artifact after applying the update, reflecting the new version number and any changed metadata or file. 427 """ 428 return self._http.request( 429 f"/api/v1/artifacts/{artifact}", 430 method="PUT", 431 body=input, 432 response_type=Artifact, 433 )
Update an artifact
Updates the metadata and, optionally, the file content of an existing artifact.
This endpoint uses optimistic concurrency control: you must supply the artifact's
current version number as from_version. If another update has incremented the
version since you last fetched the artifact, the request returns 409.
To replace the artifact's file, include a nested file object with Base64
data, filename, and mime_type. Omitting file leaves the existing file
unchanged. The authenticated user or developer must have write access to the
artifact's owner.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact to update. - input: Request body.
- input.acl: Access control list replacement (
grants) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. - input.description: New description for the artifact. Omit to leave the existing description unchanged.
- input.file: Replacement file payload. Omit to leave the current file unchanged.
- input.file_content: Legacy flat Base64 file content. Prefer
file.data. - input.file_content_type: Legacy flat MIME type. Prefer
file.mime_type. - input.file_name: Legacy flat filename. Prefer
file.filename. - input.from_version: The artifact's current version number, used for optimistic concurrency control. Returns 409 if this value does not match the server's current version.
- input.group_key: Nonunique grouping key, limited to 1024 UTF-8 bytes. Omit to preserve; null clears. Grouping-only updates do not increment the content version and from_version does not protect against concurrent metadata updates.
- input.name: New display name for the artifact. Omit to leave the existing name unchanged.
Returns:
The artifact after applying the update, reflecting the new version number and any changed metadata or file.
435 def archive(self, artifact: str) -> None: 436 """ 437 Archive an artifact 438 Soft-deletes the artifact identified by `artifact`. The artifact record is 439 retained in storage but is no longer returned by the list or show endpoints. 440 The authenticated user must have write access to the artifact's owning team or 441 organization. Attempting to archive an artifact you do not own returns 403. 442 Attempting to archive an artifact that does not exist or is already archived 443 returns 404. 444 445 Args: 446 artifact: Artifact ID (`art_...`) of the artifact to archive. 447 448 Returns: 449 Returns 204 No Content on success. The artifact is soft-deleted and no longer accessible through the API. 450 """ 451 self._http.request(f"/api/v1/artifacts/{artifact}/archive", method="POST")
Archive an artifact
Soft-deletes the artifact identified by artifact. The artifact record is
retained in storage but is no longer returned by the list or show endpoints.
The authenticated user must have write access to the artifact's owning team or
organization. Attempting to archive an artifact you do not own returns 403.
Attempting to archive an artifact that does not exist or is already archived
returns 404.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact to archive.
Returns:
Returns 204 No Content on success. The artifact is soft-deleted and no longer accessible through the API.
453 def content(self, artifact: str, *, version: int | None = None) -> dict[str, str]: 454 """ 455 Retrieve raw artifact file content 456 Returns the raw binary content of the file stored for the specified artifact. 457 The response `Content-Type` header reflects the artifact file's MIME type, so 458 you can pipe the response body directly to disk or display it in a browser. 459 By default the endpoint serves the artifact's current version. Pass the 460 `version` parameter to retrieve a specific historical version. The authenticated 461 user must have read access to the artifact's owning team or organization. 462 463 Args: 464 artifact: Artifact ID (`art_...`) of the artifact whose content to retrieve. 465 version: Version number to retrieve. Omit to return the artifact's current version. 466 467 Returns: 468 Raw binary content of the artifact file. The `Content-Type` header is set to the artifact's stored MIME type. 469 """ 470 query: dict[str, object] = {} 471 if version is not None: 472 query["version"] = version 473 return self._http.request_raw(f"/api/v1/artifacts/{artifact}/content", query=query)
Retrieve raw artifact file content
Returns the raw binary content of the file stored for the specified artifact.
The response Content-Type header reflects the artifact file's MIME type, so
you can pipe the response body directly to disk or display it in a browser.
By default the endpoint serves the artifact's current version. Pass the
version parameter to retrieve a specific historical version. The authenticated
user must have read access to the artifact's owning team or organization.
Arguments:
- artifact: Artifact ID (
art_...) of the artifact whose content to retrieve. - version: Version number to retrieve. Omit to return the artifact's current version.
Returns:
Raw binary content of the artifact file. The
Content-Typeheader is set to the artifact's stored MIME type.