> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs-parschat.parstechai.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs-parschat.parstechai.com/_mcp/server.

# Connect a channel

POST https://api-chat.parstechai.com/v1/robots/{robot_id}/channels
Content-Type: application/json

Connects a Telegram or Instagram channel to a robot. Other channel types are connected in the ParsChat panel.

**Channels you hold credentials for**, such as Telegram, connect immediately. Pass the credential in `config` and the response is a live channel with `is_active: true`.

**Instagram is different.** Meta requires the page owner to authorise in their own browser, so nothing is connected yet: the response is a pending channel carrying an `authorisation_url`. Send the page owner there. The channel becomes active only when they finish, and holds no capacity until then. Configure your return URL with us before the first connection, or the page owner's browser lands on a ParsChat screen instead of yours.

A robot holds at most one channel per type. An open Instagram handshake blocks a second one with 409 until it expires; once it has expired, retrying returns 410 and you start again.

A Telegram bot can be connected to one robot at a time; connecting a bot that is already connected elsewhere returns 409. Reconnecting a bot you disconnected from the same robot brings the channel back with its conversation history.

Reference: https://docs-parschat.parstechai.com/api-reference/channels/create-channel

## Authentication

- `Authorization` header (bearer token, required) — Your API key, issued by ParsChat sales. One key per account, spanning every robot you own. Send it as `Authorization: Bearer pk_live_…`.

## Request

### Path parameters

- `robot_id` (string, required) — The robot's id, as returned by the create call.

### Body (application/json)

This endpoint expects an object.

- `type` (enum, required) — The channel type to connect. Telegram and Instagram can be connected over the API; other channel types are connected in the ParsChat panel and then appear in your channel lists.
  - Allowed values: `telegram`, `instagram`
- `config` (RobotsRobotIdChannelsPostRequestBodyContentApplicationJsonSchemaConfig, optional) — Credentials for channels you hold the credentials for, such as a Telegram bot token. Instagram takes no config: the page owner authorises in their own browser instead.

## Response

### 201

The channel was created. What you get back depends on the type: a live channel for one you hold credentials for, or a pending handshake for Instagram.

- `Channels_createChannel_Response_201`
  - `status`: `connected` (connected)
    - `connected_at` (datetime, optional) — When the channel went live.
    - `id` (string, optional) — ParsChat identifier for the channel.
    - `is_active` (boolean, optional) — Whether the channel is receiving traffic. False while a handshake is pending or after a plan lapses.
    - `robot_id` (string, optional) — The robot that owns this channel.
    - `type` (enum, optional) — The kind of surface this channel connects.
      - Allowed values: `telegram`, `instagram`, `goftino`, `widget`, `crisp`, `gap`, `whatsapp`
    - `username` (string, optional) — The connected account's handle. Present once the page owner has authorised.
  - `status`: `pending_authorisation` (pending_authorisation)
    - `authorisation_url` (string, optional) — Send the page owner's browser here. **Opaque: redirect to it exactly as returned.** Its host and path are not part of this contract and it carries state that must survive the round trip, so never construct, parse or rewrite it.
    - `expires_at` (datetime, optional) — When the handshake expires. After this, start a new one.
    - `id` (string, optional) — ParsChat identifier for the channel being connected.
    - `robot_id` (string, optional) — The robot that will own the channel.
    - `type` (enum, optional) — The channel type you asked for.
      - Allowed values: `instagram`

## Errors

### 400 Bad Request Error

The request itself is malformed: a parameter is missing, unparseable, or out of range. Unlike 422, the request never reached validation of its contents.

- `error` (ErrorError, optional)

### 401 Unauthorized Error

The key is missing, wrong, revoked, or past its expiry date. All four answer `invalid_key`: telling an expired key from an unknown one would confirm to whoever holds a leaked key that it was once real.

- `error` (ErrorError, optional)

### 403 Forbidden Error

The call is understood but not permitted: a missing role, a lapsed plan, or exhausted capacity.

- `error` (ErrorError, optional)

### 404 Not Found Error

No such resource, or it belongs to another partner. We return 404 rather than 403 here, because a 403 would confirm the id exists.

- `error` (ErrorError, optional)

### 409 Conflict Error

The request collides with something that already exists.

- `error` (ErrorError, optional)

### 410 Gone Error

The Instagram handshake expired before the page owner finished.

- `error` (ErrorError, optional)

### 422 Unprocessable Entity Error

The payload is malformed, or a prerequisite is not configured.

- `error` (ErrorError, optional)

### 429 Too Many Requests Error

You are calling the API too fast. `details` names the limit you are held to. This never means an automated reply to an end customer was discarded: those are queued, not dropped.

- `error` (ErrorError, optional)

### 500 Internal Server Error

Something failed on our side. Retry with backoff, and quote `request_id` if it persists.

- `error` (ErrorError, optional)

### 503 Service Unavailable Error

A service we depend on (a channel provider, or our AI service) is unavailable. Retry with backoff.

- `error` (ErrorError, optional)

## Types

### RobotsRobotIdChannelsPostRequestBodyContentApplicationJsonSchemaConfig

Credentials for channels you hold the credentials for, such as a Telegram bot token. Instagram takes no config: the page owner authorises in their own browser instead.

- `token` (string, optional) — Telegram bot token, from BotFather.

### ErrorError

- `code` (string, optional) — Stable machine-readable code. Branch on this, not on the message.
- `message` (string, optional) — Human-readable explanation. Wording may change.
- `request_id` (string, optional) — Log this. It is what lets support find your exact request.
- `details` (map from string to any, optional) — Machine-readable context for the code. On `capacity_exhausted` it carries `occupied`, `requested` and `capacity`; on `rate_limited`, `limit_per_minute` and `window_seconds`.

## Examples

### Telegram, live immediately

**Request**

```json
{
  "type": "telegram",
  "config": {
    "token": "7461234567:AAH..."
  }
}
```

**Response**

```json
{
  "status": "connected",
  "connected_at": "2026-09-20T11:08:45Z",
  "id": "chn_7bT4kM",
  "is_active": true,
  "robot_id": "rbt_8fK2mQ",
  "type": "telegram",
  "username": "rose_flower_bot"
}
```

**SDK Code**

```python Telegram, live immediately
import requests

url = "https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels"

payload = {
    "type": "telegram",
    "config": { "token": "7461234567:AAH..." }
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Telegram, live immediately
const url = 'https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"type":"telegram","config":{"token":"7461234567:AAH..."}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Telegram, live immediately
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels"

	payload := strings.NewReader("{\n  \"type\": \"telegram\",\n  \"config\": {\n    \"token\": \"7461234567:AAH...\"\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Telegram, live immediately
require 'uri'
require 'net/http'

url = URI("https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"type\": \"telegram\",\n  \"config\": {\n    \"token\": \"7461234567:AAH...\"\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java Telegram, live immediately
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"type\": \"telegram\",\n  \"config\": {\n    \"token\": \"7461234567:AAH...\"\n  }\n}")
  .asString();
```

```php Telegram, live immediately
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels', [
  'body' => '{
  "type": "telegram",
  "config": {
    "token": "7461234567:AAH..."
  }
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Telegram, live immediately
using RestSharp;

var client = new RestClient("https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"type\": \"telegram\",\n  \"config\": {\n    \"token\": \"7461234567:AAH...\"\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Telegram, live immediately
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "type": "telegram",
  "config": ["token": "7461234567:AAH..."]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Instagram, awaiting authorisation

**Request**

```json
{
  "type": "instagram"
}
```

**Response**

```json
{
  "status": "connected",
  "id": "chn_3pQ7xL",
  "robot_id": "rbt_8fK2mQ",
  "type": "instagram",
  "authorisation_url": "https://connect.parstechai.com/authorise?service_id=svc_4dR8nW",
  "expires_at": "2026-09-20T12:04:33Z"
}
```

**SDK Code**

```python Instagram, awaiting authorisation
import requests

url = "https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels"

payload = { "type": "instagram" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Instagram, awaiting authorisation
const url = 'https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"type":"instagram"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Instagram, awaiting authorisation
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels"

	payload := strings.NewReader("{\n  \"type\": \"instagram\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Instagram, awaiting authorisation
require 'uri'
require 'net/http'

url = URI("https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"type\": \"instagram\"\n}"

response = http.request(request)
puts response.read_body
```

```java Instagram, awaiting authorisation
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"type\": \"instagram\"\n}")
  .asString();
```

```php Instagram, awaiting authorisation
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels', [
  'body' => '{
  "type": "instagram"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Instagram, awaiting authorisation
using RestSharp;

var client = new RestClient("https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"type\": \"instagram\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Instagram, awaiting authorisation
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["type": "instagram"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```