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

# Channels

> Connect a channel with your own account, choose who answers on it, set rules and share it.

A channel is one connection to where your customers write: a phone number, a mailbox, a website chat or a social
account. You connect each channel with your own account at the provider. ImpelLabs never uses an account of its own
for your channel. The channel belongs to the person who connects it. One agent answers on a channel.

All routes are under `https://api.impellabs.tech/api/v1`. Send `Authorization: Bearer imp_...` on each request. See
[Authentication](https://docs.impellabs.tech/api/authentication.md) and [Conventions](https://docs.impellabs.tech/api/conventions.md). The API reference lists every field.

## Who can see and change a channel

A token acts as the person who made it. Two things control access.

**The channel itself.** By default a person sees, changes and connects their own channels. Owners and admins can
manage any channel. A channel that a person may not see answers `404` with `Channel not found.` A person who sees a
channel but may not change it gets `403` with `Only its owner or an admin can change this channel.` when they try.

**The conversations on the channel.** A channel is private to its owner until the owner shares it. Its conversations
show only to:

* the owner,
* the people and departments the channel is shared with, or everyone when it is shared that way,
* the person a conversation is assigned or handed to.

Owners and admins get no extra view of the conversations on a private channel. A conversation that a person may not
read answers `404` through the [conversations](https://docs.impellabs.tech/api/conversations.md) routes. A channel with no `sharing` set
(`sharing` is `null`) shows its conversations to owners and admins as well.

Sharing never changes who the agent answers.

## List channel kinds

`GET /channels/kinds` returns the kinds of channel this server has: `kind`, `label`, `supports`, `window_hours`,
`available` and `connect`. `connect` describes what the connect step needs from you for that kind.

```bash theme={null}
curl "https://api.impellabs.tech/api/v1/channels/kinds" \
  -H "Authorization: Bearer imp_..."
```

## Connect a channel

`POST /channels/connect/{kind}` with the fields that `connect` names for that kind. The fields are the credentials of
your own account at the provider. They go in and never come back in any reply. The channel starts private to the
person who connects it.

You need the right to connect channels; otherwise `403` with `You cannot connect channels.`

```bash theme={null}
curl -X POST "https://api.impellabs.tech/api/v1/channels/connect/whatsapp" \
  -H "Authorization: Bearer imp_..." \
  -H "Content-Type: application/json" \
  -d '{
    "access_token": "YOUR_ACCESS_TOKEN",
    "waba_id": "YOUR_ACCOUNT_ID",
    "phone_number_id": "YOUR_NUMBER_ID",
    "app_id": "YOUR_APP_ID",
    "app_secret": "YOUR_APP_SECRET"
  }'
```

The reply is `201` with `{ "channels": [ ... ] }`: one channel object for each number or account that the connection
gave. The connect step uses your credentials with the provider. It saves the channel only when that works. A channel that is connected again keeps its owner, its agent and its sharing.

| Status | Cause |
| - | - |
| `400` | The provider refused the credentials, a field is not valid, the kind cannot be connected yet, or the number is connected to another workspace. `detail` says why. |
| `403` | You cannot connect channels. |
| `404` | There is no channel kind like that. |
| `409` | One more thing is needed. The reply has `detail`, `field` and sometimes `pending_id`. Send the same request again with `pending_id` and the missing `field`. A pending connection is kept for 15 minutes. |

For a mailbox, `POST /channels/email/sign-in` with `{ "provider": "gmail" }` or `{ "provider": "outlook" }` returns
`{ "url" }`: the page where the person signs in with their own account. `POST /channels/phone/numbers` lists the
numbers of a phone account for the connect step, with the account's login fields. Nothing is kept.
`GET /channels/phone/voice-options` lists the voice engines, models and voices.

## List and read channels

`GET /channels` returns an array of the channels the person may see. Filters: `kind`, and `mine=1` for your own.
`GET /channels/connections` returns the same channels as a page, with `kind`, `health` (`good`, `warning` or
`blocked`), `mine`, `q` and `sort` (`name`, `health`, `owner`, `agent`), `page` and `page_size`.
`GET /channels/{channel_id}` returns one channel and `counts`: the open conversations that the agent answers and that
the team answers.

```bash theme={null}
curl "https://api.impellabs.tech/api/v1/channels/7b1d3c20-5a4e-4d6f-8b9a-1c2d3e4f5a60" \
  -H "Authorization: Bearer imp_..."
```

```json theme={null}
{
  "id": "7b1d3c20-5a4e-4d6f-8b9a-1c2d3e4f5a60",
  "kind": "whatsapp",
  "label": "WhatsApp",
  "address": "123456789",
  "name": "Main line",
  "status": "connected",
  "problem": "",
  "checked_at": "2026-01-12T09:00:00+00:00",
  "owner": { "id": "a2c4f1d0-6b3e-4a7d-9e52-1c0b8d7e6f10", "name": "Sam Lee" },
  "agent": { "id": "5e77a1b0-3c2d-4e8f-9a6b-0d1c2b3a4f55", "name": "Front desk", "live": true },
  "supports": ["..."],
  "window_hours": 24,
  "health": "good",
  "settings": { "who": "all", "test": [], "percent": 10, "reply_wait": 0, "read_receipts": false,
                "typing": false, "rich": true, "keep_team": false, "keep_team_days": 30,
                "signature": "", "signature_card": null },
  "sharing": { "mode": "private", "members": [], "departments": [] },
  "can_read": true,
  "can_share": true,
  "can_manage": true,
  "mine": true,
  "created_at": "2026-01-10T08:00:00+00:00",
  "counts": { "ai": 1, "team": 0 }
}
```

The example shows the main fields. The channel also has `info`, `features`, `template_categories`, `test_phones`,
`unshared_takers` and `agent_hidden`. `supports` and `features` come from the channel kind.

`POST /channels/{channel_id}/verify` asks the provider whether the channel still works. It needs the right to manage
the channel. `DELETE /channels/{channel_id}` disconnects it. The channel is archived and the reply is `204`.

## Choose who answers

`PATCH /channels/{channel_id}` with `{ "agent_id": "<id>" }` puts one agent on the channel. It replaces the agent that
was there. Send `null` for nobody. You need the right to manage the channel.

```bash theme={null}
curl -X PATCH "https://api.impellabs.tech/api/v1/channels/7b1d3c20-5a4e-4d6f-8b9a-1c2d3e4f5a60" \
  -H "Authorization: Bearer imp_..." \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "5e77a1b0-3c2d-4e8f-9a6b-0d1c2b3a4f55"}'
```

The reply is the channel with `counts`.

| Status | Cause |
| - | - |
| `400` | The agent does not exist. A Chief of Staff cannot answer customers. A personal agent must belong to the owner of the channel. A shared agent must be one you may read. |
| `400` | The request has no `agent_id` and no `settings`. |
| `403` | You may not change this channel. |

## Settings and sharing

`PATCH /channels/{channel_id}` with `{ "settings": { ... } }` changes only the keys you send.

| Key | Meaning |
| - | - |
| `who` | `all`, `selected` or `rollout`. `selected` means the agent answers only the test addresses. `rollout` means the test addresses and a share of the others. |
| `test` | Customer addresses that the agent always answers. A phone channel needs the form `+` and the country code. 50 at most. |
| `percent` | 0 to 100. For `rollout` only. A customer stays in or out. |
| `reply_wait` | Seconds to wait for more lines before the agent answers. 0 to 120. |
| `read_receipts`, `typing`, `rich` | `true` or `false`. Used where the channel supports them. |
| `keep_team`, `keep_team_days` | Customers your team wrote to in the days before the agent went live stay with the team. `keep_team_days` is 1 to 365. |
| `signature`, `signature_card` | A mailbox only. The sign-off under every mail. |
| `sharing` | Who reads the conversations. See below. |

A change to `who`, `test` or `percent` applies to new conversations. An unknown key answers `400` with
`This is not a channel setting.`

### Sharing

`sharing` is `{ "mode": "private" | "people" | "everyone", "members": [member ids], "departments": [department ids] }`.
Use `members` and `departments` with `people` only. `people` means the listed members and the members of the listed
departments. `everyone` means every member. A channel has no levels: a person who can read the conversations can
read them all.

```bash theme={null}
curl -X PATCH "https://api.impellabs.tech/api/v1/channels/7b1d3c20-5a4e-4d6f-8b9a-1c2d3e4f5a60" \
  -H "Authorization: Bearer imp_..." \
  -H "Content-Type: application/json" \
  -d '{"settings": {"sharing": {"mode": "people", "members": ["a2c4f1d0-6b3e-4a7d-9e52-1c0b8d7e6f10"], "departments": []}}}'
```

Only the person who connected the channel can share it with more people. Another person who manages the channel can
stop sharing or narrow it. A wider change by them answers `403` with
`Only the person who connected this channel can share it with more people.`

The channel object has two hints for the owner. `unshared_takers` lists people that a handoff rule sends customers to
who cannot read the channel yet. `agent_hidden` is `true` when the channel is shared with people who cannot read the
agent that answers on it. They see the agent's name and replies, never its instructions.

## Templates

A template is a message that you may send when the reply window is closed. Templates belong to the account of the
channel and are reviewed by the provider.

* `GET /channels/{channel_id}/templates` lists them. `status` filters by review status.
* `POST /channels/{channel_id}/templates` with `{ "name", "language", "category", "components" }` sends a new template
  for review. Each variable needs a sample value in the `example` of its component.
* `PATCH /channels/{channel_id}/templates/{template_id}` with `{ "components", "category"? }` changes a template. It is
  reviewed again.
* `DELETE /channels/{channel_id}/templates/{template_id}` removes every language of that name. The reply is `204`.
* `POST /channels/{channel_id}/templates/sync` reads the templates again from the provider.
* `POST /channels/{channel_id}/templates/media` with a multipart `file` uploads a sample image, video or PDF for a
  header. The reply is `{ "handle" }`. Put the handle in the header's `example.header_handle` as a list of one.

Listing needs the right to see the channel. Every change needs the right to manage it.

## Profile, catalog, posts and insights

These routes depend on the channel kind. The API reference has their fields.

* `GET` and `PATCH /channels/{channel_id}/profile`: the business profile that customers see.
* `GET /channels/{channel_id}/catalog`, `POST`, `PATCH`, `DELETE`, `POST .../catalog/sync` and
  `GET .../catalog/items`: the catalog of a number that has one.
* `GET` and `POST /channels/{channel_id}/posts`: the latest posts of an account, and one new photo post.
* `GET /channels/{channel_id}/insights`: reach and activity over the last 28 days.
* `POST /channels/{channel_id}/test-call`: a phone line calls your own number, and the channel's agent answers, as a
  test. The reply is `202` with `{ "room" }`.
* `GET` and `PATCH /channels/prompts`: how agents talk on each kind of channel.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.