Install guide
Install Telltale Bot
Telltale Bot is one tag. You put it on every page of your site, and it tells you whether each visitor is a person, an AI agent acting for a person, or a bot.
You need a login for the Telltale Bot viewer at app.telltale.bot. Each site has its own tag, so install the tag you copy for that site and no other.
1. Copy your tag
- Sign in at app.telltale.bot.
- On Sites, click the gear on your site's card. (Or pick the site and choose Site settings at the top.)
- Open Installation. Above the tag, choose whether it pushes the verdict to your dataLayer (on unless you turn it off) and, if your account has the Member accounts tab, where your site keeps the signed-in member's ID. The tag updates as you choose.
- Click Copy tag.
The tag is filled in for your site. Paste it as it is. Its settings look like this:
var CONFIG = {
script: 'https://js.ttbcdn.net/v2/telltale.js',
server: 'https://in.ttbcdn.net',
path: '/c/YOUR_PATH',
key: 'YOUR_SITE_KEY',
dataLayer: 'dataLayer'
};
The key names your site. Anyone who reads your page can see it, and that is expected: it is not a password. If your login can see all of your account's sites, you may also see + Add a site on Sites. It creates a new site with its own tag.
2. Install it
Use one of the ways below, not two. If the tag runs twice on a page, the first copy does the work and the second does nothing.
Directly in the page (recommended). Paste the tag into the <head> of every page, as high as you can, before other scripts. This measures more visitors: ad and tracker blockers often block Google Tag Manager, and a tag in the page still runs for those visitors. It also starts earlier, so it sees more of the visit.
Through Google Tag Manager. GTM is easier to set up if you already use it.
- Go to Tags, then New, and choose Custom HTML. Paste the whole tag.
- For Triggering, choose Initialization - All Pages. It is the earliest trigger GTM has, and the tag can only see what happens after it loads.
- Under Advanced Settings, set Tag firing options to Once per page.
- Decide whether it waits for consent (see Consent). To run it before consent, set its Consent Settings to No additional consent required. To wait, add the same consent checks your analytics tags use.
- Check it in Preview (step 3), then Submit to publish.
Using GA4 too? Import a container instead. Installation in the viewer offers a GTM container for your site: the tag as a Custom HTML tag, with your site's values and the options you chose there, plus what the GA4 recipe sets up by hand (a trigger on the verdict, a variable for each of its fields and a tag that sends the verdict to GA4). It needs your GA4 Google tag in the same container.
- In GTM, go to Admin, then Import Container. Pick the file and a workspace, then choose Merge, not Overwrite: Overwrite replaces every tag, trigger and variable already in that workspace. Choose Rename conflicting tags, triggers, and variables too, then Confirm. Everything lands in a Telltale Bot folder.
- Open the variable Telltale Bot - GA4 measurement ID and put in your GA4 measurement ID (it starts with
G-). If you already have a variable for it, put yours in place of ours in the code of the Telltale Bot - GA4 verdict event tag and delete ours. - If the container already had our tag, delete one of the two Telltale Bot tags.
- The tag is set to run before consent, as recommended under Consent. The GA4 verdict tag hands its event to your Google tag, which applies GA4's consent settings to it as to your other GA4 events; if you hold your GA4 tags back by giving each one a consent requirement, give this one the same. Change them if your site needs otherwise.
- Register the event's parameters in GA4 (see the GA4 recipe), check it in Preview, then Submit.
Or with our GTM tag template. It is the same tag as a form in GTM, for containers that do not allow Custom HTML tags or teams that prefer templates. Download the template and fill in its fields from your tag.
- Go to Templates. Under Tag Templates, choose New, then the ⋮ menu at the top right, then Import. Pick the file and Save.
- Go to Tags, then New, and choose Telltale Bot. Fill in Path and Site key from your tag's
CONFIG(pathandkey), and the other fields if your tag differs. - Set the trigger, firing options and consent as for the Custom HTML tag above, check it in Preview, then Submit.
The template may only load our script from js.ttbcdn.net. If you set up your own script hostname (custom domain), add the new hostname under the template's Permissions, Injects scripts. Without that, the tag stops and says why in the browser's console during GTM Preview.
For the member ID (see Member accounts), the template reads a cookie or a GTM variable. If your site keeps the ID in JavaScript, make a GTM variable that gives it, a JavaScript Variable or, for anything longer, a Custom JavaScript variable, and choose it under From a GTM variable. The template reads the variable once, when the tag fires, so a member who signs in without the page reloading is counted from their next page. The Custom HTML tag reads the ID at every report.
Through another tag manager. The tag is a single <script> element, so a tag manager that takes HTML (a custom HTML or custom code tag) takes it as it is. One that takes JavaScript only, such as Tealium iQ, takes what is between its two script tags.
- Tealium iQ: add a JavaScript Code extension, paste what is between the tag's two script tags, and set its scope to Pre Loader, the earliest. Then save and publish.
- In any tag manager, run it on every page, as early as it allows. Running twice on a page does no harm.
- The tag pushes the verdict to
window.dataLayer, which Tealium doesn't read. Take it from the page events instead, for example as a Tealium event (and turn the dataLayer push off on Installation if nothing else reads it):
addEventListener('telltale:verdict', function (e) {
if (window.utag && utag.link) utag.link({
tealium_event: 'telltale_verdict',
telltale_actor: e.detail.actor,
telltale_agent_id: e.detail.agentId,
telltale_confidence: e.detail.confidence
});
});
The tag loads its script in the background, after your page. It is built not to slow your page down, it changes nothing visible on it, and it sets no cookies. It lets the browser connect to our server while the script downloads, so the verdict comes sooner on a visitor's first page (see A faster first verdict).
3. Check that it works
- Open a page of your site. In GTM Preview, or in the browser's console by typing
dataLayer, look for an event calledtelltale.verdict. It usually appears within a second of the page loading.Telltale.verdictin the console shows the same verdict. - In the viewer, Site settings, then General, shows Receiving reports once pageviews arrive. Your visits also show on the All traffic tab.
- Having the browser's developer tools open can make your own visit look more like automation. That is expected.
What the tag adds to the dataLayer
When our server answers, the tag pushes the verdict to your page's dataLayer (and fires the page events). To keep it out of your dataLayer, set dataLayer: null in the tag's settings. For a visit from Claude in Chrome, for example:
{
"event": "telltale.verdict",
"telltale": {
"actor": "agentic",
"agentId": "claude-extension",
"confidence": "high",
"declared": false
}
}
There are two events. Each has a dataLayer name for GTM and a matching page event for scripts on the page, and both carry the same fields:
| dataLayer event | Page event | When it comes |
|---|---|---|
telltale.verdict |
telltale:verdict |
Once per pageview, when our server answers: usually well under a second after the page loads. If our server can't be reached, nothing fires. |
telltale.verdict-update |
telltale:verdict-update |
Only when the verdict changes while the visitor is still on the page. AI agents mostly show themselves when they act, so the tag checks again about two seconds after the first click or keypress. Most pages have none. |
The verdict covers the visit so far (one browser tab), not only the current page. By default each event carries four fields:
actor:human,agentic(an AI assistant doing a task one person asked for) orbot(automation running on its own, such as crawlers and scrapers). Automation with no sign of an assistant behind it isbot.agentId: who it is, when we can tell. For exampleclaude-extension,googlebot, orautomated-browserwhen we can tell it is automated but not whose. It ishumanfor people. See which AI agents we recognize.confidence:high,mediumorlow, for the verdict given.declared:truewhen the automation named itself (in its user agent),falsewhen we worked it out. It is left out for people.
Before each event the tag pushes { telltale: null }. That clears the previous values, because GTM merges pushes together.
To act on the verdict in GTM, trigger your tags on the telltale.verdict event, not on the page view. A tag that fires on the page view runs before the verdict is there.
Without GTM: the page events
The tag also tells the page itself, so any script can use the verdict without GTM. It fires telltale:verdict and telltale:verdict-update on window, at the same moments as their dataLayer events (see the table above), with the same fields in event.detail. They fire whether or not the dataLayer push is on.
Telltale.verdict always holds the latest verdict, so a script that starts after the event can still read it:
function useVerdict(v) {
if (v.actor !== 'human') { /* e.g. skip an ad call, flag a form */ }
}
if (window.Telltale && Telltale.verdict) useVerdict(Telltale.verdict);
addEventListener('telltale:verdict', function (e) { useVerdict(e.detail); });
addEventListener('telltale:verdict-update', function (e) { useVerdict(e.detail); });
The names use a colon on purpose: jQuery reads a dot in an event name as a namespace, so $(window).on('telltale:verdict', …) works where a dotted name would not.
More fields: data layer fields
The default is the verdict alone. Every script on the page can read the verdict, so it never carries the evidence behind a verdict or anything that identifies a visitor. You can add more fields in the viewer: Site settings, then Data layer fields. They go with every copy of the verdict: the dataLayer push, the page events and Telltale.verdict.
- Pick a preset (Verdict only, IP enrichment, IP enrichment + location, Device, Everything), or tick fields one by one.
- The fields cover the agent's name (
agentName), the visitor's network (ISP, network type, VPN or proxy), the IP's country, region and city, and the browser, operating system and device. - The page lists every field with an example and shows exactly what your pages will receive.
- Changes apply from the next pageview. You don't need to change the tag.
A field with no value for a visitor is left out. Field names never change once they are offered, so your GTM variables keep working.
Sending the verdict to GA4 and other analytics tools
Recipes for GA4 (with GTM or gtag.js), Plausible, Matomo, Piano Analytics, PostHog, Mixpanel, Amplitude, Segment and other tools are on their own page: Send the verdict to your analytics.
Signed-in members: the Member accounts tab
If your site has member accounts, the tag can send your own ID for the signed-in member. The Member accounts tab then shows, per member, how many pageviews were automated (a member scraping through a paid account) and how many devices and networks used the account at once (account sharing). Turn the tab on under Account settings › Add-ons; the site's Installation page then has an option to set where the tag finds the ID.
- In the tag's settings, set
account. To read the cookie your site keeps the member ID in:account: { cookie: 'memberid' }, with your cookie's name. The cookie must be readable by JavaScript (not HttpOnly). - If the ID is somewhere else, give it directly (
account: window.memberId, or a GTM variable in GTM), or give a function that returns it. - Send an ID, not an email address: up to 128 characters, no spaces. A value with an
@is dropped. If your IDs are email addresses, send a hash of them. - On pages where nobody is signed in, the ID is simply missing; nothing else changes. The tag reads only that one cookie.
The member ID is used only to group pageviews in your reports; it never changes a verdict and never goes to the dataLayer. On the All traffic tab, search account: and the ID to see that member's visitors; Site settings, then Delete, can erase everything stored for a member. Say in your privacy notice that you send your members' IDs to us for security.
Your own hostnames (optional)
The tag can load the script and send reports through hostnames on your own domain instead of ours. It takes two: one for reports, such as tt.example.com, and one for the script, such as tt-cdn.example.com, which our CDN serves.
- In Telltale Bot, open Site settings, then Custom domain, and add both hostnames.
- At your DNS provider, add a
CNAMErecord for each: the reports hostname with the targetin.ttbcdn.net, the script hostname with the targetjs.ttbcdn.net. - When Custom domain shows Ready (we issue the certificates, usually within a few minutes of the records showing up), copy the tag again from Installation. It now uses your hostnames, each as soon as it is ready. The old tag keeps working, so there is no rush.
Important: the records must be DNS CNAMEs to our hostnames only, not a proxy.
Use CNAMEs, not A records with our addresses, as our IPs may change. To stop using a hostname, put the tag back first, then remove the hostname: reports sent to a removed hostname are refused, and a removed script hostname stops serving the script.
A faster first verdict
Before it loads its script, the tag adds this to the page's <head>, with your tag's server as the host:
<link rel="preconnect" href="https://in.ttbcdn.net" crossorigin>
It lets the browser open its connection to our server while the script downloads, so on a visitor's first page the verdict doesn't wait for that connection. It downloads nothing and changes nothing visible on the page. Later pages reuse the connection, so it only speeds up the first one: for visitors in Europe, by up to about a quarter of a second.
- It comes with the tag. There is nothing to add, and it waits with the tag: a consent tool or tag manager that holds the tag back holds it back too.
- Tags copied from October 24 to 26, 2026 have it as a separate line above their script. They work as they are. If you copy the tag again, remove that line.
- The GTM tag template can't make it: GTM templates can only load scripts. With the template, add the line above to your pages'
<head>if you can edit them. If your consent tool holds back scripts in the page itself, hold that line back too: it contacts our server as soon as the page loads.
Content Security Policy
If your site sends a Content Security Policy, allow our two hosts:
script-src https://js.ttbcdn.netfor the script.connect-src https://in.ttbcdn.netfor the reports.
With your own hostnames, allow your script hostname in script-src and your reports hostname in connect-src instead.
With the tag directly in the page and a policy that blocks inline scripts, the tag's <script> also needs your nonce or a hash. A nonce is easier: a hash changes whenever you edit the tag's settings. Through GTM, Custom HTML tags need what GTM's own instructions for Content Security Policy say.
If your policy uses 'strict-dynamic', the nonced tag is trusted to load our script, and browsers that support 'strict-dynamic' ignore the https://js.ttbcdn.net source. Keep it anyway for browsers that don't.
If your policy requires Trusted Types (require-trusted-types-for 'script'), the tag's line s.src = CONFIG.script needs a policy that allows script URLs on https://js.ttbcdn.net. Create one in your own code (for example a default policy whose createScriptURL passes that host and rejects others), and list its name in trusted-types if you restrict policy names.
Nothing else is needed: the script uses no eval, workers or blob URLs, sets no cookies, and loads no images, fonts or frames from anywhere.
Good to know
- Single-page apps: the tag measures full page loads. A route change inside the app is part of the same pageview, so don't fire the tag again on GTM's History Change trigger.
- A renamed dataLayer: if your site uses a name other than
dataLayer, changedataLayer: 'dataLayer'in the tag's settings to your name. - Updates are automatic. We update the script on our side, and the installed tag stays as it is. If a change ever needs a new tag, we will tell you.
Consent
The tag sets no cookies. It keeps a random tab ID in the browser's session storage, which is deleted when the tab closes. If you set account, it also reads that one cookie of yours and sends the member ID. It reads details of the browser and of how the page is used (never what is typed), and our server looks up the visitor's IP address. Our privacy page lists everything that is collected.
Our recommendation: run it on every page, before consent, as a security measure. Under the GDPR, the legal basis is your legitimate interest in security and fraud prevention, which the regulation names itself (Recitals 47 and 49).
In the EU, the EEA and the UK, a second rule applies (ePrivacy Article 5(3); PECR in the UK). Reading information from a visitor's device needs consent unless it is strictly necessary for the service the visitor asked for, with or without cookies. Bot and fraud protection is commonly run under that exception, before consent, and we think Telltale Bot qualifies. To run it before consent:
- List it in your cookie or privacy notice as a security measure, and say what it reads.
- Let the verdict reach analytics and ad tools only through tags that already wait for consent. The tag puts the verdict in your page (your dataLayer and its events) and nowhere else. Your GA4 tag, with its own consent settings, decides whether it goes further.
- Don't use the verdict for advertising or to build profiles of people.
Running it only after consent mostly defeats it. Automation seldom accepts a consent banner: most bots never answer it, and AI agents acting for a person tend to decline it. So after consent the tag measures the visitors who accepted, mostly people, and misses most of the automation it is there to find. If your consent tool holds back Google Tag Manager itself, install the tag directly in the page so it runs before the banner.
Outside the EU, the EEA and the UK, most privacy laws ask you to disclose security processing like this rather than get consent first: name it in your privacy policy. This is our position, not legal advice. The decision is yours, for your site and for where your visitors are.
Before you rely on it
Telltale Bot is in beta. Read what Telltale Bot misses: the visits it never sees, and the people it can mistake for automation. Once reports arrive, Reading your reports explains the viewer. Questions about installing it: support@telltale.bot.