> ## Documentation Index
> Fetch the complete documentation index at: https://dev.docs.1to1ai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Channels

> Lists the business channels and their public key

<Info>
  **Endpoint** · `GET /channels`
</Info>

<Note>
  **Read-only** endpoint: it returns information and changes nothing. It is not sent inside the `actions` array — you call it directly.
</Note>

Returns the active channels of the business, each one with its **public key** (`key`, prefixed with `ch_`). That key is the single most used value in the whole API: the `channel` field of the conversation reference is **required in every action** of `POST /conversation/actions`, and it is also accepted as an optional filter on several query endpoints.

Start here: list the channels once, store the key of the channel you will work with, and reuse it on every request. You can also copy it from the dashboard under **Settings → Channels**, field **Channel key**.

**Parameters**

* This endpoint **takes no query parameters**. It returns the complete list, unpaginated.
* `{slug}` — business identifier in the path (**required**).
* `Authorization: Bearer <key>` — authentication header (**required**).

### Response

```json theme={null}
{
  "data": [
    {
      "key": "ch_7A9K2M4Q",
      "name": "WhatsApp Sales",
      "type": "whatsapp",
      "is_tester": false
    },
    {
      "key": "ch_3F5T8B1Z",
      "name": "WhatsApp Testing",
      "type": "whatsapp",
      "is_tester": true
    }
  ]
}
```

<ResponseField name="data" type="array" required>
  Complete list of active channels. Deleted channels are not returned.
</ResponseField>

<ResponseField name="data[].key" type="string" required>
  Public key of the channel (`ch_...`). This is the value you pass as `channel`.
</ResponseField>

<ResponseField name="data[].name" type="string" required>
  Channel name as shown in the dashboard.
</ResponseField>

<ResponseField name="data[].type" type="string" required>
  Channel type, for example `whatsapp`.
</ResponseField>

<ResponseField name="data[].is_tester" type="boolean" required>
  `true` if this is the business testing channel. Useful to avoid sending real traffic to a test channel.
</ResponseField>

### Example

This is a read: the `GET` creates, modifies and deletes nothing. Its only purpose is to give you the key you will later put in `channel` when you run an action.

```bash theme={null}
curl -X GET "https://app.1to1.ai/api/v1/public/{slug}/channels" \
  -H "Authorization: Bearer sk_1to1_your_api_key"
```

With the key in hand, you can identify a conversation in any action:

```jsonc theme={null}
{
  "conversation": {
    "phone": "+5215512345678",
    "channel": "ch_7A9K2M4Q"
  },
  "actions": [{ "type": "mark_resolved" }]
}
```

**Errors**

| HTTP status | Code                      | When it happens                                                  |
| ----------- | ------------------------- | ---------------------------------------------------------------- |
| `401`       | `INVALID_API_TOKEN`       | Key missing, malformed or invalid.                               |
| `403`       | `TOKEN_BUSINESS_MISMATCH` | The `{slug}` in the path does not match the business of the key. |
| `429`       | `RATE_LIMIT_EXCEEDED`     | Rate limit exceeded. Retry according to `Retry-After`.           |
| `500`       | `UNKNOWN_ERROR`           | Unexpected server error.                                         |

Full reference in [Errors](/en/errors).

A channel key that does not exist does not fail here, but in the request that uses it: the action responds `404` (`CHANNEL_NOT_FOUND`). To see where `channel` fits inside an action group, see [Actions — Overview](/en/action-groups/overview); for the conversation resolution order, see [Identify a conversation](/en/conversations).
