For developers

WidgetChat API and webhooks

The conversations with your website visitors are available to your own software: your CRM, a scenario in an integration builder or a script on your server. Read messages, reply to a visitor and receive events with a key issued in the dashboard. The full method reference is in the documentation.

Updated

What you can do

  • Read conversations The site's conversations filtered by state and time, one conversation's card and the whole exchange page by page.
  • Reply to a visitor The reply shows up in the chat window on the site exactly like a reply from Telegram and joins the shared history.
  • Close a conversation The conversation is marked closed, and the visitor's next message starts a new one.
  • Fetch an attachment Visitor files are downloaded with the key, and events carry a temporary signed link that another server can open without our key.
  • Receive events A new conversation, a new message and a closed conversation are pushed to your address.

The access key

The key is issued in the dashboard for one site, in the API and webhooks section of the connection card. The value is shown once: we keep only its fingerprint. A lost key is revoked and issued again.

The key is a server key. It must not go into your page code: any visitor would read it there and get access to every conversation.

curl https://api.widgetchat.ru/api/v1/conversations \
  -H "Authorization: Bearer wck_your_key"

Replying to a visitor

Sending again with the same Idempotency-Key header does not create a second reply. The connection can drop after the request was already accepted, and a retry without that key would double the message in the conversation.

curl -X POST https://api.widgetchat.ru/api/v1/conversations/<id>/messages \
  -H "Authorization: Bearer wck_your_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reply-4417" \
  -d '{"content": "Your order is on the way, delivery tomorrow before 2 pm"}'

Events on your address

The address and the set of events are configured in the dashboard next to the keys. Events: conversation.started, message.created, conversation.closed. The message.created event fires for messages in both directions, so a message carries an origin field: it shows that the reply came from your own program and does not have to be sent again.

A 2xx answer means accepted. A 4xx is not retried. On a dropped connection, a 5xx, or if your endpoint stays silent for more than 20 seconds, we try again: three attempts in total, with pauses of 5 and 10 seconds. Every attempt is visible in the delivery log in the dashboard, which keeps 30 days.

POST /your-handler HTTP/1.1
Content-Type: application/json
X-WidgetChat-Event: message.created
X-WidgetChat-Delivery: message.created:8f1c…
X-WidgetChat-Attempt: 1
X-WidgetChat-Timestamp: 1755878400
X-WidgetChat-Signature: sha256=6b2f…

{"id":"message.created:8f1c…","event":"message.created","createdAt":"2026-08-22T12:00:00Z",
 "workspaceKey":"example-ru","data":{"conversation":{…},"message":{…}}}

Checking the signature

What is signed is not the body alone but the timestamp and the body joined by a dot. A signature over a bare body could be replayed a day later and the handler would not tell the replay from a fresh event. The timestamp inside the signature makes such a replay visible.

Check three things: the signature matches, the timestamp is no more than five minutes away from your clock, and the delivery id from the X-WidgetChat-Delivery header has not been seen before. A retry arrives with the same id, so an event already taken into work is dropped by it.

# Go
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(timestampHeader + "." + string(body)))
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))

The signing secret is shown once when the address is created. If you lose it, replace it with the button in the dashboard and put the new one into your handler.

Limits and rules

  • HTTPS only Both for API requests and for the address events are sent to.
  • 300 requests per minute per key Above the limit the answer is 429 with a Retry-After header.
  • One response envelope A successful answer carries a data field, a failure carries an error field with a code and an explanation.
  • Sites are isolated A key opens the conversations of the site it was issued for. A neighbouring site's conversation is not found with it.

Frequently asked questions

Where do I get the access key?

In the dashboard, in the connected site's card, the API and webhooks section. The key is shown once when created.

How is a webhook different from polling the API?

A webhook arrives by itself at the moment of the event; polling means asking us on a schedule. For a CRM and notifications take webhooks, for exporting history take ordinary requests.

What if my server did not answer?

We make two more attempts, after 5 and after 10 seconds. If they fail too, the attempts stay in the delivery log in the dashboard with the response code and the error text.

Can I connect WidgetChat to my CRM?

Yes, through this API: conversations are read with requests, replies are sent with a request, and events arrive on your address. Bitrix24 and RetailCRM have ready connections that need no code.

Are Telegram replies visible through the API?

Yes. The API works with the conversations from the chat window on the site, and agent replies from Telegram are part of the same conversation.

Read next

Add the chat to your website

Sign up with email or Telegram, set it up in the dashboard, paste one line of code. Free.