Home Integrations and API Kulpunai widget inside your CRM

Kulpunai widget inside your CRM

Last updated on October 01, 2026

Kulpunai widget inside your CRM

The embeddable widget adds a floating button to the pages of your CRM. Clicking it opens a panel with Kulpunai conversations: the list, the chat, replies, canned responses and attachments work exactly as in the main app. Agents stop switching tabs, and the CRM can open the right conversation straight from a lead card.

It works with any CRM that lets you add one script tag: Bitrix24, amoCRM or an in-house system.

What you need

  • Administrator role in Kulpunai;
  • The CRM domain that will host the widget, served over HTTPS;
  • A way to add a script to the CRM page template.

Step 1. Allow the domains

  1. Open Settings → Integrations → Embeddable widget.
  2. Under Allowed domains enter the CRM domain and click Add. Examples: crm.example.com, https://*.bitrix24.ru, localhost:3001 for a local check.
  3. Click Save.

While the list is empty the widget stays disabled: the browser will not open the panel on any site. A star allows every subdomain; a port goes after a colon.

Step 2. Paste the install code

Under Install code click Copy code and paste the snippet before the closing </body> tag of every CRM page that should show the widget. The code already contains the platform address and your account number:

<script>
  (function (d, t) {
    var g = d.createElement(t), s = d.getElementsByTagName(t)[0];
    g.src = 'https://online.kulpunai.com/packs/js/embed.js';
    g.async = true;
    s.parentNode.insertBefore(g, s);
    g.onload = function () {
      window.kulpunaiEmbed.run({ baseUrl: 'https://online.kulpunai.com', accountId: 123 });
    };
  })(document, 'script');
</script>

After the page loads, a button appears in the bottom-right corner. A click opens the panel; another click, or the minimize button in the panel header, hides it.

Step 3. Sign in inside the panel

On first open the panel shows the Kulpunai login form. There are three ways to sign in:

  • Email and password of the agent, as in the main app;
  • The "Continue with your open Kulpunai session" button — if the agent is already signed in to Kulpunai in another tab, a small window passes the session into the panel and closes itself;
  • Automatically in Chrome with default settings: the panel sees the open session and signs in without a click.

Google and SSO sign-in are not available inside the panel: browsers do not allow those windows in embedded pages. If the browser blocks storage for embedded pages (for example Chrome Incognito), the panel shows a message with a link to open Kulpunai in a new tab.

Open a conversation from a lead card

The widget accepts commands from the CRM page. To open a specific conversation on click, call:

window.kulpunaiEmbed.openConversation(4821);

The number is the conversation number, the same one shown in the chat URL in Kulpunai. The panel opens by itself; if the agent has not signed in yet, the command runs right after sign-in.

Available calls and events:

  • kulpunaiEmbed.open(), close(), toggle() — control the panel;
  • kulpunaiEmbed.openConversation(id) — open a conversation;
  • kulpunaiEmbed.on('ready', fn) — the agent is signed in and the panel is ready;
  • kulpunaiEmbed.on('unread', fn) — the unread count changed, fn receives { count };
  • kulpunaiEmbed.on('conversation:opened', fn) — a conversation opened, fn receives { conversationId };
  • kulpunaiEmbed.on('auth:required', fn) — the panel is showing the login form.

Where the CRM gets the conversation number

Through a webhook. In Settings → Integrations → Webhooks subscribe your backend to the conversation_created event. The request carries the conversation number in id and the contact in meta.sender with phone, name and email. Store the number on the lead and pass it to openConversation. See the "Webhooks" article.

Through the API. If the lead was created before the customer wrote, the CRM backend finds the conversation by phone with two requests using an agent access token (see "API and access token"):

GET /api/v1/accounts/123/contacts/search?q=%2B996555123456
GET /api/v1/accounts/123/contacts/917/conversations

The first request returns the contact, the second its conversations; take the id of the most recent one.

For Bitrix24 nothing extra is needed: the integration already writes the conversation number and link into the lead timeline.

A lead link inside the panel

To let the agent see the CRM card from the chat, store its address in the Kulpunai contact attributes:

PATCH /api/v1/accounts/123/contacts/917
{ "custom_attributes": { "crm_lead_url": "https://crm.example.com/leads/4821" } }

Create the crm_lead_url attribute in Settings → Custom attributes with the "link" type, and it appears in the contact side panel.

Keeping the assignee in sync

Assignment works in both directions without any widget changes.

From Kulpunai to the CRM. Subscribe your backend to the conversation_updated event in Settings → Integrations → Webhooks. It fires on every agent or team change, including auto-assignment. The current agent is in meta.assignee, the team in meta.team:

{
  "event": "conversation_updated",
  "id": 4821,
  "status": "open",
  "meta": {
    "assignee": { "id": 7, "name": "Aigul", "availability_status": "online" },
    "assignee_type": "User",
    "team": { "id": 2, "name": "Sales" }
  }
}

An empty meta.assignee means the conversation is unassigned. The event does not carry the agent's email: map id to your CRM user with GET /api/v1/accounts/123/agents, which returns id, name and email. The event also fires on other conversation changes (status, labels, priority), so compare the agent with the stored one and react only to a real change.

From the CRM to Kulpunai. To assign or reassign an agent, send a request with an access token:

POST /api/v1/accounts/123/conversations/4821/assignments
{ "assignee_id": 7 }

An empty assignee_id unassigns the conversation. To assign a team, pass team_id instead of assignee_id. The agent must be a member of the conversation's inbox; GET /api/v1/accounts/123/inboxes/<inbox id>/assignable_agents lists who qualifies.

Avoiding a loop. After an assignment from the CRM, Kulpunai sends conversation_updated back. If the agent in the event matches the one the CRM just set, skip the event.

Limitations

  • One snippet serves one Kulpunai account; the agent must be a member of that account;
  • The panel shows the same conversations and permissions as the main app: agents only see what they have access to;
  • In Safari the session inside the panel is dropped after a week without use, and the agent signs in again;
  • On screens narrower than 480 px the panel opens full screen.

Troubleshooting

  • The button does not appear — check that the script loads from online.kulpunai.com and the browser console shows no errors. Make sure the snippet has the right accountId.
  • The panel is blank — the page domain is not in Allowed domains or is misspelled. The domain must match the page that hosts the snippet, including the port.
  • The panel shows a storage-blocked message — the browser forbids embedded pages from storing data. Allow third-party cookies for online.kulpunai.com or open Kulpunai in a new tab using the link in the message.
  • "Continue with your open session" does nothing — the browser blocked the popup. Allow popups for the CRM domain and click again.