> 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 Instagram

> A browser redirect rather than an API call, plus the return URL that sends your customer back to your own panel.

## Why this is not a single API call

An Instagram page cannot be connected with a token you already hold. Meta requires the **page
owner** to authorise it in their own browser. So `POST /v1/robots/{id}/channels` with
`"type": "instagram"` does not connect anything. It **starts a handshake** and returns a URL to
send the page owner to.

```json
{
  "id": "chn_3pQ7xL",
  "type": "instagram",
  "robot_id": "rbt_8fK2mQ",
  "status": "pending_authorisation",
  "authorisation_url": "https://api-chat.parstechai.com/v1/connect/Yk3pQ9vT2mW8xR4nL6cH1sJ7dF0aZ5eU3gB9kP2qV8w",
  "expires_at": "2026-09-20T12:04:33Z"
}
```

Open `authorisation_url` in the page owner's browser. The channel becomes `is_active: true` only
once they finish, and **until then it holds no capacity**.

> **Warning**
>
> **Treat `authorisation_url` as opaque. Redirect to it exactly as returned.** It is not served by
> `api-chat.parstechai.com`, its host and path are not part of this API's contract, and it carries
> state that must survive the round trip. Do not construct it, parse it, rewrite its host, or strip
> its query string.

## Configure your return URL first

> **Warning**
>
> **Tell us your return URL before your first connection.** Without one configured, the handshake
> sends your customer to **our** dashboard: a ParsChat screen they have never seen, mid-signup, on
> a product they believe is yours.
>
> Calling the endpoint without one returns `422 return_url_not_configured`.

| URL             | Purpose                                                    | Who calls it        |
| --------------- | ---------------------------------------------------------- | ------------------- |
| **Webhook URL** | Receives events, server-to-server                          | us → your server    |
| **Return URL**  | Where the page owner's **browser** lands after authorising | browser → your site |

You set the webhook URL yourself in your ParsChat panel. The return URL is the one you give us:
because it is where a person's browser is sent, a writable endpoint would turn a stolen key into an
open-redirect and phishing tool.

> **Info**
>
> **Your return URL must share an origin with your webhook URL**, and must be `https`. This is
> enforced rather than advisory. It is what makes it impossible to bounce a page owner to an
> unrelated site.

## The flow

```mermaid
sequenceDiagram
    participant C as Page owner's browser
    participant P as Your panel
    participant PC as ParsChat
    participant Meta as Instagram

    P->>PC: 1. POST /v1/robots/{id}/channels {"type":"instagram"}
    PC-->>P: 2. authorisation_url
    P->>C: 3. send the owner to authorisation_url
    C->>Meta: 4. the owner authorises the page
    Meta-->>PC: 5. authorisation completed
    PC->>C: 6. redirect to YOUR return_url (service_id + status)
    C->>P: 7. owner lands back on your panel
    P->>PC: 8. GET /v1/robots/{id}/channels to confirm
```

Steps 1–3 are yours. Steps 4–7 happen in the page owner's browser, and you are not involved.
Step 8 is yours again: confirm the channel is live rather than trusting the browser's arrival.

> **Info**
>
> Everything between step 3 and step 6 is handled for you, including the token exchange and the
> event subscription. You never see or store an Instagram token.

### What arrives at your return URL

The browser lands on your page with the `service_id` and a status, as query parameters:

```
https://partner.example/instagram/done?service_id=svc_4dR8nW&status=success
```

Render your own success or failure screen from it. Do not treat the browser's arrival as proof the
channel is live. Confirm with `GET /v1/robots/{robot_id}/channels`.

## Errors

| Status | `code`                      | Meaning                                              |
| ------ | --------------------------- | ---------------------------------------------------- |
| `422`  | `return_url_not_configured` | No return URL configured for you yet. Contact us     |
| `409`  | `handshake_pending`         | An unexpired handshake already exists for this robot |
| `410`  | `handshake_expired`         | The owner took too long; start a new one             |
| `403`  | `channel_not_in_plan`       | Your plan does not include Instagram                 |
| `409`  | `conflict`                  | This robot already has an Instagram channel          |

> **Info**
>
> A handshake expires about an hour after it is started. If your customer abandons the flow and
> comes back later, simply call `POST …/channels` again to get a fresh `authorisation_url`.

## Disconnecting

```bash
curl -X DELETE https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels/chn_3pQ7xL \
  -H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx"
```

`204 No Content`. Capacity is freed immediately. **Conversations and history are not deleted.**
They survive the disconnection and a later reconnection.