# Update

Partial update of a connected Slack channel: switch auto-reply on or off, and change the agent and mode that answer there. Only the fields you include are changed.





Partial update. Send only the fields you want to change. Slack channels only.

```http
PATCH /api/public/v1/connected-channels/{id}
```

`{id}` is the `cc_…` record ID from [List](/api/channels/list). This is the one endpoint that takes the `cc_…` ID; the platform `channel_id` is not accepted here.

Requires an API key with the `channels:write` scope. Only an organization admin can create a key with that scope.

## Request body [#request-body]

<TypeTable
  type="{
  auto_reply: {
    type: &#x22;boolean&#x22;,
    description: &#x22;`true`: Nairi acts on every new top-level post in the channel without being tagged. Replies inside threads still need an @mention. `false`: Nairi answers only when tagged.&#x22;
  },
  default_agent_id: {
    type: &#x22;string&#x22;,
    description: &#x22;The agent that answers in this channel. Accepts the ULID (`cci_…`) or the human-readable slug. Must belong to your organization.&#x22;
  },
  default_mode: {
    type: &#x22;string&#x22;,
    description: &#x22;`ask` (reads, explains and replies in a thread, never edits files) or `execute` (may edit files and open pull requests).&#x22;
  }
}"
/>

<Callout type="info">
  At least one field is required. An empty body returns `400`.
</Callout>

When `auto_reply` actually changes, Nairi posts a short note in the Slack channel naming the API key that made the change, the same way the dashboard names the person. Repeating the current value posts nothing.

## Example [#example]

<Tabs items="[&#x22;bash&#x22;, &#x22;TypeScript&#x22;, &#x22;Ruby&#x22;, &#x22;Python&#x22;, &#x22;Go&#x22;]">
  <Tab value="bash">
    ```bash
    curl -X PATCH https://api.nairi.ai/api/public/v1/connected-channels/CHANNEL_RECORD_ID \
      -H "Authorization: Bearer $NAIRI_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "auto_reply": true,
        "default_agent_id": "oncall",
        "default_mode": "ask"
      }'
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts
    const res = await fetch(
      `https://api.nairi.ai/api/public/v1/connected-channels/${channelRecordId}`,
      {
        method: "PATCH",
        headers: {
          Authorization: `Bearer ${process.env.NAIRI_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          auto_reply: true,
          default_agent_id: "oncall",
          default_mode: "ask",
        }),
      },
    );
    const channel = await res.json();
    ```
  </Tab>

  <Tab value="Ruby">
    ```ruby
    require "net/http"
    require "json"
    require "uri"

    uri = URI("https://api.nairi.ai/api/public/v1/connected-channels/#{channel_record_id}")
    req = Net::HTTP::Patch.new(uri)
    req["Authorization"] = "Bearer #{ENV['NAIRI_API_KEY']}"
    req["Content-Type"] = "application/json"
    req.body = {
      auto_reply: true,
      default_agent_id: "oncall",
      default_mode: "ask",
    }.to_json

    res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
    channel = JSON.parse(res.body)
    ```
  </Tab>

  <Tab value="Python">
    ```python
    import os
    import requests

    res = requests.patch(
        f"https://api.nairi.ai/api/public/v1/connected-channels/{channel_record_id}",
        headers={
            "Authorization": f"Bearer {os.environ['NAIRI_API_KEY']}",
            "Content-Type": "application/json",
        },
        json={
            "auto_reply": True,
            "default_agent_id": "oncall",
            "default_mode": "ask",
        },
    )
    channel = res.json()
    ```
  </Tab>

  <Tab value="Go">
    ```go
    package main

    import (
    	"bytes"
    	"encoding/json"
    	"fmt"
    	"io"
    	"net/http"
    	"os"
    )

    func main() {
    	channelRecordID := os.Getenv("CHANNEL_RECORD_ID")
    	body, _ := json.Marshal(map[string]any{
    		"auto_reply":       true,
    		"default_agent_id": "oncall",
    		"default_mode":     "ask",
    	})
    	req, _ := http.NewRequest(
    		"PATCH",
    		"https://api.nairi.ai/api/public/v1/connected-channels/"+channelRecordID,
    		bytes.NewReader(body),
    	)
    	req.Header.Set("Authorization", "Bearer "+os.Getenv("NAIRI_API_KEY"))
    	req.Header.Set("Content-Type", "application/json")
    	res, _ := http.DefaultClient.Do(req)
    	defer res.Body.Close()
    	raw, _ := io.ReadAll(res.Body)
    	var channel map[string]any
    	json.Unmarshal(raw, &channel)
    	fmt.Println(channel)
    }
    ```
  </Tab>
</Tabs>

## Response: `200 OK` [#response-200-ok]

The updated channel, in the same shape as [List](/api/channels/list).

```json
{
  "id": "cc_01KGFV0WN7G22N8HWYDWFHAYBG",
  "channel_type": "slack",
  "channel_id": "C0AC1J9LF1V",
  "channel_name": "ops-nairi",
  "team_id": "T08S1TQ0QHX",
  "team_name": "Nairi",
  "default_agent_id": "oncall",
  "default_mode": "ask",
  "auto_reply": true,
  "auto_reply_set_at": "2026-10-21T11:03:43.000Z",
  "created_at": "2026-02-22T13:06:42.000Z",
  "updated_at": "2026-10-21T11:03:43.000Z"
}
```

## Errors [#errors]

| Status | When                                                                                                                                      |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid JSON, no fields, an unknown `default_mode`, or a `default_agent_id` that is not in your organization.                             |
| `400`  | `auto_reply: true` on a Slack Connect channel shared with another workspace: `Shared channels cannot auto-reply yet.`                     |
| `400`  | `auto_reply: true` on a channel still waiting for an admin's approval: `Approve this channel first.`                                      |
| `403`  | The API key does not have the `channels:write` scope.                                                                                     |
| `404`  | No Slack channel with that `cc_…` ID in your organization. Discord channels return `404` too; they cannot be changed through the API yet. |

## Limits that stay in the dashboard [#limits-that-stay-in-the-dashboard]

Pausing auto-reply for every channel at once, and the hourly limit on how many runs an auto-reply channel may start, are organization settings. They can only be changed by an admin in the dashboard under Settings → Slack.
