archastro.platform.v1.resources.slack_channel_bindings
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: 739c91726193 4 5from __future__ import annotations 6 7import builtins 8from typing import Any, Literal, Required, TypedDict 9 10from pydantic import BaseModel, Field 11 12from ...runtime.http_client import HttpClient, SyncHttpClient 13from ...types.common import ( 14 SlackChannelBinding, 15 SlackChannelBindingListResponse, 16 SlackDeliveryOutcomeListResponse, 17) 18 19 20class SlackChannelBindingCreateInput(TypedDict, total=False): 21 "Create or update a Slack channel binding" 22 23 agent_user_ids: Required[list[str]] 24 "List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents." 25 allow_bot_conversations: bool | None 26 "Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged." 27 channel_id: Required[str] 28 "Slack channel ID to bind (e.g. `C01234ABCDE`). Acts as the natural key of the binding within the workspace." 29 customer_label: str | None 30 "Human-readable label for the customer associated with this channel. Stored in the binding's config. `null` if omitted." 31 is_ext_shared_cached: bool | None 32 "Cached value of Slack's `is_ext_shared` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. `null` if omitted." 33 is_private_cached: bool | None 34 "Cached value of Slack's `is_private` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. `null` if omitted." 35 slack_team_id: Required[str] 36 "Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use." 37 team_id: Required[str] 38 "ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team." 39 40 41class SlackChannelBindingProvisionInput(TypedDict, total=False): 42 "Start adding a customer over Slack Connect" 43 44 channel_name: str | None 45 "Name for a Slack channel to create for this customer. Required unless `existing_channel_id` is given. The channel is created private." 46 customer_email: str | None 47 "Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty." 48 customer_key: Required[str] 49 "The vendor's own primary key for this customer (`customer_id` / `account_id` / `tenant_id`). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning." 50 customer_label: Required[str] 51 "Human-readable name for the customer (e.g. `Acme, Inc.`). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input." 52 existing_channel_id: str | None 53 "Adopt this already-shared Slack Connect channel (e.g. `C01234ABCDE`) instead of creating one. Mutually exclusive with `channel_name`." 54 inputs: dict[str, Any] | None 55 "String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map." 56 slack_team_id: Required[str] 57 "Slack workspace team ID of the vendor's own Slack installation (e.g. `T01234ABCDE`). The customer's workspace is not known yet it resolves from whoever accepts." 58 template_config_id: Required[str] 59 "Config ID (`cfg_ `) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet." 60 61 62class SlackChannelBindingDepositThreadInput(TypedDict, total=False): 63 "Point a Slack channel's deposit pipe at a staging thread, or turn it off" 64 65 slack_team_id: Required[str] 66 "Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use." 67 thread_id: str | None 68 "Staging thread ID (primary key, `thr_ `) deposits should flow into. Pass `null` to turn the pipe off." 69 70 71class SlackChannelBindingDeleteResponse(BaseModel): 72 """ 73 Successful response 74 """ 75 76 channel: str = Field(..., description="Slack channel ID of the binding that was deleted.") 77 deleted: bool = Field( 78 ..., description="Always `true` when the binding was successfully removed." 79 ) 80 81 82class AsyncSlackChannelBindingResource: 83 def __init__(self, http: HttpClient): 84 self._http = http 85 86 async def list( 87 self, 88 *, 89 integration: builtins.list[str] | None = None, 90 team: builtins.list[str] | None = None, 91 agent: builtins.list[str] | None = None, 92 org: builtins.list[str] | None = None, 93 page: int | None = None, 94 per_page: int | None = None, 95 ) -> SlackChannelBindingListResponse: 96 """ 97 List Slack channel bindings 98 Returns a page of Slack channel bindings visible to the authenticated user. 99 Results can be filtered by integration, team, agent, or organization. Omit all 100 filter params to retrieve every binding the caller can see. 101 Pagination is page-based. Pass `page` and `per_page` to navigate large result 102 sets. `page` must be a positive integer; `per_page` must be between 1 and 100. 103 Invalid values return 400. 104 105 Args: 106 integration: Return only bindings whose Slack integration matches one of these integration IDs. Omit to return bindings across all integrations. 107 team: Return only bindings bound to one of these team IDs. Omit to return bindings for all teams. 108 agent: Return only bindings that have at least one of these agent user IDs attached. Omit to return bindings regardless of agent attachment. 109 org: Return only bindings that belong to one of these organization IDs. Omit to return bindings across all organizations visible to the caller. 110 page: Page number to retrieve, 1-indexed. Defaults to 1. Must be a positive integer. 111 per_page: Number of bindings to return per page. Defaults to 25; maximum is 100. 112 113 Returns: 114 Paginated list of Slack channel bindings visible to the caller. 115 """ 116 query: dict[str, object] = {} 117 if integration is not None: 118 query["integration"] = integration 119 if team is not None: 120 query["team"] = team 121 if agent is not None: 122 query["agent"] = agent 123 if org is not None: 124 query["org"] = org 125 if page is not None: 126 query["page"] = page 127 if per_page is not None: 128 query["per_page"] = per_page 129 return await self._http.request( 130 "/api/v1/slack_channel_bindings", 131 query=query, 132 response_type=SlackChannelBindingListResponse, 133 ) 134 135 async def create(self, input: SlackChannelBindingCreateInput) -> SlackChannelBinding: 136 """ 137 Create or update a Slack channel binding 138 Creates a new binding between a Slack channel and a team, or updates the 139 existing binding if one already exists for the given channel. The caller also 140 supplies a list of agents to attach to the binding and enroll as members of the 141 destination team. 142 The caller must have team-manage rights on the destination team (and on the 143 currently bound team if the channel is being re-pointed). Returns 403 if 144 permission is insufficient. All write steps are idempotent, so retrying after 145 a partial failure is safe. 146 On success the REST endpoint returns 201 Created. The script binding 147 (`slack.channel_bindings.upsert`) returns the full binding object including the 148 attached agents. 149 150 Args: 151 input: Request body. 152 input.agent_user_ids: List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents. 153 input.allow_bot_conversations: Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged. 154 input.channel_id: Slack channel ID to bind (e.g. `C01234ABCDE`). Acts as the natural key of the binding within the workspace. 155 input.customer_label: Human-readable label for the customer associated with this channel. Stored in the binding's config. `null` if omitted. 156 input.is_ext_shared_cached: Cached value of Slack's `is_ext_shared` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. `null` if omitted. 157 input.is_private_cached: Cached value of Slack's `is_private` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. `null` if omitted. 158 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 159 input.team_id: ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team. 160 161 Returns: 162 The created or updated Slack channel binding, including the full list of currently attached agents. 163 """ 164 return await self._http.request( 165 "/api/v1/slack_channel_bindings", 166 method="POST", 167 body=input, 168 response_type=SlackChannelBinding, 169 ) 170 171 async def provision(self, input: SlackChannelBindingProvisionInput) -> SlackChannelBinding: 172 """ 173 Start adding a customer over Slack Connect 174 Opens a Slack Connect channel with a new customer creating one and sending 175 the invite, or adopting a shared channel you already have and records who is 176 adding whom so the addition can finish once the customer accepts. 177 The returned binding is **pending**: nothing mirrors, and no per-customer Team, 178 agent, or solution instance exists yet. Acceptance is asynchronous and may 179 never come. When it does, the addition completes in the background under the 180 identity of the admin who called this endpoint, re-checked live at that moment. 181 A caller who has since lost their admin role does not get a substitute the 182 addition is refused and a human re-adds the customer. 183 The caller must be an admin of the Slack integration's own organization. This 184 is the same authority the completion demands, checked here so a customer is 185 never invited into a channel whose addition can never finish. 186 Deliberately not exposed as a script binding: this sends mail to a person 187 outside the org, so it stays a vendor-admin HTTP surface. 188 189 Args: 190 input: Request body. 191 input.channel_name: Name for a Slack channel to create for this customer. Required unless `existing_channel_id` is given. The channel is created private. 192 input.customer_email: Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty. 193 input.customer_key: The vendor's own primary key for this customer (`customer_id` / `account_id` / `tenant_id`). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning. 194 input.customer_label: Human-readable name for the customer (e.g. `Acme, Inc.`). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input. 195 input.existing_channel_id: Adopt this already-shared Slack Connect channel (e.g. `C01234ABCDE`) instead of creating one. Mutually exclusive with `channel_name`. 196 input.inputs: String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map. 197 input.slack_team_id: Slack workspace team ID of the vendor's own Slack installation (e.g. `T01234ABCDE`). The customer's workspace is not known yet it resolves from whoever accepts. 198 input.template_config_id: Config ID (`cfg_ `) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet. 199 200 Returns: 201 The pending binding for the customer's channel. `disclosure_state` is `pending` until the customer accepts, and `scope_key` is null until the addition finishes. 202 """ 203 return await self._http.request( 204 "/api/v1/slack_channel_bindings/provision", 205 method="POST", 206 body=input, 207 response_type=SlackChannelBinding, 208 ) 209 210 async def delete(self, channel: str) -> SlackChannelBindingDeleteResponse: 211 """ 212 Delete a Slack channel binding 213 Removes the binding between a Slack channel and its associated team. The 214 channel is identified by its Slack channel ID together with the `slack_team_id` 215 that scopes it to a specific Slack workspace. Removing the binding does not 216 delete the bound team or any conversation threads scoped to it; decommission 217 those resources separately if required. 218 The caller must have team-manage rights on the team the channel is currently 219 bound to. Returning 403 indicates insufficient permission; returning 404 220 indicates the binding does not exist or is not visible to the caller. 221 The REST endpoint returns 204 No Content on success. The script binding 222 (`slack.channel_bindings.delete`) returns a confirmation object so script 223 callers can verify success without an additional fetch. Both paths are 224 idempotent retrying after a partial failure is safe. 225 226 Args: 227 channel: Slack channel ID of the binding to delete (e.g. `C01234ABCDE`). 228 229 Returns: 230 Successful response 231 """ 232 return await self._http.request( 233 f"/api/v1/slack_channel_bindings/{channel}", 234 method="DELETE", 235 response_type=SlackChannelBindingDeleteResponse, 236 ) 237 238 async def get(self, channel: str, slack_team_id: str) -> SlackChannelBinding: 239 """ 240 Retrieve a Slack channel binding 241 Returns the Slack channel binding identified by a Slack channel ID and workspace 242 team ID pair. Use this endpoint to look up the team and agents currently bound 243 to a specific Slack channel. 244 The `channel` path parameter is the Slack channel ID; `slack_team_id` identifies 245 the Slack workspace the channel belongs to, disambiguating channels with the same 246 ID across workspaces. Both parameters are required. Returns 404 if no binding 247 exists for the given pair or the associated Slack integration is not visible to 248 the caller. 249 250 Args: 251 channel: Slack channel ID of the binding to retrieve (e.g. `C01234ABCDE`). 252 slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Used together with `channel` to uniquely identify the binding. 253 254 Returns: 255 The Slack channel binding for the given channel and workspace. 256 """ 257 query: dict[str, object] = {} 258 query["slack_team_id"] = slack_team_id 259 return await self._http.request( 260 f"/api/v1/slack_channel_bindings/{channel}", 261 query=query, 262 response_type=SlackChannelBinding, 263 ) 264 265 async def delivery_outcomes( 266 self, 267 channel: str, 268 *, 269 since: str | None = None, 270 outcome: Literal["delivered", "floored", "judge_refused", "failed"] | None = None, 271 limit: int | None = None, 272 before_cursor: str | None = None, 273 after_cursor: str | None = None, 274 ) -> SlackDeliveryOutcomeListResponse: 275 """ 276 List delivery outcomes for a Slack channel 277 Returns what happened to each agent message this platform sent to a Slack 278 channel, newest attempt first. 279 A message that never appears in a Slack channel has several possible causes 280 that look identical from the channel itself: a content guard withheld it, the 281 cross-org judge refused it, Slack rejected the call, or nobody asked anything. 282 This endpoint tells them apart. Use it to confirm a reply was delivered, or to 283 find out why one never arrived, without reading the channel's mirrored 284 conversation. 285 Outcomes cover **outbound agent messages only**. They carry no message 286 content, no author, and nothing about inbound messages. Access follows the 287 channel's binding the organization and app the channel is bound to and 288 needs no membership in the mirrored thread. 289 Paginated with opaque cursors, newest first. When `has_more` is true, pass the 290 response's `before_cursor` back as `before_cursor` to continue into older 291 history. `since` and `outcome` narrow the result set; they are filters, not 292 paging controls. 293 294 Args: 295 channel: Slack channel ID to read delivery outcomes for (e.g. `C01234ABCDE`). 296 since: Only return attempts at or after this ISO 8601 timestamp (e.g. `2026-08-11T00:00:00Z`). Omit to return the most recent attempts regardless of age. 297 outcome: Return only attempts with this outcome. Omit to return every outcome. Use `floored` and `judge_refused` to see only what was withheld. 298 limit: Maximum number of outcomes to return. Defaults to 50; maximum is 200. 299 before_cursor: Opaque cursor from a previous response; returns outcomes older than it. Cursors are not parseable and are only valid against this endpoint. 300 after_cursor: Opaque cursor from a previous response; returns outcomes newer than it. Suited to a UI loading newer entries. To poll for everything recorded since a point in time, prefer `since` with a little overlap and de-duplicate on `id` `after_cursor` can miss an attempt recorded in the same millisecond as the cursor's own row. 301 302 Returns: 303 Delivery outcomes for the requested channel, newest first. 304 """ 305 query: dict[str, object] = {} 306 if since is not None: 307 query["since"] = since 308 if outcome is not None: 309 query["outcome"] = outcome 310 if limit is not None: 311 query["limit"] = limit 312 if before_cursor is not None: 313 query["before_cursor"] = before_cursor 314 if after_cursor is not None: 315 query["after_cursor"] = after_cursor 316 return await self._http.request( 317 f"/api/v1/slack_channel_bindings/{channel}/delivery_outcomes", 318 query=query, 319 response_type=SlackDeliveryOutcomeListResponse, 320 ) 321 322 async def deposit_thread( 323 self, channel: str, input: SlackChannelBindingDepositThreadInput 324 ) -> SlackChannelBinding: 325 """ 326 Point a Slack channel's deposit pipe at a staging thread, or turn it off 327 Sets the binding's deposit target the internal staging thread the 328 deposit pipe copies this channel's mirror content into. Pass a `null` 329 `thread_id` to turn the pipe off. 330 The target is validated server-side: it must exist, belong to the 331 binding's app and org, and never be a Slack mirror thread. Customer 332 bindings (bound `team_id`) additionally require a team-owned private 333 thread with no participant list, so the staging read ACL stays governed 334 by the channel-membership projection. Re-pointing or clearing an 335 existing target purges the old thread's deposit entries. 336 337 Args: 338 channel: Slack channel ID whose binding is being configured (e.g. `C01234ABCDE`). 339 input: Request body. 340 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 341 input.thread_id: Staging thread ID (primary key, `thr_ `) deposits should flow into. Pass `null` to turn the pipe off. 342 343 Returns: 344 The binding with the updated deposit config. 345 """ 346 return await self._http.request( 347 f"/api/v1/slack_channel_bindings/{channel}/deposit_thread", 348 method="POST", 349 body=input, 350 response_type=SlackChannelBinding, 351 ) 352 353 354class SlackChannelBindingResource: 355 def __init__(self, http: SyncHttpClient): 356 self._http = http 357 358 def list( 359 self, 360 *, 361 integration: builtins.list[str] | None = None, 362 team: builtins.list[str] | None = None, 363 agent: builtins.list[str] | None = None, 364 org: builtins.list[str] | None = None, 365 page: int | None = None, 366 per_page: int | None = None, 367 ) -> SlackChannelBindingListResponse: 368 """ 369 List Slack channel bindings 370 Returns a page of Slack channel bindings visible to the authenticated user. 371 Results can be filtered by integration, team, agent, or organization. Omit all 372 filter params to retrieve every binding the caller can see. 373 Pagination is page-based. Pass `page` and `per_page` to navigate large result 374 sets. `page` must be a positive integer; `per_page` must be between 1 and 100. 375 Invalid values return 400. 376 377 Args: 378 integration: Return only bindings whose Slack integration matches one of these integration IDs. Omit to return bindings across all integrations. 379 team: Return only bindings bound to one of these team IDs. Omit to return bindings for all teams. 380 agent: Return only bindings that have at least one of these agent user IDs attached. Omit to return bindings regardless of agent attachment. 381 org: Return only bindings that belong to one of these organization IDs. Omit to return bindings across all organizations visible to the caller. 382 page: Page number to retrieve, 1-indexed. Defaults to 1. Must be a positive integer. 383 per_page: Number of bindings to return per page. Defaults to 25; maximum is 100. 384 385 Returns: 386 Paginated list of Slack channel bindings visible to the caller. 387 """ 388 query: dict[str, object] = {} 389 if integration is not None: 390 query["integration"] = integration 391 if team is not None: 392 query["team"] = team 393 if agent is not None: 394 query["agent"] = agent 395 if org is not None: 396 query["org"] = org 397 if page is not None: 398 query["page"] = page 399 if per_page is not None: 400 query["per_page"] = per_page 401 return self._http.request( 402 "/api/v1/slack_channel_bindings", 403 query=query, 404 response_type=SlackChannelBindingListResponse, 405 ) 406 407 def create(self, input: SlackChannelBindingCreateInput) -> SlackChannelBinding: 408 """ 409 Create or update a Slack channel binding 410 Creates a new binding between a Slack channel and a team, or updates the 411 existing binding if one already exists for the given channel. The caller also 412 supplies a list of agents to attach to the binding and enroll as members of the 413 destination team. 414 The caller must have team-manage rights on the destination team (and on the 415 currently bound team if the channel is being re-pointed). Returns 403 if 416 permission is insufficient. All write steps are idempotent, so retrying after 417 a partial failure is safe. 418 On success the REST endpoint returns 201 Created. The script binding 419 (`slack.channel_bindings.upsert`) returns the full binding object including the 420 attached agents. 421 422 Args: 423 input: Request body. 424 input.agent_user_ids: List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents. 425 input.allow_bot_conversations: Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged. 426 input.channel_id: Slack channel ID to bind (e.g. `C01234ABCDE`). Acts as the natural key of the binding within the workspace. 427 input.customer_label: Human-readable label for the customer associated with this channel. Stored in the binding's config. `null` if omitted. 428 input.is_ext_shared_cached: Cached value of Slack's `is_ext_shared` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. `null` if omitted. 429 input.is_private_cached: Cached value of Slack's `is_private` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. `null` if omitted. 430 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 431 input.team_id: ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team. 432 433 Returns: 434 The created or updated Slack channel binding, including the full list of currently attached agents. 435 """ 436 return self._http.request( 437 "/api/v1/slack_channel_bindings", 438 method="POST", 439 body=input, 440 response_type=SlackChannelBinding, 441 ) 442 443 def provision(self, input: SlackChannelBindingProvisionInput) -> SlackChannelBinding: 444 """ 445 Start adding a customer over Slack Connect 446 Opens a Slack Connect channel with a new customer creating one and sending 447 the invite, or adopting a shared channel you already have and records who is 448 adding whom so the addition can finish once the customer accepts. 449 The returned binding is **pending**: nothing mirrors, and no per-customer Team, 450 agent, or solution instance exists yet. Acceptance is asynchronous and may 451 never come. When it does, the addition completes in the background under the 452 identity of the admin who called this endpoint, re-checked live at that moment. 453 A caller who has since lost their admin role does not get a substitute the 454 addition is refused and a human re-adds the customer. 455 The caller must be an admin of the Slack integration's own organization. This 456 is the same authority the completion demands, checked here so a customer is 457 never invited into a channel whose addition can never finish. 458 Deliberately not exposed as a script binding: this sends mail to a person 459 outside the org, so it stays a vendor-admin HTTP surface. 460 461 Args: 462 input: Request body. 463 input.channel_name: Name for a Slack channel to create for this customer. Required unless `existing_channel_id` is given. The channel is created private. 464 input.customer_email: Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty. 465 input.customer_key: The vendor's own primary key for this customer (`customer_id` / `account_id` / `tenant_id`). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning. 466 input.customer_label: Human-readable name for the customer (e.g. `Acme, Inc.`). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input. 467 input.existing_channel_id: Adopt this already-shared Slack Connect channel (e.g. `C01234ABCDE`) instead of creating one. Mutually exclusive with `channel_name`. 468 input.inputs: String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map. 469 input.slack_team_id: Slack workspace team ID of the vendor's own Slack installation (e.g. `T01234ABCDE`). The customer's workspace is not known yet it resolves from whoever accepts. 470 input.template_config_id: Config ID (`cfg_ `) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet. 471 472 Returns: 473 The pending binding for the customer's channel. `disclosure_state` is `pending` until the customer accepts, and `scope_key` is null until the addition finishes. 474 """ 475 return self._http.request( 476 "/api/v1/slack_channel_bindings/provision", 477 method="POST", 478 body=input, 479 response_type=SlackChannelBinding, 480 ) 481 482 def delete(self, channel: str) -> SlackChannelBindingDeleteResponse: 483 """ 484 Delete a Slack channel binding 485 Removes the binding between a Slack channel and its associated team. The 486 channel is identified by its Slack channel ID together with the `slack_team_id` 487 that scopes it to a specific Slack workspace. Removing the binding does not 488 delete the bound team or any conversation threads scoped to it; decommission 489 those resources separately if required. 490 The caller must have team-manage rights on the team the channel is currently 491 bound to. Returning 403 indicates insufficient permission; returning 404 492 indicates the binding does not exist or is not visible to the caller. 493 The REST endpoint returns 204 No Content on success. The script binding 494 (`slack.channel_bindings.delete`) returns a confirmation object so script 495 callers can verify success without an additional fetch. Both paths are 496 idempotent retrying after a partial failure is safe. 497 498 Args: 499 channel: Slack channel ID of the binding to delete (e.g. `C01234ABCDE`). 500 501 Returns: 502 Successful response 503 """ 504 return self._http.request( 505 f"/api/v1/slack_channel_bindings/{channel}", 506 method="DELETE", 507 response_type=SlackChannelBindingDeleteResponse, 508 ) 509 510 def get(self, channel: str, slack_team_id: str) -> SlackChannelBinding: 511 """ 512 Retrieve a Slack channel binding 513 Returns the Slack channel binding identified by a Slack channel ID and workspace 514 team ID pair. Use this endpoint to look up the team and agents currently bound 515 to a specific Slack channel. 516 The `channel` path parameter is the Slack channel ID; `slack_team_id` identifies 517 the Slack workspace the channel belongs to, disambiguating channels with the same 518 ID across workspaces. Both parameters are required. Returns 404 if no binding 519 exists for the given pair or the associated Slack integration is not visible to 520 the caller. 521 522 Args: 523 channel: Slack channel ID of the binding to retrieve (e.g. `C01234ABCDE`). 524 slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Used together with `channel` to uniquely identify the binding. 525 526 Returns: 527 The Slack channel binding for the given channel and workspace. 528 """ 529 query: dict[str, object] = {} 530 query["slack_team_id"] = slack_team_id 531 return self._http.request( 532 f"/api/v1/slack_channel_bindings/{channel}", 533 query=query, 534 response_type=SlackChannelBinding, 535 ) 536 537 def delivery_outcomes( 538 self, 539 channel: str, 540 *, 541 since: str | None = None, 542 outcome: Literal["delivered", "floored", "judge_refused", "failed"] | None = None, 543 limit: int | None = None, 544 before_cursor: str | None = None, 545 after_cursor: str | None = None, 546 ) -> SlackDeliveryOutcomeListResponse: 547 """ 548 List delivery outcomes for a Slack channel 549 Returns what happened to each agent message this platform sent to a Slack 550 channel, newest attempt first. 551 A message that never appears in a Slack channel has several possible causes 552 that look identical from the channel itself: a content guard withheld it, the 553 cross-org judge refused it, Slack rejected the call, or nobody asked anything. 554 This endpoint tells them apart. Use it to confirm a reply was delivered, or to 555 find out why one never arrived, without reading the channel's mirrored 556 conversation. 557 Outcomes cover **outbound agent messages only**. They carry no message 558 content, no author, and nothing about inbound messages. Access follows the 559 channel's binding the organization and app the channel is bound to and 560 needs no membership in the mirrored thread. 561 Paginated with opaque cursors, newest first. When `has_more` is true, pass the 562 response's `before_cursor` back as `before_cursor` to continue into older 563 history. `since` and `outcome` narrow the result set; they are filters, not 564 paging controls. 565 566 Args: 567 channel: Slack channel ID to read delivery outcomes for (e.g. `C01234ABCDE`). 568 since: Only return attempts at or after this ISO 8601 timestamp (e.g. `2026-08-11T00:00:00Z`). Omit to return the most recent attempts regardless of age. 569 outcome: Return only attempts with this outcome. Omit to return every outcome. Use `floored` and `judge_refused` to see only what was withheld. 570 limit: Maximum number of outcomes to return. Defaults to 50; maximum is 200. 571 before_cursor: Opaque cursor from a previous response; returns outcomes older than it. Cursors are not parseable and are only valid against this endpoint. 572 after_cursor: Opaque cursor from a previous response; returns outcomes newer than it. Suited to a UI loading newer entries. To poll for everything recorded since a point in time, prefer `since` with a little overlap and de-duplicate on `id` `after_cursor` can miss an attempt recorded in the same millisecond as the cursor's own row. 573 574 Returns: 575 Delivery outcomes for the requested channel, newest first. 576 """ 577 query: dict[str, object] = {} 578 if since is not None: 579 query["since"] = since 580 if outcome is not None: 581 query["outcome"] = outcome 582 if limit is not None: 583 query["limit"] = limit 584 if before_cursor is not None: 585 query["before_cursor"] = before_cursor 586 if after_cursor is not None: 587 query["after_cursor"] = after_cursor 588 return self._http.request( 589 f"/api/v1/slack_channel_bindings/{channel}/delivery_outcomes", 590 query=query, 591 response_type=SlackDeliveryOutcomeListResponse, 592 ) 593 594 def deposit_thread( 595 self, channel: str, input: SlackChannelBindingDepositThreadInput 596 ) -> SlackChannelBinding: 597 """ 598 Point a Slack channel's deposit pipe at a staging thread, or turn it off 599 Sets the binding's deposit target the internal staging thread the 600 deposit pipe copies this channel's mirror content into. Pass a `null` 601 `thread_id` to turn the pipe off. 602 The target is validated server-side: it must exist, belong to the 603 binding's app and org, and never be a Slack mirror thread. Customer 604 bindings (bound `team_id`) additionally require a team-owned private 605 thread with no participant list, so the staging read ACL stays governed 606 by the channel-membership projection. Re-pointing or clearing an 607 existing target purges the old thread's deposit entries. 608 609 Args: 610 channel: Slack channel ID whose binding is being configured (e.g. `C01234ABCDE`). 611 input: Request body. 612 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 613 input.thread_id: Staging thread ID (primary key, `thr_ `) deposits should flow into. Pass `null` to turn the pipe off. 614 615 Returns: 616 The binding with the updated deposit config. 617 """ 618 return self._http.request( 619 f"/api/v1/slack_channel_bindings/{channel}/deposit_thread", 620 method="POST", 621 body=input, 622 response_type=SlackChannelBinding, 623 )
21class SlackChannelBindingCreateInput(TypedDict, total=False): 22 "Create or update a Slack channel binding" 23 24 agent_user_ids: Required[list[str]] 25 "List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents." 26 allow_bot_conversations: bool | None 27 "Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged." 28 channel_id: Required[str] 29 "Slack channel ID to bind (e.g. `C01234ABCDE`). Acts as the natural key of the binding within the workspace." 30 customer_label: str | None 31 "Human-readable label for the customer associated with this channel. Stored in the binding's config. `null` if omitted." 32 is_ext_shared_cached: bool | None 33 "Cached value of Slack's `is_ext_shared` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. `null` if omitted." 34 is_private_cached: bool | None 35 "Cached value of Slack's `is_private` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. `null` if omitted." 36 slack_team_id: Required[str] 37 "Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use." 38 team_id: Required[str] 39 "ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team."
Create or update a Slack channel binding
List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents.
Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged.
Slack channel ID to bind (e.g. C01234ABCDE). Acts as the natural key of the binding within the workspace.
Human-readable label for the customer associated with this channel. Stored in the binding's config. null if omitted.
Cached value of Slack's is_private flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. null if omitted.
42class SlackChannelBindingProvisionInput(TypedDict, total=False): 43 "Start adding a customer over Slack Connect" 44 45 channel_name: str | None 46 "Name for a Slack channel to create for this customer. Required unless `existing_channel_id` is given. The channel is created private." 47 customer_email: str | None 48 "Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty." 49 customer_key: Required[str] 50 "The vendor's own primary key for this customer (`customer_id` / `account_id` / `tenant_id`). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning." 51 customer_label: Required[str] 52 "Human-readable name for the customer (e.g. `Acme, Inc.`). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input." 53 existing_channel_id: str | None 54 "Adopt this already-shared Slack Connect channel (e.g. `C01234ABCDE`) instead of creating one. Mutually exclusive with `channel_name`." 55 inputs: dict[str, Any] | None 56 "String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map." 57 slack_team_id: Required[str] 58 "Slack workspace team ID of the vendor's own Slack installation (e.g. `T01234ABCDE`). The customer's workspace is not known yet it resolves from whoever accepts." 59 template_config_id: Required[str] 60 "Config ID (`cfg_ `) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet."
Start adding a customer over Slack Connect
Name for a Slack channel to create for this customer. Required unless existing_channel_id is given. The channel is created private.
Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty.
The vendor's own primary key for this customer (customer_id / account_id / tenant_id). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning.
Human-readable name for the customer (e.g. Acme, Inc.). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input.
Adopt this already-shared Slack Connect channel (e.g. C01234ABCDE) instead of creating one. Mutually exclusive with channel_name.
String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map.
63class SlackChannelBindingDepositThreadInput(TypedDict, total=False): 64 "Point a Slack channel's deposit pipe at a staging thread, or turn it off" 65 66 slack_team_id: Required[str] 67 "Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use." 68 thread_id: str | None 69 "Staging thread ID (primary key, `thr_ `) deposits should flow into. Pass `null` to turn the pipe off."
Point a Slack channel's deposit pipe at a staging thread, or turn it off
72class SlackChannelBindingDeleteResponse(BaseModel): 73 """ 74 Successful response 75 """ 76 77 channel: str = Field(..., description="Slack channel ID of the binding that was deleted.") 78 deleted: bool = Field( 79 ..., description="Always `true` when the binding was successfully removed." 80 )
Successful response
83class AsyncSlackChannelBindingResource: 84 def __init__(self, http: HttpClient): 85 self._http = http 86 87 async def list( 88 self, 89 *, 90 integration: builtins.list[str] | None = None, 91 team: builtins.list[str] | None = None, 92 agent: builtins.list[str] | None = None, 93 org: builtins.list[str] | None = None, 94 page: int | None = None, 95 per_page: int | None = None, 96 ) -> SlackChannelBindingListResponse: 97 """ 98 List Slack channel bindings 99 Returns a page of Slack channel bindings visible to the authenticated user. 100 Results can be filtered by integration, team, agent, or organization. Omit all 101 filter params to retrieve every binding the caller can see. 102 Pagination is page-based. Pass `page` and `per_page` to navigate large result 103 sets. `page` must be a positive integer; `per_page` must be between 1 and 100. 104 Invalid values return 400. 105 106 Args: 107 integration: Return only bindings whose Slack integration matches one of these integration IDs. Omit to return bindings across all integrations. 108 team: Return only bindings bound to one of these team IDs. Omit to return bindings for all teams. 109 agent: Return only bindings that have at least one of these agent user IDs attached. Omit to return bindings regardless of agent attachment. 110 org: Return only bindings that belong to one of these organization IDs. Omit to return bindings across all organizations visible to the caller. 111 page: Page number to retrieve, 1-indexed. Defaults to 1. Must be a positive integer. 112 per_page: Number of bindings to return per page. Defaults to 25; maximum is 100. 113 114 Returns: 115 Paginated list of Slack channel bindings visible to the caller. 116 """ 117 query: dict[str, object] = {} 118 if integration is not None: 119 query["integration"] = integration 120 if team is not None: 121 query["team"] = team 122 if agent is not None: 123 query["agent"] = agent 124 if org is not None: 125 query["org"] = org 126 if page is not None: 127 query["page"] = page 128 if per_page is not None: 129 query["per_page"] = per_page 130 return await self._http.request( 131 "/api/v1/slack_channel_bindings", 132 query=query, 133 response_type=SlackChannelBindingListResponse, 134 ) 135 136 async def create(self, input: SlackChannelBindingCreateInput) -> SlackChannelBinding: 137 """ 138 Create or update a Slack channel binding 139 Creates a new binding between a Slack channel and a team, or updates the 140 existing binding if one already exists for the given channel. The caller also 141 supplies a list of agents to attach to the binding and enroll as members of the 142 destination team. 143 The caller must have team-manage rights on the destination team (and on the 144 currently bound team if the channel is being re-pointed). Returns 403 if 145 permission is insufficient. All write steps are idempotent, so retrying after 146 a partial failure is safe. 147 On success the REST endpoint returns 201 Created. The script binding 148 (`slack.channel_bindings.upsert`) returns the full binding object including the 149 attached agents. 150 151 Args: 152 input: Request body. 153 input.agent_user_ids: List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents. 154 input.allow_bot_conversations: Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged. 155 input.channel_id: Slack channel ID to bind (e.g. `C01234ABCDE`). Acts as the natural key of the binding within the workspace. 156 input.customer_label: Human-readable label for the customer associated with this channel. Stored in the binding's config. `null` if omitted. 157 input.is_ext_shared_cached: Cached value of Slack's `is_ext_shared` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. `null` if omitted. 158 input.is_private_cached: Cached value of Slack's `is_private` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. `null` if omitted. 159 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 160 input.team_id: ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team. 161 162 Returns: 163 The created or updated Slack channel binding, including the full list of currently attached agents. 164 """ 165 return await self._http.request( 166 "/api/v1/slack_channel_bindings", 167 method="POST", 168 body=input, 169 response_type=SlackChannelBinding, 170 ) 171 172 async def provision(self, input: SlackChannelBindingProvisionInput) -> SlackChannelBinding: 173 """ 174 Start adding a customer over Slack Connect 175 Opens a Slack Connect channel with a new customer creating one and sending 176 the invite, or adopting a shared channel you already have and records who is 177 adding whom so the addition can finish once the customer accepts. 178 The returned binding is **pending**: nothing mirrors, and no per-customer Team, 179 agent, or solution instance exists yet. Acceptance is asynchronous and may 180 never come. When it does, the addition completes in the background under the 181 identity of the admin who called this endpoint, re-checked live at that moment. 182 A caller who has since lost their admin role does not get a substitute the 183 addition is refused and a human re-adds the customer. 184 The caller must be an admin of the Slack integration's own organization. This 185 is the same authority the completion demands, checked here so a customer is 186 never invited into a channel whose addition can never finish. 187 Deliberately not exposed as a script binding: this sends mail to a person 188 outside the org, so it stays a vendor-admin HTTP surface. 189 190 Args: 191 input: Request body. 192 input.channel_name: Name for a Slack channel to create for this customer. Required unless `existing_channel_id` is given. The channel is created private. 193 input.customer_email: Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty. 194 input.customer_key: The vendor's own primary key for this customer (`customer_id` / `account_id` / `tenant_id`). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning. 195 input.customer_label: Human-readable name for the customer (e.g. `Acme, Inc.`). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input. 196 input.existing_channel_id: Adopt this already-shared Slack Connect channel (e.g. `C01234ABCDE`) instead of creating one. Mutually exclusive with `channel_name`. 197 input.inputs: String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map. 198 input.slack_team_id: Slack workspace team ID of the vendor's own Slack installation (e.g. `T01234ABCDE`). The customer's workspace is not known yet it resolves from whoever accepts. 199 input.template_config_id: Config ID (`cfg_ `) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet. 200 201 Returns: 202 The pending binding for the customer's channel. `disclosure_state` is `pending` until the customer accepts, and `scope_key` is null until the addition finishes. 203 """ 204 return await self._http.request( 205 "/api/v1/slack_channel_bindings/provision", 206 method="POST", 207 body=input, 208 response_type=SlackChannelBinding, 209 ) 210 211 async def delete(self, channel: str) -> SlackChannelBindingDeleteResponse: 212 """ 213 Delete a Slack channel binding 214 Removes the binding between a Slack channel and its associated team. The 215 channel is identified by its Slack channel ID together with the `slack_team_id` 216 that scopes it to a specific Slack workspace. Removing the binding does not 217 delete the bound team or any conversation threads scoped to it; decommission 218 those resources separately if required. 219 The caller must have team-manage rights on the team the channel is currently 220 bound to. Returning 403 indicates insufficient permission; returning 404 221 indicates the binding does not exist or is not visible to the caller. 222 The REST endpoint returns 204 No Content on success. The script binding 223 (`slack.channel_bindings.delete`) returns a confirmation object so script 224 callers can verify success without an additional fetch. Both paths are 225 idempotent retrying after a partial failure is safe. 226 227 Args: 228 channel: Slack channel ID of the binding to delete (e.g. `C01234ABCDE`). 229 230 Returns: 231 Successful response 232 """ 233 return await self._http.request( 234 f"/api/v1/slack_channel_bindings/{channel}", 235 method="DELETE", 236 response_type=SlackChannelBindingDeleteResponse, 237 ) 238 239 async def get(self, channel: str, slack_team_id: str) -> SlackChannelBinding: 240 """ 241 Retrieve a Slack channel binding 242 Returns the Slack channel binding identified by a Slack channel ID and workspace 243 team ID pair. Use this endpoint to look up the team and agents currently bound 244 to a specific Slack channel. 245 The `channel` path parameter is the Slack channel ID; `slack_team_id` identifies 246 the Slack workspace the channel belongs to, disambiguating channels with the same 247 ID across workspaces. Both parameters are required. Returns 404 if no binding 248 exists for the given pair or the associated Slack integration is not visible to 249 the caller. 250 251 Args: 252 channel: Slack channel ID of the binding to retrieve (e.g. `C01234ABCDE`). 253 slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Used together with `channel` to uniquely identify the binding. 254 255 Returns: 256 The Slack channel binding for the given channel and workspace. 257 """ 258 query: dict[str, object] = {} 259 query["slack_team_id"] = slack_team_id 260 return await self._http.request( 261 f"/api/v1/slack_channel_bindings/{channel}", 262 query=query, 263 response_type=SlackChannelBinding, 264 ) 265 266 async def delivery_outcomes( 267 self, 268 channel: str, 269 *, 270 since: str | None = None, 271 outcome: Literal["delivered", "floored", "judge_refused", "failed"] | None = None, 272 limit: int | None = None, 273 before_cursor: str | None = None, 274 after_cursor: str | None = None, 275 ) -> SlackDeliveryOutcomeListResponse: 276 """ 277 List delivery outcomes for a Slack channel 278 Returns what happened to each agent message this platform sent to a Slack 279 channel, newest attempt first. 280 A message that never appears in a Slack channel has several possible causes 281 that look identical from the channel itself: a content guard withheld it, the 282 cross-org judge refused it, Slack rejected the call, or nobody asked anything. 283 This endpoint tells them apart. Use it to confirm a reply was delivered, or to 284 find out why one never arrived, without reading the channel's mirrored 285 conversation. 286 Outcomes cover **outbound agent messages only**. They carry no message 287 content, no author, and nothing about inbound messages. Access follows the 288 channel's binding the organization and app the channel is bound to and 289 needs no membership in the mirrored thread. 290 Paginated with opaque cursors, newest first. When `has_more` is true, pass the 291 response's `before_cursor` back as `before_cursor` to continue into older 292 history. `since` and `outcome` narrow the result set; they are filters, not 293 paging controls. 294 295 Args: 296 channel: Slack channel ID to read delivery outcomes for (e.g. `C01234ABCDE`). 297 since: Only return attempts at or after this ISO 8601 timestamp (e.g. `2026-08-11T00:00:00Z`). Omit to return the most recent attempts regardless of age. 298 outcome: Return only attempts with this outcome. Omit to return every outcome. Use `floored` and `judge_refused` to see only what was withheld. 299 limit: Maximum number of outcomes to return. Defaults to 50; maximum is 200. 300 before_cursor: Opaque cursor from a previous response; returns outcomes older than it. Cursors are not parseable and are only valid against this endpoint. 301 after_cursor: Opaque cursor from a previous response; returns outcomes newer than it. Suited to a UI loading newer entries. To poll for everything recorded since a point in time, prefer `since` with a little overlap and de-duplicate on `id` `after_cursor` can miss an attempt recorded in the same millisecond as the cursor's own row. 302 303 Returns: 304 Delivery outcomes for the requested channel, newest first. 305 """ 306 query: dict[str, object] = {} 307 if since is not None: 308 query["since"] = since 309 if outcome is not None: 310 query["outcome"] = outcome 311 if limit is not None: 312 query["limit"] = limit 313 if before_cursor is not None: 314 query["before_cursor"] = before_cursor 315 if after_cursor is not None: 316 query["after_cursor"] = after_cursor 317 return await self._http.request( 318 f"/api/v1/slack_channel_bindings/{channel}/delivery_outcomes", 319 query=query, 320 response_type=SlackDeliveryOutcomeListResponse, 321 ) 322 323 async def deposit_thread( 324 self, channel: str, input: SlackChannelBindingDepositThreadInput 325 ) -> SlackChannelBinding: 326 """ 327 Point a Slack channel's deposit pipe at a staging thread, or turn it off 328 Sets the binding's deposit target the internal staging thread the 329 deposit pipe copies this channel's mirror content into. Pass a `null` 330 `thread_id` to turn the pipe off. 331 The target is validated server-side: it must exist, belong to the 332 binding's app and org, and never be a Slack mirror thread. Customer 333 bindings (bound `team_id`) additionally require a team-owned private 334 thread with no participant list, so the staging read ACL stays governed 335 by the channel-membership projection. Re-pointing or clearing an 336 existing target purges the old thread's deposit entries. 337 338 Args: 339 channel: Slack channel ID whose binding is being configured (e.g. `C01234ABCDE`). 340 input: Request body. 341 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 342 input.thread_id: Staging thread ID (primary key, `thr_ `) deposits should flow into. Pass `null` to turn the pipe off. 343 344 Returns: 345 The binding with the updated deposit config. 346 """ 347 return await self._http.request( 348 f"/api/v1/slack_channel_bindings/{channel}/deposit_thread", 349 method="POST", 350 body=input, 351 response_type=SlackChannelBinding, 352 )
87 async def list( 88 self, 89 *, 90 integration: builtins.list[str] | None = None, 91 team: builtins.list[str] | None = None, 92 agent: builtins.list[str] | None = None, 93 org: builtins.list[str] | None = None, 94 page: int | None = None, 95 per_page: int | None = None, 96 ) -> SlackChannelBindingListResponse: 97 """ 98 List Slack channel bindings 99 Returns a page of Slack channel bindings visible to the authenticated user. 100 Results can be filtered by integration, team, agent, or organization. Omit all 101 filter params to retrieve every binding the caller can see. 102 Pagination is page-based. Pass `page` and `per_page` to navigate large result 103 sets. `page` must be a positive integer; `per_page` must be between 1 and 100. 104 Invalid values return 400. 105 106 Args: 107 integration: Return only bindings whose Slack integration matches one of these integration IDs. Omit to return bindings across all integrations. 108 team: Return only bindings bound to one of these team IDs. Omit to return bindings for all teams. 109 agent: Return only bindings that have at least one of these agent user IDs attached. Omit to return bindings regardless of agent attachment. 110 org: Return only bindings that belong to one of these organization IDs. Omit to return bindings across all organizations visible to the caller. 111 page: Page number to retrieve, 1-indexed. Defaults to 1. Must be a positive integer. 112 per_page: Number of bindings to return per page. Defaults to 25; maximum is 100. 113 114 Returns: 115 Paginated list of Slack channel bindings visible to the caller. 116 """ 117 query: dict[str, object] = {} 118 if integration is not None: 119 query["integration"] = integration 120 if team is not None: 121 query["team"] = team 122 if agent is not None: 123 query["agent"] = agent 124 if org is not None: 125 query["org"] = org 126 if page is not None: 127 query["page"] = page 128 if per_page is not None: 129 query["per_page"] = per_page 130 return await self._http.request( 131 "/api/v1/slack_channel_bindings", 132 query=query, 133 response_type=SlackChannelBindingListResponse, 134 )
List Slack channel bindings
Returns a page of Slack channel bindings visible to the authenticated user.
Results can be filtered by integration, team, agent, or organization. Omit all
filter params to retrieve every binding the caller can see.
Pagination is page-based. Pass page and per_page to navigate large result
sets. page must be a positive integer; per_page must be between 1 and 100.
Invalid values return 400.
Arguments:
- integration: Return only bindings whose Slack integration matches one of these integration IDs. Omit to return bindings across all integrations.
- team: Return only bindings bound to one of these team IDs. Omit to return bindings for all teams.
- agent: Return only bindings that have at least one of these agent user IDs attached. Omit to return bindings regardless of agent attachment.
- org: Return only bindings that belong to one of these organization IDs. Omit to return bindings across all organizations visible to the caller.
- page: Page number to retrieve, 1-indexed. Defaults to 1. Must be a positive integer.
- per_page: Number of bindings to return per page. Defaults to 25; maximum is 100.
Returns:
Paginated list of Slack channel bindings visible to the caller.
136 async def create(self, input: SlackChannelBindingCreateInput) -> SlackChannelBinding: 137 """ 138 Create or update a Slack channel binding 139 Creates a new binding between a Slack channel and a team, or updates the 140 existing binding if one already exists for the given channel. The caller also 141 supplies a list of agents to attach to the binding and enroll as members of the 142 destination team. 143 The caller must have team-manage rights on the destination team (and on the 144 currently bound team if the channel is being re-pointed). Returns 403 if 145 permission is insufficient. All write steps are idempotent, so retrying after 146 a partial failure is safe. 147 On success the REST endpoint returns 201 Created. The script binding 148 (`slack.channel_bindings.upsert`) returns the full binding object including the 149 attached agents. 150 151 Args: 152 input: Request body. 153 input.agent_user_ids: List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents. 154 input.allow_bot_conversations: Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged. 155 input.channel_id: Slack channel ID to bind (e.g. `C01234ABCDE`). Acts as the natural key of the binding within the workspace. 156 input.customer_label: Human-readable label for the customer associated with this channel. Stored in the binding's config. `null` if omitted. 157 input.is_ext_shared_cached: Cached value of Slack's `is_ext_shared` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. `null` if omitted. 158 input.is_private_cached: Cached value of Slack's `is_private` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. `null` if omitted. 159 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 160 input.team_id: ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team. 161 162 Returns: 163 The created or updated Slack channel binding, including the full list of currently attached agents. 164 """ 165 return await self._http.request( 166 "/api/v1/slack_channel_bindings", 167 method="POST", 168 body=input, 169 response_type=SlackChannelBinding, 170 )
Create or update a Slack channel binding
Creates a new binding between a Slack channel and a team, or updates the
existing binding if one already exists for the given channel. The caller also
supplies a list of agents to attach to the binding and enroll as members of the
destination team.
The caller must have team-manage rights on the destination team (and on the
currently bound team if the channel is being re-pointed). Returns 403 if
permission is insufficient. All write steps are idempotent, so retrying after
a partial failure is safe.
On success the REST endpoint returns 201 Created. The script binding
(slack.channel_bindings.upsert) returns the full binding object including the
attached agents.
Arguments:
- input: Request body.
- input.agent_user_ids: List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents.
- input.allow_bot_conversations: Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged.
- input.channel_id: Slack channel ID to bind (e.g.
C01234ABCDE). Acts as the natural key of the binding within the workspace. - input.customer_label: Human-readable label for the customer associated with this channel. Stored in the binding's config.
nullif omitted. - input.is_ext_shared_cached: Cached value of Slack's
is_ext_sharedflag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups.nullif omitted. - input.is_private_cached: Cached value of Slack's
is_privateflag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed.nullif omitted. - input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g.
T01234ABCDE). Identifies which Slack integration to use. - input.team_id: ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team.
Returns:
The created or updated Slack channel binding, including the full list of currently attached agents.
172 async def provision(self, input: SlackChannelBindingProvisionInput) -> SlackChannelBinding: 173 """ 174 Start adding a customer over Slack Connect 175 Opens a Slack Connect channel with a new customer creating one and sending 176 the invite, or adopting a shared channel you already have and records who is 177 adding whom so the addition can finish once the customer accepts. 178 The returned binding is **pending**: nothing mirrors, and no per-customer Team, 179 agent, or solution instance exists yet. Acceptance is asynchronous and may 180 never come. When it does, the addition completes in the background under the 181 identity of the admin who called this endpoint, re-checked live at that moment. 182 A caller who has since lost their admin role does not get a substitute the 183 addition is refused and a human re-adds the customer. 184 The caller must be an admin of the Slack integration's own organization. This 185 is the same authority the completion demands, checked here so a customer is 186 never invited into a channel whose addition can never finish. 187 Deliberately not exposed as a script binding: this sends mail to a person 188 outside the org, so it stays a vendor-admin HTTP surface. 189 190 Args: 191 input: Request body. 192 input.channel_name: Name for a Slack channel to create for this customer. Required unless `existing_channel_id` is given. The channel is created private. 193 input.customer_email: Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty. 194 input.customer_key: The vendor's own primary key for this customer (`customer_id` / `account_id` / `tenant_id`). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning. 195 input.customer_label: Human-readable name for the customer (e.g. `Acme, Inc.`). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input. 196 input.existing_channel_id: Adopt this already-shared Slack Connect channel (e.g. `C01234ABCDE`) instead of creating one. Mutually exclusive with `channel_name`. 197 input.inputs: String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map. 198 input.slack_team_id: Slack workspace team ID of the vendor's own Slack installation (e.g. `T01234ABCDE`). The customer's workspace is not known yet it resolves from whoever accepts. 199 input.template_config_id: Config ID (`cfg_ `) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet. 200 201 Returns: 202 The pending binding for the customer's channel. `disclosure_state` is `pending` until the customer accepts, and `scope_key` is null until the addition finishes. 203 """ 204 return await self._http.request( 205 "/api/v1/slack_channel_bindings/provision", 206 method="POST", 207 body=input, 208 response_type=SlackChannelBinding, 209 )
Start adding a customer over Slack Connect Opens a Slack Connect channel with a new customer creating one and sending the invite, or adopting a shared channel you already have and records who is adding whom so the addition can finish once the customer accepts. The returned binding is pending: nothing mirrors, and no per-customer Team, agent, or solution instance exists yet. Acceptance is asynchronous and may never come. When it does, the addition completes in the background under the identity of the admin who called this endpoint, re-checked live at that moment. A caller who has since lost their admin role does not get a substitute the addition is refused and a human re-adds the customer. The caller must be an admin of the Slack integration's own organization. This is the same authority the completion demands, checked here so a customer is never invited into a channel whose addition can never finish. Deliberately not exposed as a script binding: this sends mail to a person outside the org, so it stays a vendor-admin HTTP surface.
Arguments:
- input: Request body.
- input.channel_name: Name for a Slack channel to create for this customer. Required unless
existing_channel_idis given. The channel is created private. - input.customer_email: Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty.
- input.customer_key: The vendor's own primary key for this customer (
customer_id/account_id/tenant_id). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning. - input.customer_label: Human-readable name for the customer (e.g.
Acme, Inc.). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input. - input.existing_channel_id: Adopt this already-shared Slack Connect channel (e.g.
C01234ABCDE) instead of creating one. Mutually exclusive withchannel_name. - input.inputs: String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map.
- input.slack_team_id: Slack workspace team ID of the vendor's own Slack installation (e.g.
T01234ABCDE). The customer's workspace is not known yet it resolves from whoever accepts. - input.template_config_id: Config ID (
cfg_) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet.
Returns:
The pending binding for the customer's channel.
disclosure_stateispendinguntil the customer accepts, andscope_keyis null until the addition finishes.
211 async def delete(self, channel: str) -> SlackChannelBindingDeleteResponse: 212 """ 213 Delete a Slack channel binding 214 Removes the binding between a Slack channel and its associated team. The 215 channel is identified by its Slack channel ID together with the `slack_team_id` 216 that scopes it to a specific Slack workspace. Removing the binding does not 217 delete the bound team or any conversation threads scoped to it; decommission 218 those resources separately if required. 219 The caller must have team-manage rights on the team the channel is currently 220 bound to. Returning 403 indicates insufficient permission; returning 404 221 indicates the binding does not exist or is not visible to the caller. 222 The REST endpoint returns 204 No Content on success. The script binding 223 (`slack.channel_bindings.delete`) returns a confirmation object so script 224 callers can verify success without an additional fetch. Both paths are 225 idempotent retrying after a partial failure is safe. 226 227 Args: 228 channel: Slack channel ID of the binding to delete (e.g. `C01234ABCDE`). 229 230 Returns: 231 Successful response 232 """ 233 return await self._http.request( 234 f"/api/v1/slack_channel_bindings/{channel}", 235 method="DELETE", 236 response_type=SlackChannelBindingDeleteResponse, 237 )
Delete a Slack channel binding
Removes the binding between a Slack channel and its associated team. The
channel is identified by its Slack channel ID together with the slack_team_id
that scopes it to a specific Slack workspace. Removing the binding does not
delete the bound team or any conversation threads scoped to it; decommission
those resources separately if required.
The caller must have team-manage rights on the team the channel is currently
bound to. Returning 403 indicates insufficient permission; returning 404
indicates the binding does not exist or is not visible to the caller.
The REST endpoint returns 204 No Content on success. The script binding
(slack.channel_bindings.delete) returns a confirmation object so script
callers can verify success without an additional fetch. Both paths are
idempotent retrying after a partial failure is safe.
Arguments:
- channel: Slack channel ID of the binding to delete (e.g.
C01234ABCDE).
Returns:
Successful response
239 async def get(self, channel: str, slack_team_id: str) -> SlackChannelBinding: 240 """ 241 Retrieve a Slack channel binding 242 Returns the Slack channel binding identified by a Slack channel ID and workspace 243 team ID pair. Use this endpoint to look up the team and agents currently bound 244 to a specific Slack channel. 245 The `channel` path parameter is the Slack channel ID; `slack_team_id` identifies 246 the Slack workspace the channel belongs to, disambiguating channels with the same 247 ID across workspaces. Both parameters are required. Returns 404 if no binding 248 exists for the given pair or the associated Slack integration is not visible to 249 the caller. 250 251 Args: 252 channel: Slack channel ID of the binding to retrieve (e.g. `C01234ABCDE`). 253 slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Used together with `channel` to uniquely identify the binding. 254 255 Returns: 256 The Slack channel binding for the given channel and workspace. 257 """ 258 query: dict[str, object] = {} 259 query["slack_team_id"] = slack_team_id 260 return await self._http.request( 261 f"/api/v1/slack_channel_bindings/{channel}", 262 query=query, 263 response_type=SlackChannelBinding, 264 )
Retrieve a Slack channel binding
Returns the Slack channel binding identified by a Slack channel ID and workspace
team ID pair. Use this endpoint to look up the team and agents currently bound
to a specific Slack channel.
The channel path parameter is the Slack channel ID; slack_team_id identifies
the Slack workspace the channel belongs to, disambiguating channels with the same
ID across workspaces. Both parameters are required. Returns 404 if no binding
exists for the given pair or the associated Slack integration is not visible to
the caller.
Arguments:
- channel: Slack channel ID of the binding to retrieve (e.g.
C01234ABCDE). - slack_team_id: Slack workspace team ID that the channel belongs to (e.g.
T01234ABCDE). Used together withchannelto uniquely identify the binding.
Returns:
The Slack channel binding for the given channel and workspace.
266 async def delivery_outcomes( 267 self, 268 channel: str, 269 *, 270 since: str | None = None, 271 outcome: Literal["delivered", "floored", "judge_refused", "failed"] | None = None, 272 limit: int | None = None, 273 before_cursor: str | None = None, 274 after_cursor: str | None = None, 275 ) -> SlackDeliveryOutcomeListResponse: 276 """ 277 List delivery outcomes for a Slack channel 278 Returns what happened to each agent message this platform sent to a Slack 279 channel, newest attempt first. 280 A message that never appears in a Slack channel has several possible causes 281 that look identical from the channel itself: a content guard withheld it, the 282 cross-org judge refused it, Slack rejected the call, or nobody asked anything. 283 This endpoint tells them apart. Use it to confirm a reply was delivered, or to 284 find out why one never arrived, without reading the channel's mirrored 285 conversation. 286 Outcomes cover **outbound agent messages only**. They carry no message 287 content, no author, and nothing about inbound messages. Access follows the 288 channel's binding the organization and app the channel is bound to and 289 needs no membership in the mirrored thread. 290 Paginated with opaque cursors, newest first. When `has_more` is true, pass the 291 response's `before_cursor` back as `before_cursor` to continue into older 292 history. `since` and `outcome` narrow the result set; they are filters, not 293 paging controls. 294 295 Args: 296 channel: Slack channel ID to read delivery outcomes for (e.g. `C01234ABCDE`). 297 since: Only return attempts at or after this ISO 8601 timestamp (e.g. `2026-08-11T00:00:00Z`). Omit to return the most recent attempts regardless of age. 298 outcome: Return only attempts with this outcome. Omit to return every outcome. Use `floored` and `judge_refused` to see only what was withheld. 299 limit: Maximum number of outcomes to return. Defaults to 50; maximum is 200. 300 before_cursor: Opaque cursor from a previous response; returns outcomes older than it. Cursors are not parseable and are only valid against this endpoint. 301 after_cursor: Opaque cursor from a previous response; returns outcomes newer than it. Suited to a UI loading newer entries. To poll for everything recorded since a point in time, prefer `since` with a little overlap and de-duplicate on `id` `after_cursor` can miss an attempt recorded in the same millisecond as the cursor's own row. 302 303 Returns: 304 Delivery outcomes for the requested channel, newest first. 305 """ 306 query: dict[str, object] = {} 307 if since is not None: 308 query["since"] = since 309 if outcome is not None: 310 query["outcome"] = outcome 311 if limit is not None: 312 query["limit"] = limit 313 if before_cursor is not None: 314 query["before_cursor"] = before_cursor 315 if after_cursor is not None: 316 query["after_cursor"] = after_cursor 317 return await self._http.request( 318 f"/api/v1/slack_channel_bindings/{channel}/delivery_outcomes", 319 query=query, 320 response_type=SlackDeliveryOutcomeListResponse, 321 )
List delivery outcomes for a Slack channel
Returns what happened to each agent message this platform sent to a Slack
channel, newest attempt first.
A message that never appears in a Slack channel has several possible causes
that look identical from the channel itself: a content guard withheld it, the
cross-org judge refused it, Slack rejected the call, or nobody asked anything.
This endpoint tells them apart. Use it to confirm a reply was delivered, or to
find out why one never arrived, without reading the channel's mirrored
conversation.
Outcomes cover outbound agent messages only. They carry no message
content, no author, and nothing about inbound messages. Access follows the
channel's binding the organization and app the channel is bound to and
needs no membership in the mirrored thread.
Paginated with opaque cursors, newest first. When has_more is true, pass the
response's before_cursor back as before_cursor to continue into older
history. since and outcome narrow the result set; they are filters, not
paging controls.
Arguments:
- channel: Slack channel ID to read delivery outcomes for (e.g.
C01234ABCDE). - since: Only return attempts at or after this ISO 8601 timestamp (e.g.
2026-08-11T00:00:00Z). Omit to return the most recent attempts regardless of age. - outcome: Return only attempts with this outcome. Omit to return every outcome. Use
flooredandjudge_refusedto see only what was withheld. - limit: Maximum number of outcomes to return. Defaults to 50; maximum is 200.
- before_cursor: Opaque cursor from a previous response; returns outcomes older than it. Cursors are not parseable and are only valid against this endpoint.
- after_cursor: Opaque cursor from a previous response; returns outcomes newer than it. Suited to a UI loading newer entries. To poll for everything recorded since a point in time, prefer
sincewith a little overlap and de-duplicate onidafter_cursorcan miss an attempt recorded in the same millisecond as the cursor's own row.
Returns:
Delivery outcomes for the requested channel, newest first.
323 async def deposit_thread( 324 self, channel: str, input: SlackChannelBindingDepositThreadInput 325 ) -> SlackChannelBinding: 326 """ 327 Point a Slack channel's deposit pipe at a staging thread, or turn it off 328 Sets the binding's deposit target the internal staging thread the 329 deposit pipe copies this channel's mirror content into. Pass a `null` 330 `thread_id` to turn the pipe off. 331 The target is validated server-side: it must exist, belong to the 332 binding's app and org, and never be a Slack mirror thread. Customer 333 bindings (bound `team_id`) additionally require a team-owned private 334 thread with no participant list, so the staging read ACL stays governed 335 by the channel-membership projection. Re-pointing or clearing an 336 existing target purges the old thread's deposit entries. 337 338 Args: 339 channel: Slack channel ID whose binding is being configured (e.g. `C01234ABCDE`). 340 input: Request body. 341 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 342 input.thread_id: Staging thread ID (primary key, `thr_ `) deposits should flow into. Pass `null` to turn the pipe off. 343 344 Returns: 345 The binding with the updated deposit config. 346 """ 347 return await self._http.request( 348 f"/api/v1/slack_channel_bindings/{channel}/deposit_thread", 349 method="POST", 350 body=input, 351 response_type=SlackChannelBinding, 352 )
Point a Slack channel's deposit pipe at a staging thread, or turn it off
Sets the binding's deposit target the internal staging thread the
deposit pipe copies this channel's mirror content into. Pass a null
thread_id to turn the pipe off.
The target is validated server-side: it must exist, belong to the
binding's app and org, and never be a Slack mirror thread. Customer
bindings (bound team_id) additionally require a team-owned private
thread with no participant list, so the staging read ACL stays governed
by the channel-membership projection. Re-pointing or clearing an
existing target purges the old thread's deposit entries.
Arguments:
- channel: Slack channel ID whose binding is being configured (e.g.
C01234ABCDE). - input: Request body.
- input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g.
T01234ABCDE). Identifies which Slack integration to use. - input.thread_id: Staging thread ID (primary key,
thr_) deposits should flow into. Passnullto turn the pipe off.
Returns:
The binding with the updated deposit config.
355class SlackChannelBindingResource: 356 def __init__(self, http: SyncHttpClient): 357 self._http = http 358 359 def list( 360 self, 361 *, 362 integration: builtins.list[str] | None = None, 363 team: builtins.list[str] | None = None, 364 agent: builtins.list[str] | None = None, 365 org: builtins.list[str] | None = None, 366 page: int | None = None, 367 per_page: int | None = None, 368 ) -> SlackChannelBindingListResponse: 369 """ 370 List Slack channel bindings 371 Returns a page of Slack channel bindings visible to the authenticated user. 372 Results can be filtered by integration, team, agent, or organization. Omit all 373 filter params to retrieve every binding the caller can see. 374 Pagination is page-based. Pass `page` and `per_page` to navigate large result 375 sets. `page` must be a positive integer; `per_page` must be between 1 and 100. 376 Invalid values return 400. 377 378 Args: 379 integration: Return only bindings whose Slack integration matches one of these integration IDs. Omit to return bindings across all integrations. 380 team: Return only bindings bound to one of these team IDs. Omit to return bindings for all teams. 381 agent: Return only bindings that have at least one of these agent user IDs attached. Omit to return bindings regardless of agent attachment. 382 org: Return only bindings that belong to one of these organization IDs. Omit to return bindings across all organizations visible to the caller. 383 page: Page number to retrieve, 1-indexed. Defaults to 1. Must be a positive integer. 384 per_page: Number of bindings to return per page. Defaults to 25; maximum is 100. 385 386 Returns: 387 Paginated list of Slack channel bindings visible to the caller. 388 """ 389 query: dict[str, object] = {} 390 if integration is not None: 391 query["integration"] = integration 392 if team is not None: 393 query["team"] = team 394 if agent is not None: 395 query["agent"] = agent 396 if org is not None: 397 query["org"] = org 398 if page is not None: 399 query["page"] = page 400 if per_page is not None: 401 query["per_page"] = per_page 402 return self._http.request( 403 "/api/v1/slack_channel_bindings", 404 query=query, 405 response_type=SlackChannelBindingListResponse, 406 ) 407 408 def create(self, input: SlackChannelBindingCreateInput) -> SlackChannelBinding: 409 """ 410 Create or update a Slack channel binding 411 Creates a new binding between a Slack channel and a team, or updates the 412 existing binding if one already exists for the given channel. The caller also 413 supplies a list of agents to attach to the binding and enroll as members of the 414 destination team. 415 The caller must have team-manage rights on the destination team (and on the 416 currently bound team if the channel is being re-pointed). Returns 403 if 417 permission is insufficient. All write steps are idempotent, so retrying after 418 a partial failure is safe. 419 On success the REST endpoint returns 201 Created. The script binding 420 (`slack.channel_bindings.upsert`) returns the full binding object including the 421 attached agents. 422 423 Args: 424 input: Request body. 425 input.agent_user_ids: List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents. 426 input.allow_bot_conversations: Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged. 427 input.channel_id: Slack channel ID to bind (e.g. `C01234ABCDE`). Acts as the natural key of the binding within the workspace. 428 input.customer_label: Human-readable label for the customer associated with this channel. Stored in the binding's config. `null` if omitted. 429 input.is_ext_shared_cached: Cached value of Slack's `is_ext_shared` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. `null` if omitted. 430 input.is_private_cached: Cached value of Slack's `is_private` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. `null` if omitted. 431 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 432 input.team_id: ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team. 433 434 Returns: 435 The created or updated Slack channel binding, including the full list of currently attached agents. 436 """ 437 return self._http.request( 438 "/api/v1/slack_channel_bindings", 439 method="POST", 440 body=input, 441 response_type=SlackChannelBinding, 442 ) 443 444 def provision(self, input: SlackChannelBindingProvisionInput) -> SlackChannelBinding: 445 """ 446 Start adding a customer over Slack Connect 447 Opens a Slack Connect channel with a new customer creating one and sending 448 the invite, or adopting a shared channel you already have and records who is 449 adding whom so the addition can finish once the customer accepts. 450 The returned binding is **pending**: nothing mirrors, and no per-customer Team, 451 agent, or solution instance exists yet. Acceptance is asynchronous and may 452 never come. When it does, the addition completes in the background under the 453 identity of the admin who called this endpoint, re-checked live at that moment. 454 A caller who has since lost their admin role does not get a substitute the 455 addition is refused and a human re-adds the customer. 456 The caller must be an admin of the Slack integration's own organization. This 457 is the same authority the completion demands, checked here so a customer is 458 never invited into a channel whose addition can never finish. 459 Deliberately not exposed as a script binding: this sends mail to a person 460 outside the org, so it stays a vendor-admin HTTP surface. 461 462 Args: 463 input: Request body. 464 input.channel_name: Name for a Slack channel to create for this customer. Required unless `existing_channel_id` is given. The channel is created private. 465 input.customer_email: Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty. 466 input.customer_key: The vendor's own primary key for this customer (`customer_id` / `account_id` / `tenant_id`). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning. 467 input.customer_label: Human-readable name for the customer (e.g. `Acme, Inc.`). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input. 468 input.existing_channel_id: Adopt this already-shared Slack Connect channel (e.g. `C01234ABCDE`) instead of creating one. Mutually exclusive with `channel_name`. 469 input.inputs: String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map. 470 input.slack_team_id: Slack workspace team ID of the vendor's own Slack installation (e.g. `T01234ABCDE`). The customer's workspace is not known yet it resolves from whoever accepts. 471 input.template_config_id: Config ID (`cfg_ `) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet. 472 473 Returns: 474 The pending binding for the customer's channel. `disclosure_state` is `pending` until the customer accepts, and `scope_key` is null until the addition finishes. 475 """ 476 return self._http.request( 477 "/api/v1/slack_channel_bindings/provision", 478 method="POST", 479 body=input, 480 response_type=SlackChannelBinding, 481 ) 482 483 def delete(self, channel: str) -> SlackChannelBindingDeleteResponse: 484 """ 485 Delete a Slack channel binding 486 Removes the binding between a Slack channel and its associated team. The 487 channel is identified by its Slack channel ID together with the `slack_team_id` 488 that scopes it to a specific Slack workspace. Removing the binding does not 489 delete the bound team or any conversation threads scoped to it; decommission 490 those resources separately if required. 491 The caller must have team-manage rights on the team the channel is currently 492 bound to. Returning 403 indicates insufficient permission; returning 404 493 indicates the binding does not exist or is not visible to the caller. 494 The REST endpoint returns 204 No Content on success. The script binding 495 (`slack.channel_bindings.delete`) returns a confirmation object so script 496 callers can verify success without an additional fetch. Both paths are 497 idempotent retrying after a partial failure is safe. 498 499 Args: 500 channel: Slack channel ID of the binding to delete (e.g. `C01234ABCDE`). 501 502 Returns: 503 Successful response 504 """ 505 return self._http.request( 506 f"/api/v1/slack_channel_bindings/{channel}", 507 method="DELETE", 508 response_type=SlackChannelBindingDeleteResponse, 509 ) 510 511 def get(self, channel: str, slack_team_id: str) -> SlackChannelBinding: 512 """ 513 Retrieve a Slack channel binding 514 Returns the Slack channel binding identified by a Slack channel ID and workspace 515 team ID pair. Use this endpoint to look up the team and agents currently bound 516 to a specific Slack channel. 517 The `channel` path parameter is the Slack channel ID; `slack_team_id` identifies 518 the Slack workspace the channel belongs to, disambiguating channels with the same 519 ID across workspaces. Both parameters are required. Returns 404 if no binding 520 exists for the given pair or the associated Slack integration is not visible to 521 the caller. 522 523 Args: 524 channel: Slack channel ID of the binding to retrieve (e.g. `C01234ABCDE`). 525 slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Used together with `channel` to uniquely identify the binding. 526 527 Returns: 528 The Slack channel binding for the given channel and workspace. 529 """ 530 query: dict[str, object] = {} 531 query["slack_team_id"] = slack_team_id 532 return self._http.request( 533 f"/api/v1/slack_channel_bindings/{channel}", 534 query=query, 535 response_type=SlackChannelBinding, 536 ) 537 538 def delivery_outcomes( 539 self, 540 channel: str, 541 *, 542 since: str | None = None, 543 outcome: Literal["delivered", "floored", "judge_refused", "failed"] | None = None, 544 limit: int | None = None, 545 before_cursor: str | None = None, 546 after_cursor: str | None = None, 547 ) -> SlackDeliveryOutcomeListResponse: 548 """ 549 List delivery outcomes for a Slack channel 550 Returns what happened to each agent message this platform sent to a Slack 551 channel, newest attempt first. 552 A message that never appears in a Slack channel has several possible causes 553 that look identical from the channel itself: a content guard withheld it, the 554 cross-org judge refused it, Slack rejected the call, or nobody asked anything. 555 This endpoint tells them apart. Use it to confirm a reply was delivered, or to 556 find out why one never arrived, without reading the channel's mirrored 557 conversation. 558 Outcomes cover **outbound agent messages only**. They carry no message 559 content, no author, and nothing about inbound messages. Access follows the 560 channel's binding the organization and app the channel is bound to and 561 needs no membership in the mirrored thread. 562 Paginated with opaque cursors, newest first. When `has_more` is true, pass the 563 response's `before_cursor` back as `before_cursor` to continue into older 564 history. `since` and `outcome` narrow the result set; they are filters, not 565 paging controls. 566 567 Args: 568 channel: Slack channel ID to read delivery outcomes for (e.g. `C01234ABCDE`). 569 since: Only return attempts at or after this ISO 8601 timestamp (e.g. `2026-08-11T00:00:00Z`). Omit to return the most recent attempts regardless of age. 570 outcome: Return only attempts with this outcome. Omit to return every outcome. Use `floored` and `judge_refused` to see only what was withheld. 571 limit: Maximum number of outcomes to return. Defaults to 50; maximum is 200. 572 before_cursor: Opaque cursor from a previous response; returns outcomes older than it. Cursors are not parseable and are only valid against this endpoint. 573 after_cursor: Opaque cursor from a previous response; returns outcomes newer than it. Suited to a UI loading newer entries. To poll for everything recorded since a point in time, prefer `since` with a little overlap and de-duplicate on `id` `after_cursor` can miss an attempt recorded in the same millisecond as the cursor's own row. 574 575 Returns: 576 Delivery outcomes for the requested channel, newest first. 577 """ 578 query: dict[str, object] = {} 579 if since is not None: 580 query["since"] = since 581 if outcome is not None: 582 query["outcome"] = outcome 583 if limit is not None: 584 query["limit"] = limit 585 if before_cursor is not None: 586 query["before_cursor"] = before_cursor 587 if after_cursor is not None: 588 query["after_cursor"] = after_cursor 589 return self._http.request( 590 f"/api/v1/slack_channel_bindings/{channel}/delivery_outcomes", 591 query=query, 592 response_type=SlackDeliveryOutcomeListResponse, 593 ) 594 595 def deposit_thread( 596 self, channel: str, input: SlackChannelBindingDepositThreadInput 597 ) -> SlackChannelBinding: 598 """ 599 Point a Slack channel's deposit pipe at a staging thread, or turn it off 600 Sets the binding's deposit target the internal staging thread the 601 deposit pipe copies this channel's mirror content into. Pass a `null` 602 `thread_id` to turn the pipe off. 603 The target is validated server-side: it must exist, belong to the 604 binding's app and org, and never be a Slack mirror thread. Customer 605 bindings (bound `team_id`) additionally require a team-owned private 606 thread with no participant list, so the staging read ACL stays governed 607 by the channel-membership projection. Re-pointing or clearing an 608 existing target purges the old thread's deposit entries. 609 610 Args: 611 channel: Slack channel ID whose binding is being configured (e.g. `C01234ABCDE`). 612 input: Request body. 613 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 614 input.thread_id: Staging thread ID (primary key, `thr_ `) deposits should flow into. Pass `null` to turn the pipe off. 615 616 Returns: 617 The binding with the updated deposit config. 618 """ 619 return self._http.request( 620 f"/api/v1/slack_channel_bindings/{channel}/deposit_thread", 621 method="POST", 622 body=input, 623 response_type=SlackChannelBinding, 624 )
359 def list( 360 self, 361 *, 362 integration: builtins.list[str] | None = None, 363 team: builtins.list[str] | None = None, 364 agent: builtins.list[str] | None = None, 365 org: builtins.list[str] | None = None, 366 page: int | None = None, 367 per_page: int | None = None, 368 ) -> SlackChannelBindingListResponse: 369 """ 370 List Slack channel bindings 371 Returns a page of Slack channel bindings visible to the authenticated user. 372 Results can be filtered by integration, team, agent, or organization. Omit all 373 filter params to retrieve every binding the caller can see. 374 Pagination is page-based. Pass `page` and `per_page` to navigate large result 375 sets. `page` must be a positive integer; `per_page` must be between 1 and 100. 376 Invalid values return 400. 377 378 Args: 379 integration: Return only bindings whose Slack integration matches one of these integration IDs. Omit to return bindings across all integrations. 380 team: Return only bindings bound to one of these team IDs. Omit to return bindings for all teams. 381 agent: Return only bindings that have at least one of these agent user IDs attached. Omit to return bindings regardless of agent attachment. 382 org: Return only bindings that belong to one of these organization IDs. Omit to return bindings across all organizations visible to the caller. 383 page: Page number to retrieve, 1-indexed. Defaults to 1. Must be a positive integer. 384 per_page: Number of bindings to return per page. Defaults to 25; maximum is 100. 385 386 Returns: 387 Paginated list of Slack channel bindings visible to the caller. 388 """ 389 query: dict[str, object] = {} 390 if integration is not None: 391 query["integration"] = integration 392 if team is not None: 393 query["team"] = team 394 if agent is not None: 395 query["agent"] = agent 396 if org is not None: 397 query["org"] = org 398 if page is not None: 399 query["page"] = page 400 if per_page is not None: 401 query["per_page"] = per_page 402 return self._http.request( 403 "/api/v1/slack_channel_bindings", 404 query=query, 405 response_type=SlackChannelBindingListResponse, 406 )
List Slack channel bindings
Returns a page of Slack channel bindings visible to the authenticated user.
Results can be filtered by integration, team, agent, or organization. Omit all
filter params to retrieve every binding the caller can see.
Pagination is page-based. Pass page and per_page to navigate large result
sets. page must be a positive integer; per_page must be between 1 and 100.
Invalid values return 400.
Arguments:
- integration: Return only bindings whose Slack integration matches one of these integration IDs. Omit to return bindings across all integrations.
- team: Return only bindings bound to one of these team IDs. Omit to return bindings for all teams.
- agent: Return only bindings that have at least one of these agent user IDs attached. Omit to return bindings regardless of agent attachment.
- org: Return only bindings that belong to one of these organization IDs. Omit to return bindings across all organizations visible to the caller.
- page: Page number to retrieve, 1-indexed. Defaults to 1. Must be a positive integer.
- per_page: Number of bindings to return per page. Defaults to 25; maximum is 100.
Returns:
Paginated list of Slack channel bindings visible to the caller.
408 def create(self, input: SlackChannelBindingCreateInput) -> SlackChannelBinding: 409 """ 410 Create or update a Slack channel binding 411 Creates a new binding between a Slack channel and a team, or updates the 412 existing binding if one already exists for the given channel. The caller also 413 supplies a list of agents to attach to the binding and enroll as members of the 414 destination team. 415 The caller must have team-manage rights on the destination team (and on the 416 currently bound team if the channel is being re-pointed). Returns 403 if 417 permission is insufficient. All write steps are idempotent, so retrying after 418 a partial failure is safe. 419 On success the REST endpoint returns 201 Created. The script binding 420 (`slack.channel_bindings.upsert`) returns the full binding object including the 421 attached agents. 422 423 Args: 424 input: Request body. 425 input.agent_user_ids: List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents. 426 input.allow_bot_conversations: Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged. 427 input.channel_id: Slack channel ID to bind (e.g. `C01234ABCDE`). Acts as the natural key of the binding within the workspace. 428 input.customer_label: Human-readable label for the customer associated with this channel. Stored in the binding's config. `null` if omitted. 429 input.is_ext_shared_cached: Cached value of Slack's `is_ext_shared` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. `null` if omitted. 430 input.is_private_cached: Cached value of Slack's `is_private` flag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed. `null` if omitted. 431 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 432 input.team_id: ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team. 433 434 Returns: 435 The created or updated Slack channel binding, including the full list of currently attached agents. 436 """ 437 return self._http.request( 438 "/api/v1/slack_channel_bindings", 439 method="POST", 440 body=input, 441 response_type=SlackChannelBinding, 442 )
Create or update a Slack channel binding
Creates a new binding between a Slack channel and a team, or updates the
existing binding if one already exists for the given channel. The caller also
supplies a list of agents to attach to the binding and enroll as members of the
destination team.
The caller must have team-manage rights on the destination team (and on the
currently bound team if the channel is being re-pointed). Returns 403 if
permission is insufficient. All write steps are idempotent, so retrying after
a partial failure is safe.
On success the REST endpoint returns 201 Created. The script binding
(slack.channel_bindings.upsert) returns the full binding object including the
attached agents.
Arguments:
- input: Request body.
- input.agent_user_ids: List of agent user IDs to attach to the binding and enroll as members of the destination team. Pass an empty array to bind the channel without attaching any agents.
- input.allow_bot_conversations: Opt this channel into sustained bot-to-bot conversation: the reply loop brake is disabled for its mirror thread. Set when the counterparty is a known bot the agent should keep answering. Omitting the parameter leaves the stored value unchanged.
- input.channel_id: Slack channel ID to bind (e.g.
C01234ABCDE). Acts as the natural key of the binding within the workspace. - input.customer_label: Human-readable label for the customer associated with this channel. Stored in the binding's config.
nullif omitted. - input.is_ext_shared_cached: Cached value of Slack's
is_ext_sharedflag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups.nullif omitted. - input.is_private_cached: Cached value of Slack's
is_privateflag for the channel. When provided, this value is persisted on the binding to avoid repeated Slack API lookups. Private channels are member-managed.nullif omitted. - input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g.
T01234ABCDE). Identifies which Slack integration to use. - input.team_id: ID of the team to bind the Slack channel to. The caller must have team-manage rights on this team.
Returns:
The created or updated Slack channel binding, including the full list of currently attached agents.
444 def provision(self, input: SlackChannelBindingProvisionInput) -> SlackChannelBinding: 445 """ 446 Start adding a customer over Slack Connect 447 Opens a Slack Connect channel with a new customer creating one and sending 448 the invite, or adopting a shared channel you already have and records who is 449 adding whom so the addition can finish once the customer accepts. 450 The returned binding is **pending**: nothing mirrors, and no per-customer Team, 451 agent, or solution instance exists yet. Acceptance is asynchronous and may 452 never come. When it does, the addition completes in the background under the 453 identity of the admin who called this endpoint, re-checked live at that moment. 454 A caller who has since lost their admin role does not get a substitute the 455 addition is refused and a human re-adds the customer. 456 The caller must be an admin of the Slack integration's own organization. This 457 is the same authority the completion demands, checked here so a customer is 458 never invited into a channel whose addition can never finish. 459 Deliberately not exposed as a script binding: this sends mail to a person 460 outside the org, so it stays a vendor-admin HTTP surface. 461 462 Args: 463 input: Request body. 464 input.channel_name: Name for a Slack channel to create for this customer. Required unless `existing_channel_id` is given. The channel is created private. 465 input.customer_email: Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty. 466 input.customer_key: The vendor's own primary key for this customer (`customer_id` / `account_id` / `tenant_id`). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning. 467 input.customer_label: Human-readable name for the customer (e.g. `Acme, Inc.`). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input. 468 input.existing_channel_id: Adopt this already-shared Slack Connect channel (e.g. `C01234ABCDE`) instead of creating one. Mutually exclusive with `channel_name`. 469 input.inputs: String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map. 470 input.slack_team_id: Slack workspace team ID of the vendor's own Slack installation (e.g. `T01234ABCDE`). The customer's workspace is not known yet it resolves from whoever accepts. 471 input.template_config_id: Config ID (`cfg_ `) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet. 472 473 Returns: 474 The pending binding for the customer's channel. `disclosure_state` is `pending` until the customer accepts, and `scope_key` is null until the addition finishes. 475 """ 476 return self._http.request( 477 "/api/v1/slack_channel_bindings/provision", 478 method="POST", 479 body=input, 480 response_type=SlackChannelBinding, 481 )
Start adding a customer over Slack Connect Opens a Slack Connect channel with a new customer creating one and sending the invite, or adopting a shared channel you already have and records who is adding whom so the addition can finish once the customer accepts. The returned binding is pending: nothing mirrors, and no per-customer Team, agent, or solution instance exists yet. Acceptance is asynchronous and may never come. When it does, the addition completes in the background under the identity of the admin who called this endpoint, re-checked live at that moment. A caller who has since lost their admin role does not get a substitute the addition is refused and a human re-adds the customer. The caller must be an admin of the Slack integration's own organization. This is the same authority the completion demands, checked here so a customer is never invited into a channel whose addition can never finish. Deliberately not exposed as a script binding: this sends mail to a person outside the org, so it stays a vendor-admin HTTP surface.
Arguments:
- input: Request body.
- input.channel_name: Name for a Slack channel to create for this customer. Required unless
existing_channel_idis given. The channel is created private. - input.customer_email: Address the Slack Connect invite is sent to. Required when creating a channel; optional when adopting one the customer is already in. Whoever accepts becomes the verified counterparty.
- input.customer_key: The vendor's own primary key for this customer (
customer_id/account_id/tenant_id). The per-customer agent's data access is locked to it. Immutable once the customer is added: re-targeting means offboarding and re-provisioning. - input.customer_label: Human-readable name for the customer (e.g.
Acme, Inc.). Used for the vendor's own dashboards and as the per-customer Team's name. Not an identity or an access control input. - input.existing_channel_id: Adopt this already-shared Slack Connect channel (e.g.
C01234ABCDE) instead of creating one. Mutually exclusive withchannel_name. - input.inputs: String-keyed values the per-customer solution instance is stamped with. Defaults to an empty map.
- input.slack_team_id: Slack workspace team ID of the vendor's own Slack installation (e.g.
T01234ABCDE). The customer's workspace is not known yet it resolves from whoever accepts. - input.template_config_id: Config ID (
cfg_) of the org-installed Solution the per-customer instance is stamped from. Must be the organization's own installed copy, not the catalog original instances stamped from a different config do not appear in the vendor's customer fleet.
Returns:
The pending binding for the customer's channel.
disclosure_stateispendinguntil the customer accepts, andscope_keyis null until the addition finishes.
483 def delete(self, channel: str) -> SlackChannelBindingDeleteResponse: 484 """ 485 Delete a Slack channel binding 486 Removes the binding between a Slack channel and its associated team. The 487 channel is identified by its Slack channel ID together with the `slack_team_id` 488 that scopes it to a specific Slack workspace. Removing the binding does not 489 delete the bound team or any conversation threads scoped to it; decommission 490 those resources separately if required. 491 The caller must have team-manage rights on the team the channel is currently 492 bound to. Returning 403 indicates insufficient permission; returning 404 493 indicates the binding does not exist or is not visible to the caller. 494 The REST endpoint returns 204 No Content on success. The script binding 495 (`slack.channel_bindings.delete`) returns a confirmation object so script 496 callers can verify success without an additional fetch. Both paths are 497 idempotent retrying after a partial failure is safe. 498 499 Args: 500 channel: Slack channel ID of the binding to delete (e.g. `C01234ABCDE`). 501 502 Returns: 503 Successful response 504 """ 505 return self._http.request( 506 f"/api/v1/slack_channel_bindings/{channel}", 507 method="DELETE", 508 response_type=SlackChannelBindingDeleteResponse, 509 )
Delete a Slack channel binding
Removes the binding between a Slack channel and its associated team. The
channel is identified by its Slack channel ID together with the slack_team_id
that scopes it to a specific Slack workspace. Removing the binding does not
delete the bound team or any conversation threads scoped to it; decommission
those resources separately if required.
The caller must have team-manage rights on the team the channel is currently
bound to. Returning 403 indicates insufficient permission; returning 404
indicates the binding does not exist or is not visible to the caller.
The REST endpoint returns 204 No Content on success. The script binding
(slack.channel_bindings.delete) returns a confirmation object so script
callers can verify success without an additional fetch. Both paths are
idempotent retrying after a partial failure is safe.
Arguments:
- channel: Slack channel ID of the binding to delete (e.g.
C01234ABCDE).
Returns:
Successful response
511 def get(self, channel: str, slack_team_id: str) -> SlackChannelBinding: 512 """ 513 Retrieve a Slack channel binding 514 Returns the Slack channel binding identified by a Slack channel ID and workspace 515 team ID pair. Use this endpoint to look up the team and agents currently bound 516 to a specific Slack channel. 517 The `channel` path parameter is the Slack channel ID; `slack_team_id` identifies 518 the Slack workspace the channel belongs to, disambiguating channels with the same 519 ID across workspaces. Both parameters are required. Returns 404 if no binding 520 exists for the given pair or the associated Slack integration is not visible to 521 the caller. 522 523 Args: 524 channel: Slack channel ID of the binding to retrieve (e.g. `C01234ABCDE`). 525 slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Used together with `channel` to uniquely identify the binding. 526 527 Returns: 528 The Slack channel binding for the given channel and workspace. 529 """ 530 query: dict[str, object] = {} 531 query["slack_team_id"] = slack_team_id 532 return self._http.request( 533 f"/api/v1/slack_channel_bindings/{channel}", 534 query=query, 535 response_type=SlackChannelBinding, 536 )
Retrieve a Slack channel binding
Returns the Slack channel binding identified by a Slack channel ID and workspace
team ID pair. Use this endpoint to look up the team and agents currently bound
to a specific Slack channel.
The channel path parameter is the Slack channel ID; slack_team_id identifies
the Slack workspace the channel belongs to, disambiguating channels with the same
ID across workspaces. Both parameters are required. Returns 404 if no binding
exists for the given pair or the associated Slack integration is not visible to
the caller.
Arguments:
- channel: Slack channel ID of the binding to retrieve (e.g.
C01234ABCDE). - slack_team_id: Slack workspace team ID that the channel belongs to (e.g.
T01234ABCDE). Used together withchannelto uniquely identify the binding.
Returns:
The Slack channel binding for the given channel and workspace.
538 def delivery_outcomes( 539 self, 540 channel: str, 541 *, 542 since: str | None = None, 543 outcome: Literal["delivered", "floored", "judge_refused", "failed"] | None = None, 544 limit: int | None = None, 545 before_cursor: str | None = None, 546 after_cursor: str | None = None, 547 ) -> SlackDeliveryOutcomeListResponse: 548 """ 549 List delivery outcomes for a Slack channel 550 Returns what happened to each agent message this platform sent to a Slack 551 channel, newest attempt first. 552 A message that never appears in a Slack channel has several possible causes 553 that look identical from the channel itself: a content guard withheld it, the 554 cross-org judge refused it, Slack rejected the call, or nobody asked anything. 555 This endpoint tells them apart. Use it to confirm a reply was delivered, or to 556 find out why one never arrived, without reading the channel's mirrored 557 conversation. 558 Outcomes cover **outbound agent messages only**. They carry no message 559 content, no author, and nothing about inbound messages. Access follows the 560 channel's binding the organization and app the channel is bound to and 561 needs no membership in the mirrored thread. 562 Paginated with opaque cursors, newest first. When `has_more` is true, pass the 563 response's `before_cursor` back as `before_cursor` to continue into older 564 history. `since` and `outcome` narrow the result set; they are filters, not 565 paging controls. 566 567 Args: 568 channel: Slack channel ID to read delivery outcomes for (e.g. `C01234ABCDE`). 569 since: Only return attempts at or after this ISO 8601 timestamp (e.g. `2026-08-11T00:00:00Z`). Omit to return the most recent attempts regardless of age. 570 outcome: Return only attempts with this outcome. Omit to return every outcome. Use `floored` and `judge_refused` to see only what was withheld. 571 limit: Maximum number of outcomes to return. Defaults to 50; maximum is 200. 572 before_cursor: Opaque cursor from a previous response; returns outcomes older than it. Cursors are not parseable and are only valid against this endpoint. 573 after_cursor: Opaque cursor from a previous response; returns outcomes newer than it. Suited to a UI loading newer entries. To poll for everything recorded since a point in time, prefer `since` with a little overlap and de-duplicate on `id` `after_cursor` can miss an attempt recorded in the same millisecond as the cursor's own row. 574 575 Returns: 576 Delivery outcomes for the requested channel, newest first. 577 """ 578 query: dict[str, object] = {} 579 if since is not None: 580 query["since"] = since 581 if outcome is not None: 582 query["outcome"] = outcome 583 if limit is not None: 584 query["limit"] = limit 585 if before_cursor is not None: 586 query["before_cursor"] = before_cursor 587 if after_cursor is not None: 588 query["after_cursor"] = after_cursor 589 return self._http.request( 590 f"/api/v1/slack_channel_bindings/{channel}/delivery_outcomes", 591 query=query, 592 response_type=SlackDeliveryOutcomeListResponse, 593 )
List delivery outcomes for a Slack channel
Returns what happened to each agent message this platform sent to a Slack
channel, newest attempt first.
A message that never appears in a Slack channel has several possible causes
that look identical from the channel itself: a content guard withheld it, the
cross-org judge refused it, Slack rejected the call, or nobody asked anything.
This endpoint tells them apart. Use it to confirm a reply was delivered, or to
find out why one never arrived, without reading the channel's mirrored
conversation.
Outcomes cover outbound agent messages only. They carry no message
content, no author, and nothing about inbound messages. Access follows the
channel's binding the organization and app the channel is bound to and
needs no membership in the mirrored thread.
Paginated with opaque cursors, newest first. When has_more is true, pass the
response's before_cursor back as before_cursor to continue into older
history. since and outcome narrow the result set; they are filters, not
paging controls.
Arguments:
- channel: Slack channel ID to read delivery outcomes for (e.g.
C01234ABCDE). - since: Only return attempts at or after this ISO 8601 timestamp (e.g.
2026-08-11T00:00:00Z). Omit to return the most recent attempts regardless of age. - outcome: Return only attempts with this outcome. Omit to return every outcome. Use
flooredandjudge_refusedto see only what was withheld. - limit: Maximum number of outcomes to return. Defaults to 50; maximum is 200.
- before_cursor: Opaque cursor from a previous response; returns outcomes older than it. Cursors are not parseable and are only valid against this endpoint.
- after_cursor: Opaque cursor from a previous response; returns outcomes newer than it. Suited to a UI loading newer entries. To poll for everything recorded since a point in time, prefer
sincewith a little overlap and de-duplicate onidafter_cursorcan miss an attempt recorded in the same millisecond as the cursor's own row.
Returns:
Delivery outcomes for the requested channel, newest first.
595 def deposit_thread( 596 self, channel: str, input: SlackChannelBindingDepositThreadInput 597 ) -> SlackChannelBinding: 598 """ 599 Point a Slack channel's deposit pipe at a staging thread, or turn it off 600 Sets the binding's deposit target the internal staging thread the 601 deposit pipe copies this channel's mirror content into. Pass a `null` 602 `thread_id` to turn the pipe off. 603 The target is validated server-side: it must exist, belong to the 604 binding's app and org, and never be a Slack mirror thread. Customer 605 bindings (bound `team_id`) additionally require a team-owned private 606 thread with no participant list, so the staging read ACL stays governed 607 by the channel-membership projection. Re-pointing or clearing an 608 existing target purges the old thread's deposit entries. 609 610 Args: 611 channel: Slack channel ID whose binding is being configured (e.g. `C01234ABCDE`). 612 input: Request body. 613 input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g. `T01234ABCDE`). Identifies which Slack integration to use. 614 input.thread_id: Staging thread ID (primary key, `thr_ `) deposits should flow into. Pass `null` to turn the pipe off. 615 616 Returns: 617 The binding with the updated deposit config. 618 """ 619 return self._http.request( 620 f"/api/v1/slack_channel_bindings/{channel}/deposit_thread", 621 method="POST", 622 body=input, 623 response_type=SlackChannelBinding, 624 )
Point a Slack channel's deposit pipe at a staging thread, or turn it off
Sets the binding's deposit target the internal staging thread the
deposit pipe copies this channel's mirror content into. Pass a null
thread_id to turn the pipe off.
The target is validated server-side: it must exist, belong to the
binding's app and org, and never be a Slack mirror thread. Customer
bindings (bound team_id) additionally require a team-owned private
thread with no participant list, so the staging read ACL stays governed
by the channel-membership projection. Re-pointing or clearing an
existing target purges the old thread's deposit entries.
Arguments:
- channel: Slack channel ID whose binding is being configured (e.g.
C01234ABCDE). - input: Request body.
- input.slack_team_id: Slack workspace team ID that the channel belongs to (e.g.
T01234ABCDE). Identifies which Slack integration to use. - input.thread_id: Staging thread ID (primary key,
thr_) deposits should flow into. Passnullto turn the pipe off.
Returns:
The binding with the updated deposit config.