Install Web Chat on Your Website
Web chat adds a chat button to your website. Visitors click it and chat with your AI assistant, and your team replies from Teambox when needed. This guide takes you from an empty dashboard to a working chat on your site.
Steps 1 to 5 need no coding skills. The sections after them are for whoever looks after your website’s code.
Early access
What web chat is
- A chat button sits in a bottom corner of every page. It opens a chat window.
- Your AI assistant answers first, if you add one. Without one, your team answers every chat.
- Every chat shows up in Teambox, next to your WhatsApp, Instagram and Messenger chats.
- The chat only loads on the websites you list.
- Visitors don’t need an account. They can share their details or verify their email or WhatsApp number when you ask for it.
Before you start
- A Sendiee plan that includes web chat. How many web chats you can create depends on your plan.
- A way to edit your website, or the person who does it for you.
- Your website must use
https://. The chat window does not open onhttp://pages.
Step 1: Create a web chat
A web chat is one chat widget. Most businesses need one. Create more if you run several brands or websites that need a different look or team.
- In your Sendiee dashboard, open the menu and choose Channels → Web chat.
- Click Create web chat.
- Name and website. Give the channel a name. Only your team sees it. Add the website where the chat will run. You can also pick the team that gets new chats.
- Look. Pick your brand colour, the theme (Light, Dark or Match device), the side of the screen for the chat button, and a greeting.
- Install. Copy your snippet. Step 3 explains where to paste it.
You can change all of this later. The channel’s Appearance tab also has your logo, display name, tagline, the button’s label and position, and the Show on phones switch.
Step 2: Choose the allowed websites
The chat window only opens on the websites in your list. Other websites can’t show your chat, even if they copy your snippet. You manage the list in the channel’s Install tab, under Allowed websites.
- Enter the website’s address only, like
shop.example.com. If you paste a full link, thehttps://, the path and any port are removed. example.comandwww.example.comare different websites. If your site opens on both, add both.*.example.comcovers every subdomain, such aswww.example.comandshop.example.com. It does not coverexample.comitself, so add that separately.- You can add up to 20 websites to one channel.
- IP addresses and
localhostcan’t be added. - Pages must use
https://on the normal port. A page onhttp://, or with a port in its address such as:8080, can’t open the chat window. - Testing on a staging site or a website builder’s preview address? Add that address too.
Step 3: Add the snippet to your website
Your snippet is one line of code. Copy it from the channel’s Install tab. It looks like this, with your own channel key in place of wc_…:
<script src="https://cdn.sendiee.com/chat.v1.js" data-channel="wc_…" async></script>Paste it once, in a place that appears on every page, just before the closing </body> tag. Then the chat shows on every page. Don’t add it to each page separately.
The channel key is public
wc_… key is meant to be on your pages, so it is safe to publish. The allowed websites list is what stops other sites from using it.Plain HTML
- Open the file every page shares. It is often called the layout, footer or base template.
- Paste the snippet just before
</body>. - Publish your site, then open it in your browser.
WordPress
- Install a plugin that adds code to the header and footer of every page. Any header and footer code plugin works.
- Paste the snippet in the plugin’s site-wide footer box and save. Use the footer for the whole site, not for a single page.
- Clear your cache, then open your site. Cache plugins and some hosts can hide the chat until the cache refreshes.
Google Tag Manager
- In your Google Tag Manager container, create a new tag of type Custom HTML.
- Paste the snippet and set the trigger to All Pages. Name the tag something your team will recognise, like “Sendiee web chat”.
- Submit and publish the container. Preview mode alone does not put the chat live.
Shopify
- In your Shopify admin, go to Online Store, then Themes.
- On your live theme, open the ⋯ menu and choose Edit code.
- Open
layout/theme.liquid, paste the snippet just before</body>and click Save. - Open your store. The chat shows on every page that uses your theme.
Add your store’s domain to the allowed websites. If you also view the store on its .myshopify.com address, add that too. Shopify’s checkout pages don’t load theme code, so the chat doesn’t show on checkout. If you change to a new theme later, paste the snippet into the new theme as well.
Webflow, Wix, Squarespace and other website builders
Most website builders let you add code that runs on every page. The setting is usually called custom code, code injection or footer code.
- Find that setting in your site’s settings. Check your builder’s help pages if you can’t find it.
- Paste the snippet in the area for the footer, or the end of the body, and apply it to all pages.
- Publish your site.
Some builders only allow custom code on paid plans or on sites with your own domain. If you view your site on the builder’s own preview address, add that address to your allowed websites.
Step 4: Check it’s installed
- Open the channel’s Install tab. The Install check card says it is listening for your site.
- Open any page of your website in a new browser tab.
- Back in the dashboard, the card turns green and says Found on your website once the chat loads there.
The check listens for 2 minutes. If it stops, click Check again. It only counts pages on your allowed websites. The Overview tab shows when the chat was last seen under Setup health. Developers can read the same from the API, in install.lastSeenHost and install.lastSeenAt on GET /v2.0/web-chat/channels.
Not turning green? See Troubleshooting.
Step 5: Add an AI assistant and a team (optional)
- AI assistant. Create an assistant on the AI assistants page, choose Web chat as its platform and pick this channel. It then answers visitors first. Without an assistant, your team answers every chat in Teambox.
- Team. In the channel’s Behaviour tab, pick the team that gets new chats from this channel when your routing rules don’t place them.
Control the chat from your page
For developers. The snippet adds a Sendiee function to your pages. Use it to open the chat from your own button, sign customers in and out, and handle cookie consent.
| Call | What it does |
|---|---|
Sendiee('open') | Opens the chat window. Works on phones even when Show on phones is off. |
Sendiee('close') | Closes the chat window. |
Sendiee('toggle') | Opens the chat window if it is closed, closes it if it is open. |
Sendiee('identify', { userId, expiresAt, hash, email, name, phone }) | Tells the chat who a signed-in customer is. userId and hash are required, and expiresAt is recommended. See Signed-in customers. |
Sendiee('logout') | Forgets the signed-in customer on this browser. Call it when they sign out of your site. |
Sendiee('consent', false) | Stops live visitor tracking on this browser until Sendiee('consent', true). See Cookie banners and consent. |
Sendiee('consent', true) | Starts live visitor tracking again. |
The snippet loads in the background, so your own code may run before the chat is ready. Add this line once, before your first Sendiee(…) call. Calls made before the chat is ready then wait and run once it is.
<script>window.Sendiee=window.Sendiee||function(){(Sendiee.q=Sendiee.q||[]).push(arguments)}</script>Example: your own “Chat with us” button.
<script>window.Sendiee=window.Sendiee||function(){(Sendiee.q=Sendiee.q||[]).push(arguments)}</script>
<script src="https://cdn.sendiee.com/chat.v1.js" data-channel="wc_…" async></script>
<button type="button" onclick="Sendiee('open')">Chat with us</button>- Unknown commands and invalid arguments are ignored. Nothing is thrown into your page.
- If the chat does not load, for example because the channel is paused, waiting calls are dropped.
- Adding the snippet twice does nothing extra. The second copy is ignored.
Signed-in customers
For developers. If customers log in to your website, the chat can know who they are. They skip the pre-chat form and verification, their chat is marked as verified in Teambox, and they see their past chats on any device where they are signed in.
Your server proves who the customer is with a secret only it knows. The page passes that proof to the chat.
1. Create the secret
- In the dashboard, open the channel and go to Pre-chat and verification → Signed-in customers.
- Click Create secret. It starts with
wcs_. Copy it now. It is shown only once. - Store it on your server, for example in an environment variable named
SENDIEE_WEB_CHAT_SECRET.
Keep the secret on your server
2. Sign the customer’s id and an expiry on your server
Pick an expiry time, expiresAt, as Unix time in seconds. One hour from now is a good default. Then make the hash: the HMAC-SHA256 of the customer’s id and expiresAt joined by a colon, for example 12345:1767225600, using your secret as the key, written as a 64-character hex string. Use a stable id that never changes for that customer, such as the id in your database.
Make a new expiresAt and hash each time your server renders a page for a signed-in customer.
const crypto = require('crypto');
// customer = the signed-in customer from your session
const userId = String(customer.id); // must be a string
const expiresAt = Math.floor(Date.now() / 1000) + 3600; // 1 hour, in seconds
const hash = crypto
.createHmac('sha256', process.env.SENDIEE_WEB_CHAT_SECRET)
.update(`${userId}:${expiresAt}`)
.digest('hex');
// Pass userId, expiresAt and hash to your page templateWhy the expiry matters
3. Call identify on the page
On every page where the customer is signed in, after the snippet, call identify with the same id and expiry you signed and the hash from your server. Calling it on every page view is fine. If the same customer is already signed in to the chat on that browser, the chat does not sign them in again.
<script>window.Sendiee=window.Sendiee||function(){(Sendiee.q=Sendiee.q||[]).push(arguments)}</script>
<script src="https://cdn.sendiee.com/chat.v1.js" data-channel="wc_…" async></script>
<script>
Sendiee('identify', {
userId: '12345', // the same id you signed, as text
expiresAt: 1767225600, // the same expiry you signed, as a number
hash: '<hash from your server>', // 64-character hex, made in step 2
email: '[email protected]', // optional
name: 'Ananya Rao', // optional
phone: '+91 98765 43210', // optional
});
</script>userIdmust be text, exactly the text you signed. A number is ignored, so useString(id). Up to 200 characters.expiresAtmust be a number, not text, in seconds, not milliseconds. It can be at most 30 days ahead. After it passes, with one minute of grace for clock differences, that hash no longer signs anyone in.- The expiry only limits when the hash can be used. A customer who is already signed in stays signed in to the chat after it passes.
- If your site caches whole pages, for example on a CDN, don’t cache pages for signed-in customers. A cached page keeps an old
expiresAt, and sign-in stops working once it passes. - Only the id is proven by the hash. The
email,nameandphoneyou pass are saved as details the customer gave, not as verified details. - When the customer signs out of your site, call
Sendiee('logout'). The next person on that browser then starts a fresh chat. - If a different person was verified in the chat on that browser, the chat signs them out first, so two people’s chats never mix.
4. Require an expiry
Once every page sends expiresAt, open Pre-chat and verification → Signed-in customers and turn on Require an expiry on sign-ins. From then on, a sign-in without expiresAt is refused, so an old hash without an expiry can’t be used either. The switch needs a secret, and it stays on when you rotate the secret.
Update your server first
expiresAt on every page. Until then, customers whose pages use the older form are no longer recognised and see the pre-chat form and verification instead.Older form without an expiry (still works)
Sites set up before the expiry was added sign the id alone, and call identify without expiresAt. This keeps working while Require an expiry on sign-ins is off. We recommend moving to the form above. Customers who are already signed in stay signed in when you switch.
// Older form: hash = HMAC-SHA256(secret, userId), no expiresAt
const userId = String(customer.id);
const hash = crypto
.createHmac('sha256', process.env.SENDIEE_WEB_CHAT_SECRET)
.update(userId)
.digest('hex');
// On the page: Sendiee('identify', { userId, hash })Cookie banners and consent
So your team can see who is on your site right now (see Live visitors), the chat script sends a small signal from each open page: the page address and title, how the visitor found you, and a visit count. It keeps a few small values for this in your site’s local storage, such as a browser id and the visit count. The script does not set cookies on your website.
If your site asks visitors for consent first:
- Call
Sendiee('consent', false)until the visitor agrees. Tracking stops, the stored values are removed, and the choice is kept on that browser across pages until you callSendiee('consent', true). - Call
Sendiee('consent', true)when they agree. Tracking starts again straight away.
<script>window.Sendiee=window.Sendiee||function(){(Sendiee.q=Sendiee.q||[]).push(arguments)}</script>
<script>
// Before the chat script runs, pass the visitor's current choice.
// visitorHasConsented() is your cookie banner's check. It must return true or false.
Sendiee('consent', visitorHasConsented());
</script>
<script src="https://cdn.sendiee.com/chat.v1.js" data-channel="wc_…" async></script>
<script>
// In your cookie banner's "Accept" handler
function onCookiesAccepted() {
Sendiee('consent', true);
}
</script>- Consent only controls live visitor tracking. The chat button and the chat itself keep working.
- When a visitor starts a chat, the chat keeps a session token in local storage so the conversation carries on across pages.
- To turn tracking off for everyone, switch off Track live visitors in the channel’s Overview tab.
Business hours and away message
Set these in the channel’s Behaviour tab.
- Business hours. Switch it on, pick your time zone, and set the days and times you are open. New channels start with Monday to Saturday, 10:00 to 19:00, and Sunday closed. With business hours off, the chat is always open.
- Outside your hours, the chat shows Away and the day and time you open next.
- While you’re closed, choose one:
- Your assistant keeps answering (the default). The away message, if you write one, shows above the assistant’s replies.
- Away message only. Visitors can still write. Their messages are saved for your team, the assistant does not reply, and the away message is sent once per chat while you are closed.
- The away message can be up to 300 characters.
- If the channel has no active assistant, visitors see your away message while you are closed and no AI help is offered.
Pre-chat form and verification
Set these in the channel’s Pre-chat and verification tab.
Pre-chat form
- When to show it: Off (visitors start chatting right away), Before the first message, or When needed (only when the chat needs contact details).
- Fields: Name and Email (required) and Phone (optional) to start with. You can add your own contact fields, rename fields and choose which are required. Up to 8 fields.
- You can add consent text and a link to your privacy policy under the form.
- Details typed in the form show as not verified until the visitor confirms them.
Verification
- When to verify: Never, Before chat, or When needed (recommended: asked only when it matters, like order details).
- Email code: the visitor gets a 6-digit code by email and types it in the chat.
- Verify with WhatsApp: the visitor sends a short message with a code to your WhatsApp number from their own WhatsApp. This needs a WhatsApp number connected to Sendiee.
- Verified visitors are marked verified in Teambox, see their past chats on another device after verifying again, and are joined to an existing contact with the same email or phone number.
Notification sounds
In the Appearance tab, under Sound for new replies, pick Soft chime (the default), Bubble pop, Glass ping, Marimba, Pluck, Bell, Digital, Drop, or No sound.
- The sound plays in the visitor’s browser when a reply from your assistant or team arrives while the chat is closed or the tab is in the background.
- Browsers only allow sound after the visitor has clicked or typed on the page.
- Visitors can mute it from the chat’s menu.
Rating, “Email me this chat” and email replies
Set these in the channel’s Behaviour tab.
- Chat rating (on by default). When your team marks a chat as resolved in Teambox, the visitor is asked for 1 to 5 stars and an optional comment. Your team sees the rating in Teambox, and the average shows on the Overview tab.
- Offer Email me this chat. After rating, visitors who verified their email can get a copy of the chat by email, up to 3 times a day. Signed-in customers get this button only if they also verified their email in the chat.
- Email replies to visitors who left. If a visitor with a verified email closes the page before your team replies, the reply is sent to their email with a button to continue the chat on your website.
Live visitors and Start chat
The channel’s Overview tab lists who is on your website right now: the page they are on, time on site, country, device, where they came from, and how many visits they have made. Names appear once a visitor shares or verifies them. A label shows if they are already chatting with your assistant or your team. City and IP address are never shown.
Click Start chat next to a visitor to send them a message first:
- On a computer, the chat window opens with your message. On a phone, it shows as a small message bubble next to the chat button.
- The message can be up to 1,000 characters and goes out under your name.
- You can start a chat with the same visitor once every 30 minutes, and not while they are already chatting with someone on your team.
- When the visitor replies, the chat is assigned to you if nobody has it yet.
Live visitors and Start chat are also in Teambox, for admins and for agents whose role has the Access web chat permission. Developers can read the list from GET /v2.0/web-chat/channels/{channelId}/live-visitors.
When your team replies, the AI can step back
Security
Set these in the channel’s Security and Install tabs.
- Allowed websites. The chat window only opens inside pages on your allowed websites. Other websites can’t show your chat.
- Protection level: Normal (recommended). A quick bot check runs once, when a visitor starts a chat. Most visitors never see it. Messages then send straight away, with standard limits on how much one visitor can send.
- Protection level: Strict. The bot check runs on every message, and each visitor can send about half as many messages and codes. It stops more spam, but real visitors wait a moment longer for each message to send.
- Files visitors can send. Choose from images (JPG, PNG, WEBP, GIF), PDF, Office files (Word, Excel, PowerPoint) and text files (TXT, CSV), and set the largest file size. SVG and HTML files are always blocked. Turn every type off to stop file uploads.
- Pause hides the chat from your website at once. Past chats stay in Teambox. Delete frees the channel on your plan and can’t be undone.
Troubleshooting
The chat button doesn’t show
- The channel is paused. The Install tab says so. Resume it from the Security tab.
- The snippet is not on that page. Open the page, view its source, and search for
chat.v1.js. If you added it to one page only, move it to a place every page shares. - A cache still serves the old page. Clear your website, plugin and CDN caches.
- A plugin that combines, minifies or delays JavaScript changed the snippet. Exclude
chat.v1.jsfrom it. - On phones only: Show on phones is off in the Appearance tab.
- Your website’s Content Security Policy blocks the script. See below.
- Your plan no longer includes web chat.
The button shows, but the chat window is blank or refuses to connect
- The website is not in Allowed websites. Check
wwwagainst nowww, and subdomains. Remember that*.example.comdoes not coverexample.com. - The page uses
http://or has a port in its address. Open it onhttps://. - Your Content Security Policy does not allow the chat window. See below.
The install check keeps listening
- Open a page on one of your allowed websites, on
https://, while the check is listening. Pages on other addresses are not counted. - Make sure the chat button shows on that page. If it doesn’t, start with the first list.
- Check the Overview tab’s Setup health for the last time the chat was seen.
Signed-in customers still see the pre-chat form
- The channel has no secret yet, or the secret was rotated and your server still uses the old one.
userIdon the page is a number, or is not exactly the text your server signed.- The hash is not 64 hex characters, or was made with SHA-1 or MD5 instead of HMAC-SHA256.
- The page sends
expiresAtbut the hash was made from the id alone, or the other way round. With an expiry, signuserId:expiresAt. expiresAtis in milliseconds (Date.now()without dividing by 1000), is text such as"1767225600", or is more than 30 days ahead.expiresAthas passed: the page was cached, or your server’s clock is wrong.- Require an expiry on sign-ins is on and the page still uses the older form without
expiresAt. identifyruns before the chat is ready and the waiting line from Control the chat from your page is missing.
In your browser’s developer tools, the identify request to chat.sendiee.com answers with one of these codes:
| Code | What it means |
|---|---|
IDENTITY_INVALID | The hash does not match. Check the secret, the id and what you signed. |
IDENTITY_EXPIRED | The hash is right but expiresAt has passed. Sign a new one when the page is rendered. |
IDENTITY_EXPIRY_REQUIRED | Require an expiry on sign-ins is on and the call has no expiresAt. |
BAD_REQUEST | expiresAt is not whole seconds as a number, or is more than 30 days ahead. |
IDENTITY_DISABLED | The channel has no secret yet. |
Content Security Policy
If your website sends a Content-Security-Policy, add these sources to the directives you already have. Don’t replace your existing values.
Content-Security-Policy:
script-src https://cdn.sendiee.com;
frame-src https://chat.sendiee.com;
connect-src https://chat.sendiee.com;
style-src 'unsafe-inline'script-srcloads the chat script.frame-srcopens the chat window. If your policy useschild-srcinstead, add it there.connect-srcloads the chat button’s settings and sends the live visitor signal.style-src 'unsafe-inline'is needed only if your policy limits styles. The chat button draws itself with a small block of styles.
FAQ
Will the chat slow down my website?
The script is small and loads in the background, so your page does not wait for it. The chat window loads when a visitor opens it. For a visitor who has chatted before, it loads quietly once the page is idle, so new replies can show a badge on the button.
Can I use one channel on several websites?
Yes. Add up to 20 websites to its allowed list. If your websites need a different look, team or assistant, create a channel for each.
Does web chat work without an AI assistant?
Yes. Your team answers every chat from Teambox.
Where do the chats go?
To Teambox, with your other channels. Each visitor who chats is saved as a contact. Until they share a name, they show as “Visitor” followed by a short code.
What do visitors see on a phone?
The chat opens full screen on small screens. You can hide the chat button on phones with Show on phones, and still open the chat from your own button with Sendiee('open').
Can I open the chat from my own button or link?
Yes. Call Sendiee('open'). See Control the chat from your page.
What do you store about visitors?
The messages, the page they chatted from, how they found your site, their browser, language and country, and any details they share or verify. Raw IP addresses are not stored, and live visitors show the country only, never the city.
Can I work with web chat from my own system?
Yes. The web chat API lists your channels, reads the stats and live visitors, and sends messages to visitors.