Find the one footer template every page includes, paste the script tag before the closing body tag, allow the crawler in robots.txt, crawl your content, and test on staging first. The install is ten minutes. Preparing what the bot answers from takes the afternoon.

This is the whole job, in the order you should do it, written for whoever maintains the site rather than for whoever built it. Nothing here runs server-side, so none of it touches your PHP.
Step 1: find the file that ends every page
You need the single template that emits </body> on every public page. On most PHP sites it is one of these:
application/views/templates/footer.php CodeIgniter
resources/views/layouts/app.blade.php Laravel
wp-content/themes/<your-theme>/footer.php WordPress
includes/footer.php hand-rolled includes
If you are not sure, search the codebase:
grep -rn "</body>" --include="*.php" . | sort | uniq
One or two hits is a healthy site. Fifteen hits means fifteen pages each close their own body tag, and you have a decision to make: paste into all fifteen, or consolidate them into one include first. Consolidating is better and it is a bigger job than this install, so pasting fifteen times is a defensible choice if you write down where they are.
Check for landing pages outside the framework too. A campaign page dropped into the web root two years ago will not include your footer template, and it will be the page you forget.
Step 2: paste the tag
Copy the snippet from your Chatterbox Install page. It carries your public key and looks like this:
<script src="chatterbox.js" data-key="pk_live_8f3a…"></script>
<?php // immediately before </body> ?>
</body>
Put it before </body>, not in <head>. The widget is under 15KB and loads after your page, which is the behavior you want on a mid-range Android phone.
The key in that tag is a public key. It is designed to be readable by anyone who views source, the same way an analytics ID or a Razorpay key ID is. Do not go looking for a way to hide it, and do not put anything that is secret next to it.
Step 3: let the crawler in
The crawler obeys robots.txt. Old sites often carry a blanket disallow from a staging phase that nobody removed, and it will stop the crawl before it starts. Add:
User-agent: ChatterboxBot
Allow: /
Then check what your host does. Some shared-hosting stacks and WAF rules block unfamiliar user agents before PHP is reached, which looks identical to an empty site from the outside.
Step 4: give it something to answer from
Crawling the site is the fast path and it is rarely the whole answer. Two things to plan for:
Pages behind a login are invisible to a crawler. If your rate card or service scope lives inside a customer portal, upload that document instead.
The answers your staff give on the phone every week are usually not published anywhere. Type those in as question-and-answer pairs by hand. Twenty of them will do more for answer quality than another fifty crawled pages, and the content checklist is the pass to make first.
Step 5: test before it faces customers
On staging
Deploy to staging and open a page. Three things to confirm in the browser console:
The script loads with a 200 rather than a 403 from your WAF. No Content Security Policy violation. No layout collision, which on older sites usually means a z-index fight with a sticky header or a cookie banner.
If you run a CSP, the widget's origin needs to be allowed in script-src and connect-src. A site with no CSP header needs nothing.
On production
Clear the page cache after deploying. Varnish, a Cloudflare cache rule or a WordPress cache plugin will keep serving the old HTML otherwise, and you will spend twenty minutes debugging a tag that is already correct.
Then ask it five real questions from your own inbox, including one it should not be able to answer. Watch what it does with that one. It should refuse and ask for a phone number rather than produce a plausible figure, and that behavior is the thing worth checking before customers do it for you.
Test on a phone. Most of your traffic is on one.
Step 6: the parts that are yours to keep doing
Update your privacy policy. Visitors type questions and hand over a phone number, and that goes to a third-party service. Say so, in the same paragraph where you already mention analytics. Your DPDP obligations for that contact data do not move because a widget collected it.
Re-crawl after you change the site. A crawled page is a snapshot, and a stale price is worse than a missing one.
Read the conversations monthly. The refusals are the useful part: each one is a question your website does not answer, ranked by how often customers asked it. That list is a content backlog somebody actually wants.
Check where the leads land. Confirm the notification email reaches a person who acts on it, not a info@ alias nobody opens. A captured lead that nobody calls back is worse than no widget, because the customer thinks they have been in touch.