Quickstart

Pre-release v1, published 2026-09-14. This page commits to the shape of the API, not to a date. We will build exactly what is documented here. The shape can still change until 2026-10-14; after that, changes follow Versioning and stability.

The banner comes off one page at a time as each route goes live. While it is here, build against the contract and assume the route is not callable yet.

Before you start

API access comes with a plan. You need Commercial, Professional, or the Instagram API plan. See pricing.

With one of those active, set up the rest at chat.parstechai.com:

API keyCopy it from your panel
Webhook URLYour HTTPS endpoint. You set it in the panel
Return URLGive it to your ParsChat contact before your first Instagram connection

Creating and deleting robots, and connecting an Instagram service, are partner operations. If you need them, contact sales.

The one thing to know first

A service always belongs to a robot. You cannot connect an Instagram page on its own. Create the robot, then attach the service to it.

1

Create a robot

A workspace that holds conversations, automation rules and training data.

2

Connect a service to it

For Instagram this starts a browser handshake. The page owner authorises it themselves.

3

Receive events

Every message, state change and reaction arrives on your webhook.

If you manage many end customers, create one robot per customer. That is what keeps one customer’s conversations out of another’s.

1. Create a robot

curl -X POST https://api-chat.parstechai.com/v1/robots \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Rose Flower Shop",
"external_id": "shop_10422"
}'
Response
{
"id": "rbt_8fK2mQ",
"name": "Rose Flower Shop",
"external_id": "shop_10422",
"channels": [],
"created_at": "2026-09-20T11:04:33Z"
}

external_id is yours. Put your own customer id in it and we return it on every event, so you never need a lookup table.

Each robot consumes one unit of your plan’s capacity. When it runs out you get 403 capacity_exhausted. Deleting a robot frees capacity immediately.

2. Start the service connection

curl -X POST https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "type": "instagram" }'
Response
{
"id": "chn_3pQ7xL",
"type": "instagram",
"robot_id": "rbt_8fK2mQ",
"status": "pending_authorisation",
"authorisation_url": "https://api-chat.parstechai.com/v1/connect/ig/svc_4dR8nW",
"expires_at": "2026-09-20T12:04:33Z"
}

This does not connect anything yet. Instagram requires the page owner to authorise in their own browser. Send them to authorisation_url. The channel activates when they finish.

Read Connect Instagram before you build this flow. There is a redirect back to your panel that has to be configured first.

3. Confirm the service is live

curl https://api-chat.parstechai.com/v1/robots/rbt_8fK2mQ/channels \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx"
Response
{
"data": [
{
"id": "chn_3pQ7xL",
"type": "instagram",
"robot_id": "rbt_8fK2mQ",
"username": "rose.flower.shop",
"is_active": true,
"connected_at": "2026-09-20T11:06:10Z"
}
]
}

4. Verify your first event

Events arrive at the webhook URL you set in your panel. Verify the signature before you trust a payload.

Event
{
"schema_version": "1.0.0",
"event": "message",
"delivery_id": "dlv_9fK2mQ",
"occurred_at": "2026-09-20T11:09:02Z",
"robot_id": "rbt_8fK2mQ",
"external_id": "shop_10422",
"channel_id": "chn_3pQ7xL",
"data": {
"conversation_id": "cnv_4dR8nW",
"message_id": "msg_1aB2cD",
"source": "direct",
"role": "client",
"type": "text",
"text": "Hi, do you have these roses in stock?",
"attachments": [],
"sender": { "id": "iguser_88213", "username": "sara.k" },
"created_at": "2026-09-20T11:09:02Z"
}
}

The signature arrives in X-ParsChat-Signature as the hex HMAC-SHA256 of the raw request body, keyed with your secret.

import hashlib
import hmac
def is_authentic(raw_body: bytes, header_signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header_signature)

Verify against the raw bytes, before any JSON parsing. Re-serialising the payload changes key order and whitespace, and the signature will never match.

Reply 2xx as soon as you have stored the event. Anything else, including a timeout, is retried. See Webhook events.

Common errors

StatusMeaning
401Key is wrong, revoked, or expired
403Missing role, plan inactive, or capacity exhausted
404No such resource, or not yours
409Duplicate external_id, or service type already present
422Validation failed
429Rate limited. Honour Retry-After

Every code is listed in Errors.

Next