Version 0.9.0
ConvertDash documentation
Everything you need to measure people, not machines: one tag to install, a
dashboard to read, and the rules behind every number. Search the ConvertDash documentation with
/ from anywhere on the page.
Quick start Install on your platform The dashboard AI visibility Count crawlers Settings Read API Self hosting Plans
Contents
Start here
Quick start
Four steps, and most people are done in five minutes. Nothing to install on your site beyond one script tag.
- Sign up. Create an account at analytics.convertnow.tools. The first seven days include everything a paid single site gets, plus All sites. No card.
- Add your site. Open Sites and tags, press Add site, and enter the domain and a name. You get a site key and a finished tag.
- Paste the tag. Put it inside the
<head>of every page. Installing on your platform shows where that is on WordPress, Shopify, Webflow and the rest. - Press Test from my browser. It opens your site, sends one visit from your own browser, and tells you whether it got through and why. If it did not, press Check installation. It reads your page and names the problem: a missing tag, a caching plugin, a Content Security Policy or the wrong domain.
Your tag looks like this, with your own key in place of YOUR_SITE_KEY:
<script defer data-no-optimize="1" data-no-defer="1" data-cfasync="false" nowprocket
src="https://analytics.convertnow.tools/cd.js?k=YOUR_SITE_KEY"></script>
Why the extra attributes. They tell LiteSpeed Cache, WP Rocket, SiteGround Optimizer and Cloudflare Rocket Loader to leave the tag alone. Without them those tools often hold scripts back until the visitor scrolls, and some visits are never counted. Keep them, even if your site does not use any of these.
The ?k= part matters. It is how the server knows which site a visit
belongs to, and it is how your dashboard settings reach the tag without you editing
any HTML.
Once visits arrive, open Explore for the whole site on one board, or any report from the menu. Reading your dashboard walks through them.
Waiting to run it on your own server instead? See Self hosting, which says where that stands.
Installing on your platform
Every platform ends up doing the same thing: one script tag in the head of every page. No plugin is needed anywhere. Pick yours and copy the code:
WordPress
Without a plugin. Paste the tag into your theme’s header, just
before </head>, or into the header box of any code snippet plugin
you already use. The tag reads WordPress body classes, so posts, pages, archives,
search results and 404s are all recognised with nothing extra.
With the optional plugin. A free WordPress plugin can paste the tag for you. It does nothing the tag cannot do on its own, so use it only if you prefer not to touch theme files.
Signed in editors are skipped automatically: when the WordPress toolbar is on the page, the visit is not counted. Change that in Settings.
WooCommerce
Install the tag as for WordPress. Orders are then read from the order received page by themselves, with the amount and currency. Each order counts once, even if the buyer reloads the page.
Shopify
Online Store, Themes, Edit code, then layout/theme.liquid. Paste the
tag just before </head>. To count orders, add the same tag to the
order status page too, under Settings, Checkout. The tag then reads each finished
order.
Menu names move. Hosted builders rename their settings from time to time. If a label below does not match, look for Custom code, Code injection or Head code in the site settings.
Webflow
Site settings, Custom code, Head code. Paste the tag and publish.
Wix
Settings, Custom code, Add custom code. Paste the tag, choose all pages, and place it in the head.
Squarespace
Settings, Advanced, Code injection. Paste the tag into the header box.
Ghost
Settings, Code injection, Site header. Ghost prints author structured data on posts, so the Editorial reports fill in without any extra work.
Next.js, React and other single page apps
Add the tag to the head of your root layout or index.html. Route
changes are followed automatically, so each new page in the app counts as a view.
If your router changes the view without changing the address, call
convertdash.pageview() yourself when a new view appears. Doing both
counts the same view twice, so turn automatic tracking off with
data-spa="0" when you do this.
Google Tag Manager
Create a Custom HTML tag with the code from the Tag Manager tab above, set it to fire on all pages, and use the Initialization trigger so it starts as early as possible. A direct tag in the head is still the better choice when you can add one.
Plain HTML
Paste the tag inside <head> on every page, or in the shared
layout your pages use.
What the tag picks up by itself
No plugin and no extra code. The tag reads what your pages already say.
| Authors | From the author meta tag, the article’s structured data, or a byline link marked as the author. Feeds the Editorial reports. |
| Page types | Posts, pages, products, archives, search results and the home page, from WordPress body classes, structured data or Open Graph. |
| Missing pages | A WordPress 404, or a page whose title says it was not found. These land in Broken Links. |
| Site search | Anything searched with ?s=, ?q=, ?query= or ?search=. Only the term is kept. |
| Shop orders | The WooCommerce order received page, and the Shopify order status page when the tag is on it. Each order is counted once. |
| Route changes | In single page apps, each new route counts as a view. |
| Your own visits | On WordPress, anyone with the admin toolbar showing is skipped. |
When a page does not say these things itself, set them on the tag with
data-type, data-author and data-author-name.
See Tag options.
Search terms that do not look typed are dropped. The same parameter names often carry reset keys, signed links or email addresses. So email addresses, web addresses and long random strings are thrown away rather than recorded. Losing the odd real search is the cheaper mistake.
Tag options
All optional. Most sites never need any of them, because your dashboard settings
reach the tag through its ?k= key. Add an attribute to change one page
without changing the setting for the whole site.
| Attribute | Example | What it does |
|---|---|---|
data-type | product | What kind of page this is. 404 marks a not found page. |
data-author | Jane Doe | Who wrote the page, as a name or a numeric id. |
data-author-name | Jane Doe | The name to show when data-author is an id. |
data-events | 1 | 1 captures outbound, download, email and phone clicks on this page. 0 turns click capture off. |
data-files | pdf,zip | File extensions that count as downloads. |
data-selector | .cta | Extra elements to count clicks on. The label comes from data-cd-label on the element, or its text. |
data-dwell | 2000 | Milliseconds on screen before a view counts without any interaction. The default is 2000. |
data-mode | i | i counts only views with a real interaction. |
data-spa | 0 | 0 stops following route changes in single page apps. On by default. |
data-search | 0 | 0 stops recording site search terms on this page. |
data-search-keys | s,q,term | Which address parameters count as a search. |
data-frames | 1 | Count pages shown inside a frame. Off by default, so an embedded page does not add a second view. |
data-api | https://…/collect | Send visits to a different collector address. |
data-site | YOUR_SITE_KEY | The site key, for a tag loaded from an address without ?k=. |
data-dnt | 1 | 1 skips readers who send Do Not Track or Global Privacy Control on this page. The site setting decides by default. |
data-purchase | 1 | 1 exposes window.convertdash.purchase() on this page. Same as the Purchase call setting. |
Custom events
Clicks on outbound links, downloads, email links and phone links are captured on their own once you switch them on under Settings, Clicks and events. For anything else, send an event yourself after the tag has loaded:
convertdash.event('signup', { plan: 'pro' });
convertdash.event('video_play', 'homepage');
The first argument is the event name. The second is optional: a short text value, or an object whose first value is kept. Only one value is stored, on purpose, so an events table never turns into a log of personal data by accident.
Events appear in the Events section. Use them as goals in Behavior to see how often a visit ends in that action.
Revenue
Every sale is tied back to the visit that brought it: channel, landing page, referrer, campaign, author and AI assistant. Pick the method that fits your checkout. Each order is counted once, however many times it arrives.
WooCommerce and Shopify
Nothing to set up. The tag reads the order from the thank you page. On Shopify, add the tag to the order status page too, under Settings, Checkout.
Any thank you page
Put this element on the page buyers see after paying, filled in by your platform:
<div data-cd-order="ORDER-123" data-cd-amount="1499.00" data-cd-currency="INR" hidden></div>
A redirect
If your checkout can send buyers to a thank you address of your choice, add the order to it:
https://example.com/thanks?cd_order=ORDER-123&cd_amount=1499.00&cd_currency=INR
JavaScript
For a checkout that finishes without loading a new page:
convertdash.purchase({ id: 'ORDER-123', amount: 1499.00, currency: 'INR' });
From your server
For Stripe, Paddle, Gumroad, Lemon Squeezy, a Zapier webhook or your own backend. The server token is in Settings, Advanced.
curl -X POST https://analytics.convertnow.tools/api/sites/SITE_ID/orders \
-H "Authorization: Bearer SERVER_TOKEN" \
-d order_ref=ORDER-123 -d amount=1499.00 -d currency=INR
A refund is the same call with -d event=refund, and it is subtracted
so the net figure matches your shop. Send your payment provider’s own order id and
webhook retries do no harm. Orders sent from a server have no visit attached, so they
count in totals but not in the channel and page breakdowns.
Set your reporting currency under Settings, Revenue. Until the first order arrives, the Revenue screens show how to send one.
Machines
Counting machines that never run JavaScript
The tag runs in browsers. Most crawlers never run it, so on its own the tag only sees the machines that execute scripts: headless browsers, some AI agents, link previewers that render. GPTBot, ClaudeBot, Googlebot and the SEO crawlers fetch the HTML and leave. To count them, your server tells ConvertDash what it saw. People are still counted by the tag only, so nothing here can change your visitor numbers.
What is stored. A date, a kind, a name, a path and a count. The address of the machine is used once to check that a crawler is who it says it is, then discarded. The full user agent is never stored.
Option 1: send requests from your server
Post a batch of up to 500 requests to your site’s machines endpoint. Authenticate with the
server token from Settings, Advanced. Some shared hosts strip the Authorization
header, so X-CD-Token works too.
POST https://analytics.convertnow.tools/api/sites/SITE_ID/machines
X-CD-Token: YOUR_SERVER_TOKEN
Content-Type: application/json
{
"batch_id": "web1-2026-09-22T10:05",
"items": [
{ "ua": "Mozilla/5.0 (compatible; GPTBot/1.2)", "path": "/pricing", "ts": 1790071500, "ip": "20.171.207.2" },
{ "ua": "Mozilla/5.0 (compatible; Googlebot/2.1)", "path": "/blog", "ts": 1790071502 }
]
}
| Field | What it is |
|---|---|
ua | The user agent string. Required. Plain browsers are ignored. |
path | The path that was requested. Query strings are dropped. |
ts | Unix seconds. Optional, defaults to now. Older than 48 hours is skipped. |
ip | Optional. Used only to verify a claimed crawler, then discarded. |
method, status | Optional. Only GET and HEAD are counted. |
batch_id | Optional. A retried batch with the same id is not counted twice for 24 hours. |
The answer says how many were received, counted as machines, ignored as people, and verified. Keep sends to at most two a second per site. Filter on your side first: only forward requests whose user agent is not a plain browser, and nothing is added to a normal page load.
Option 2: import your access logs
Not available yet. The log importer runs as a command on the server the app is installed on, so it arrives with self hosting. Until then, Option 1 above is how server side hits reach ConvertDash, and it covers the same ground: your server posts what it saw, and only named machines are counted.
For reference, this is the command it will be:
php bin/convertdash logs:import --site=1 --file=/home/USER/logs/access.log
php bin/convertdash logs:import --site=1 --file='/var/log/nginx/access.log*' # rotated and .gz files too
Combined and common log formats, LiteSpeed logs and Cloudflare Logpush JSON lines are detected on their own. Run it hourly from cron and each run picks up where the last one stopped.
Real crawler or impostor
Anyone can put Googlebot in a user agent. When an address comes with the request, ConvertDash checks it against the ranges the operator publishes, or with a forward confirmed reverse DNS lookup for operators that verify that way. A claim that fails is filed as Fake followed by the name, so impersonation shows up in Filtered Traffic instead of hiding inside it. Without an address the name is taken at its word.
The dashboard
Reading your dashboard
The left menu holds every report, grouped by the question it answers, with Explore at the top. Every screen follows the date range, the comparison and any filter you set, and every chart can be downloaded as a picture.
Explore
One board for the whole site. Pick a goal, split everything by a segment (channel, device, browser, country, source, campaign, landing page, new or returning, assistant or not), and compare with the previous period or between two saved segments. The cards:
- Key numbers with a sparkline and the change against the comparison.
- Live now: visitors in the last 5 and 30 minutes, with their pages and sources, refreshed every 30 seconds.
- Traffic by channel over time, stacked so the layers add up to all visits.
- Source and campaign attribution: visitors, visits, bounce rate, conversion rate, revenue and revenue per visit, sortable.
- Top pages with entries, exit rate and share of converting visits.
- Funnel split by device or browser, goal completions, top events, retention, where visits go, and devices, browsers and countries with their conversion rates.
- Insight explorer: choose a metric, a breakdown, a chart and a granularity, then save the card to the board.
Drag cards to reorder them, hide the ones you do not need, and download any card as CSV. The board is saved per person and per site.
One counting rule everywhere. A visit belongs to the channel, source, campaign, device and landing page of its first pageview. Conversion rate is visits that completed the goal divided by visits.
The report sections
| Section | What it answers |
|---|---|
| Editorial | Which authors and content types bring readers in |
| Pages | Which pages are read, where visits start and end, and page flow for any page |
| AI Visibility | Assistants that send people, crawlers that read pages, and how the two relate |
| Filtered Traffic | Every bot, crawler and scanner that was refused, by name |
| Referrers | Which sites and channels send visitors |
| Campaigns | UTM source, medium and campaign |
| Geographic | A world map, countries, continents and languages |
| Devices | Device types, browsers, systems and screens |
| Behavior | Goals, funnels, journeys, retention, engagement, segments and cohorts |
| Audience | New and returning visitors, and how they engage |
| Revenue | Orders and what brought them |
| Events | Clicks, downloads, missing pages and site search |
| Growth | How traffic changes, and a calendar of every day |
| Data | AI insights and exports |
Every section opens with an at a glance screen: tiles, a trend, and short ranked lists. Long tables are paginated and searchable.
Behavior, drawn
| Screen | What you see |
|---|---|
| Journeys | A flow diagram of the first 2 to 6 steps of every visit, with where people left at each step. Hover a page to light its whole path. Start from or end at any page. |
| Funnels | Each step with the part that continued and the part that dropped, step and overall rates, the median time between steps, where the dropped went next, and the same funnel split by device, channel, country or browser. |
| Goals | Conversion rate over time per goal, rate by source, and how long a visit took to convert. |
| Retention | A cohort grid of visitors seen again after their first week or day, with the average curve above it. |
| Engagement | Pages placed by views and engaged time, sized by entries and coloured by exit rate, plus how far readers of a page get through it. |
| Page flow | For one page: where its visits came from, and where they went next. |
| Segments and cohorts | Groups of visits side by side against the whole site. |
Retention needs a longer visitor window. With the default one day window nobody can be recognised on a later day, so the retention grid explains that and links to the setting instead of drawing an empty chart.
Filters, dates, comparison and notes
Add a filter, such as one country, one campaign or one author, and it applies to every report until you remove it. Pick a preset range or custom dates, switch on compare to see the previous period beside each number, and add a note to the chart to mark a launch. The main chart can also draw a trend line, a smoothed average, unusual days and a forecast; choose which under Settings, Display.
Export
Download CSV, TSV, JSON or NDJSON by visits, pageviews, events or daily totals. The export uses the filters on screen.
AI
AI visibility and AI insights
Two different machines read your site for AI. A crawler (GPTBot, ClaudeBot, PerplexityBot, Bytespider and others) reads pages to train or index. An assistant fetch (ChatGPT-User, Perplexity-User, Claude-User) reads a page because a person asked a question just then. Separately, an assistant can send a person to you: that is a visit, counted like any other, with the assistant as its source. ConvertDash keeps the three apart.
Which assistants are recognised
Visits are matched to an assistant by the referring host, and by utm_source
when the assistant strips the referrer, as ChatGPT often does. The list covers ChatGPT,
Perplexity, Claude, Gemini, Copilot, Grok, DeepSeek, Meta AI, Le Chat, NotebookLM, Kagi,
You.com, Phind, Poe, Duck.ai, Kimi, Qwen, Doubao, HuggingChat, T3 Chat and Monica. An
assistant that sends neither a referrer nor a tag shows as direct, and nothing can change
that from your side.
The AI Visibility screens
| Screen | What it shows |
|---|---|
| AI Overview | Share of voice by assistant, week by week. Assistant referrals indexed against your site’s own growth. How those readers engage and convert compared with search and with everyone, with a significance test so small differences are called small. Revenue from assistant visits. |
| Crawl to referral | Per page: how often crawlers read it, how often assistants fetched it for someone, and how many people assistants sent to it. Pages read a lot and never cited are listed on their own, and so are pages cited but never seen crawled. |
| Crawler analytics | Crawls per bot over time, the median days between crawls of a page, which sections take the crawl budget, and bots seen for the first time. A helper drafts a robots.txt block per bot and an llms.txt starter from your top pages, and a button checks your live robots.txt and llms.txt. |
| Assistants, AI pages, AI machines | The original ranked lists: visits by assistant, pages they land on, machines by name, and pages machines read. |
Crawler numbers need server side data. Most crawlers never run the tag. Send requests or import logs as described in Counting machines, or the crawler screens only show the few that render pages.
AI insights
Under Data, AI insights is a feed of findings, ranked, each with the number, a small chart, a confidence, the reasoning and a next step. The models run on your server every night and the screen opens instantly. Nothing is sent anywhere.
| Group | How it is worked out |
|---|---|
| What changed | Level shifts found with a changepoint search over the daily series, and period changes broken down by channel, source, page, country and device to show what drove them. |
| What is unusual | The expected day comes from a seasonal decomposition with the weekly pattern. A day is unusual when it sits far from that, tested so that pure noise almost never raises an alert. |
| What is coming | A forecast for the next weeks with a range. It is only shown when it beat a simple same weekday last week baseline in a backtest, and the backtest error is stated. |
| Who converts | Which traits of a visit go with completing your goal, with confidence ranges, shown only when the model is good enough to trust. Visit personas from clustering. Channel credit from a Markov chain. |
| AI traffic | Growth of assistant referrals against the site, what they are worth, and pages models read but do not cite. |
| Suspicious traffic | Counted sources whose visits look automated even though they passed the filters. Listed for you to judge, never removed. |
Pin a finding to keep it at the top, dismiss one you have dealt with, or press Rebuild now. Findings need some history: most groups wait for about four weeks of data and enough visits to say anything with confidence.
Written summary, optional. With your own API key in
CD_AI_PROVIDER and CD_AI_KEY, a short written summary of the
findings appears on top. Only headlines and numbers are sent, never rows or visitors, and
Preview shows exactly what would be sent. Without a key, nothing leaves the server.
What counts as a visit
A pageview is counted when the page actually painted on screen and then either the visitor did something (moved, tapped, typed, scrolled) or it stayed in front of them for two seconds. Time only runs while the tab is visible, so a background tab nobody looked at never counts.
Both halves matter. Paint alone would count prerenders and forgotten tabs. Interaction alone would count scripts that click.
Where a visit came from
A visit belongs to the source, channel and campaign of its first pageview. A reader who arrives from Google and then clicks three internal links is one Google visit with four views, not one Google view and three direct ones. Visits end after 30 minutes of silence or at midnight in the site’s timezone, whichever comes first.
Why the numbers differ from Google Analytics
- Bots are filtered. Crawlers, AI crawlers, scanners, headless browsers and data centre traffic are refused and listed in Filtered Traffic.
- Visitors are counted per day. The identifier rotates daily by default, so someone who visits on Monday and again on Tuesday counts as two visitors in a weekly total. You can choose a longer window in Settings.
- Unseen pages do not count. Prerenders, prefetches and tabs opened in the background are left out.
- Privacy signals are honoured. Browsers sending Do Not Track or Global Privacy Control are skipped by default.
- Your own visits are skipped. On WordPress, signed in editors are not counted.
VPN and iCloud Private Relay visitors who interact with the page are counted like anyone else.
Filtered traffic
Everything the collector refuses is counted by kind and by name, so your visitor number can be checked rather than taken on faith. The Filtered Traffic section shows:
| AI crawlers | GPTBot, ClaudeBot, CCBot and others reading the web in bulk |
| AI assistant fetches | An assistant reading a page because a person asked it something |
| Search engines | Googlebot, Bingbot and friends |
| SEO tools | Ahrefs, Semrush and similar |
| Link previews | Slack, WhatsApp or LinkedIn unfurling a link |
| Scripts and headless browsers | curl, scrapers and automated browsers |
| Scanners | Machines probing for weaknesses |
| Data centre traffic | Browsers on cloud and hosting addresses that never interact |
Refused traffic is stored as counters, never as a log: a date, a name, a page and a number. None of it is added to your visitors.
Under Settings, Tracking you can choose the bot filter level. Standard is the default. Strict also drops anything that is not a recognisable browser. Off counts everything, and is only for debugging.
Settings
Settings reference
Every setting, its default, what it changes and when a change takes effect. Settings are per site and live under Settings in the dashboard.
Visits already stored keep what they have. A setting that changes what is stored, such as country or the returning visitor window, applies to new pageviews.
Tracking
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Site name | the domain | Shown in the site picker and at the top of the weekly summary. | At once |
| Domain | Beacons are accepted from this domain and its subdomains. Changed under Sites and tags. | At once | |
| Collect data | on | Off refuses every beacon for the site. Data already stored is kept. | At once |
Accuracy and privacy
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Bot filtering | standard | Standard refuses named crawlers and tools, requests with the wrong headers, and pageviews with no proof of a person. Strict also refuses browsers whose environment reports oddly and any agent that is not a recognisable browser. Off counts everything that reaches the endpoint, proof included. Refused requests are tallied under Filtered Traffic. | At once |
| Count a view after | 2000 | How long a page has to stay in front of somebody, in milliseconds, before it counts without them touching anything. 1000, 2000, 3000, 5000 or 10000. Time runs only while the tab is in front. | Next pageview |
| What proves a person | either | Either: an interaction or the dwell above. Interaction: only a pointer, tap, key, wheel or scroll counts, staying never does. The server refuses a dwell only view under the interaction rule even from a stale tag. | Next pageview |
| Data centre addresses | on | Refuses pageviews from cloud and hosting ranges that show no interaction. A cloud address that scrolled or tapped is counted, because relays and VPNs exit there. Strict bot filtering refuses them all. Tallied as datacenter. | At once |
| Filtered traffic | on | Keeps counters of what was refused: a date, a kind, a name, a path, a number. Off, refusals are still refused but not counted, and the Filtered Traffic screens are empty. | At once |
| Keep filtered counters for | 180 | Days the refusal counters are kept. 0 keeps them. | Hourly housekeeping |
| Do Not Track | on | A browser sending DNT: 1 or Sec-GPC: 1 is not recorded. The refusal is tallied as excluded so the gap is visible. Brave sends GPC on every request. | At once |
| Your own visits | off | On a WordPress site the tag sees the admin toolbar and skips the page. On, editors are counted. | Next pageview |
| Country data | on | Looks the country up from the address on the server and stores the two letter code. Off, nothing is stored and the Location screens stay empty from then on. | New pageviews |
| Recognise a returning visitor for | 1 | Days the visitor identifier stays the same: 1, 30, 90, 365, or 0 for never rotated. One day means nobody can be followed past midnight. Longer windows turn on returning visitors and cross day retention and must be disclosed. | New pageviews |
| Flood protection | on | Caps one address at 300 accepted requests a minute and one visitor at 30. Past the cap, requests are refused and tallied as flood. | At once |
| Visit gap | 30 | Minutes of silence that end a visit. A pageview within the gap, on the same local day, joins the previous visit. Set through the settings API. | At once |
Revenue
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Record orders | on | Off, orders from the tag, the thank you page and the API are refused. One row per shop and order reference, so a resent order never counts twice. | At once |
| Purchase call | off | Exposes window.convertdash.purchase() in the tag. | Next pageview |
| Revenue reports | on | Shows or hides the Revenue section in the menu. | Next dashboard load |
| Currency | EUR | The currency revenue is reported in. Stored amounts are not converted. | At once |
Exclusions
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Ignore IP addresses | empty | One per line. Exact addresses, wildcards such as 198.51.100.*, or CIDR ranges, IPv4 or IPv6. Matched on the server. Tallied as excluded. | At once |
| Ignore paths | empty | One per line, * as a wildcard. Matched against the stored path after the query string is removed. A pageview or click on a matching path is dropped without a trace. | At once |
| Query strings | on | Drops the query string from stored paths. Campaign tags and ad click ids are read into their own columns first and are never stored in a path either way. Off keeps every other parameter. | New pageviews |
| Except these parameters | empty | Parameter names, one per line, kept in the path when stripping is on, in a fixed order so two spellings of the same address are one page. | New pageviews |
Clicks and events
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Outbound links | on | A click on a link to another domain. | Next pageview, and the server refuses the kind at once |
| File downloads | on | A click on a link whose extension is in the list. | Same |
| Counted as a download | pdf, doc, docx, xls, xlsx, ppt, pptx, zip, rar, 7z, csv, mp3, mp4, dmg, exe, pkg | The extensions. | Next pageview |
| Email links | on | mailto: links. | Same as outbound |
| Phone links | on | tel: links. | Same as outbound |
| Specific elements | off, empty | Clicks on anything matching a CSS selector, labelled with the element’s data-cd-label or its text. A matching element is filed here and not also as another kind. | Next pageview |
| Record 404s | on | A page whose title or WordPress body class says it is missing is stored as a notfound view and listed under Broken Links. Off, the view is refused and tallied as excluded. | At once |
| Record site searches | on | The search term read off the address. Values that look like a token, a link or an email address are never recorded. | Same as outbound |
| Search parameters | s, q, query, search | Which query parameters carry a search term. | Next pageview |
| Keep events for | 0 | Days clicks and events are kept. 0 follows the raw pageview window. | Hourly housekeeping |
Display
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Default date range | 7d | What the dashboard opens on, and what an unknown range key falls back to. | Next dashboard load |
| Timezone | UTC | Where a day starts and ends in every report and the summary email. Changing it queues a rebuild of the daily summaries; the worker does it in batches and until then those days are read from raw rows, already in the new zone. Days whose raw rows have been pruned keep the summaries they have. | At once |
| Week starts on | Monday | Used by This week and the weekly charts. | Next report |
| Chart layers | off | Optional lines on the main chart, computed in the browser. | Next dashboard load |
Your data
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Keep raw rows for | 365 | Days pageviews are kept. 0 keeps them. Filters, journeys, goals, funnels, cohorts and retention read raw rows and cannot see past this. | Hourly housekeeping, batches of 5000 |
| Keep daily summaries for | 0 | Days the summaries are kept. 0 keeps them. | Hourly housekeeping |
| Run housekeeping now | Applies the windows above at once. | ||
| Rebuild summaries | Queues a rebuild. The marker moves back so reports read raw rows meanwhile; the worker summarises forward, 90 days a run. The card shows progress. | Worker | |
| Delete all analytics data | Type the domain to confirm. Everything measured up to that moment is deleted in batches; a small site is emptied at once, a large one by the worker over its next runs. Views arriving after the click are kept. Settings, the tag, notes and people stay. | At once, then worker |
Weekly summary email
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Send it | off | Next email | |
| How often | weekly | daily, weekly or every 30 days. | Next email |
| On | Monday | The weekday a weekly email goes, in the site’s timezone. Sent by the first worker run of that day and covering the seven finished days before it. Today is never included. | Next email |
| To | empty | Up to ten addresses. Empty sends nothing. | Next email |
Shared dashboard
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Enable | off | Master switch. Off, an existing link shows nothing until it is turned back on. | At once |
| Password | none | Asked of anyone opening the link. At least six characters, hashed, cannot be shown again. Set when generating a link. | The next link generated |
| Expires after | 0 | Days until the link stops working. 0 means until withdrawn. | The next link generated |
Advanced
| Setting | Default | What it does | Applies |
|---|---|---|---|
| Extra allowed domains | empty | Other domains the same tag runs on. Beacons from anywhere else are refused and tallied as origin. Links from these domains to the site count as internal, not as referrals. | At once |
| Local development | off | Accept beacons from localhost and 127.0.0.1 for this site’s key. A debug install (CD_DEBUG) accepts them regardless. | At once |
| Route changes | on | Count client side route changes as pageviews, once the reader has interacted with the page. | Next pageview |
| Endpoint | collect | Install wide. The name of the collect endpoint, for when a blocklist learns the default. Set through the settings API; the tag picks the new name up on its own. | Next pageview |
Team
Invite colleagues or clients to your sites, each with their own sign in. Choose a role per site:
| Viewer | Can see reports |
| Editor | Can also change settings |
| Admin | Can also manage people |
People you invite do not use your site count, and they see your sites with your plan’s reports. Team is part of Agency.
All sites
Every site you can open, on one screen: totals across all of them, a trend for each, and a comparison table you can sort by any column. It is the quickest way to spot which site needs attention.
All sites comes with Pro Power and Agency, and with the free trial.
White label
Put your own brand, or your client’s, on the shared dashboard and the weekly email for a site. Under Settings, White label, set:
- Brand name, shown in the header.
- Logo, as the https address of an image. It is also used as the page icon.
- Accent colour, used for charts, links and buttons.
- Brand link, optional, for the name in the header.
- Hide the ConvertDash credit on the shared dashboard and in the email.
White label is part of Agency.
Sharing
Shared links
A shared link opens one site’s dashboard, read only, without signing in. Create one in Settings, Shared dashboard. You can protect it with a password of at least six characters and give it an expiry in days. The password is stored as a hash and cannot be shown again.
- Switching sharing off stops every link for the site at once. Switching it back on brings them back.
- Generate a new link to retire the old one.
- Wrong passwords are limited, so a link cannot be guessed open.
- On Agency, the link carries your white label brand.
Shared links come with every paid plan.
Read API
Read your reports as JSON. Create a token on your Account page and send it with every request. A token sees the same sites you do and cannot change anything. The Read API is part of Agency.
Authorization: Bearer cdk_your_token
Endpoints
GET /api/v1/sites | The sites you can see: id, name, domain, timezone. |
GET /api/v1/sites/{id}/summary | Visitors, visits, views and the rest of the overview, with the change against the period before and a daily series. |
GET /api/v1/sites/{id}/reports | Every report id and name, and whether the plan covering the site opens it. |
GET /api/v1/sites/{id}/reports/{view} | One report. Table reports take page and per (10 to 200 rows). |
GET /api/v1/sites/{id}/realtime | Visitors active in the last 5 minutes. |
Every call takes range: today, yesterday,
7d, 30d, 90d, 12mo or
all. Or send from and to as dates, like
from=2026-09-01&to=2026-09-10. The default is the last 30 days.
curl -H "Authorization: Bearer cdk_your_token" \
"https://analytics.convertnow.tools/api/v1/sites/1/summary?range=30d"
Sending data from your server
Two write endpoints take the site’s server token from Settings, Advanced, as a Bearer header or as X-CD-Token: POST /api/sites/{id}/orders for orders a browser never sees (see Revenue) and POST /api/sites/{id}/machines for crawler requests (see Counting machines). The server token is not a Read API token and cannot read reports.
Errors
401 | The token is missing or revoked. |
402 | The plan has lapsed. Requests answer 402 until it is renewed. |
404 | No such site, or you cannot see it. |
429 | Too many requests. Each token may make 600 requests every 10 minutes. |
Errors come back as {"error": "..."}.
Privacy
Privacy and what is stored
ConvertDash is built so the analytics do not need a consent banner in most places. Check your own rules; this is what the software does.
| Question | Answer |
|---|---|
| Cookies | None. The tag sets no cookie and reads none. |
| Browser storage | No localStorage. A session id sits in sessionStorage, which the browser deletes when the tab closes. |
| Visitor identifier | A one way hash of the address, the browser and a secret salt that rotates. By default it rotates every day, so today’s visitor cannot be matched to yesterday’s. You can choose 30, 90 or 365 days, or never, in Settings. |
| IP address | Used for the hash, the country lookup and the data centre check, then discarded. Never written to the database. |
| User agent | Reduced to browser, version, system and device type. The full string is never stored. |
| Query strings | Removed from stored paths by default. Campaign tags are read into their own columns first. |
| Do Not Track and Global Privacy Control | Honoured by default. The skipped view is tallied as excluded so the gap is visible. |
| Third parties | None. The tag, the lookups and the dashboard are all served by the install. Nothing is sent anywhere unless you turn on a check in or the written summary. |
| Refused traffic | Counted, never logged: a date, a kind, a name, a path and a number. |
What an install will send us, once self hosting exists
Two optional check ins, both described field by field in the licensing docs that ship
with the install. The licence check in sends the key, a random install id, the domains you
track, how many sites, the versions of ConvertDash, PHP and the database, and a rough
pageview band. The product check in, which is asked for at install and off until you say
yes, sends the same facts without a key and with the monthly pageview count. No row of your
analytics, no path, no referrer and no visitor is in either. php bin/convertdash
checkin off stops the product check in and deletes what was sent.
Troubleshooting
Start with the two buttons on Sites and tags. Check installation reads your page and names the problem. Test from my browser sends one visit from your own browser and shows whether it got through, and if not, why.
No tag found
The tag is not in the page the dashboard fetched. Check that it is inside
<head> and on the live site, not only in a draft or a staging copy.
If you just added it, clear your site’s cache, because the old page may still be
served.
Caching and optimisation plugins
LiteSpeed Cache, WP Rocket, SiteGround Optimizer and Cloudflare Rocket Loader can
delay or combine scripts. The attributes on the tag ask them not to. If one still
delays it, add cd.js to that plugin’s list of scripts to leave alone
(in LiteSpeed Cache: Page Optimization, JS Delayed Includes Excludes; in WP Rocket:
File Optimization, Excluded JavaScript Files). Then clear the cache.
Cloudflare
If your site sits behind Cloudflare, the tag is not affected: it carries data-cfasync="false" so Rocket Loader leaves it alone, and each visit is a POST that no cache stores. Pages served from Cloudflare’s cache still run the tag in every browser, so every visit is counted. If numbers look low and nothing in Filtered Traffic explains it, check that Bot Fight Mode is not challenging requests to the analytics host.
Ad blockers and Brave
Some blockers stop analytics requests, and those visits cannot be counted. Brave also sends Global Privacy Control with every request, which ConvertDash honours by default. To test your own install, use a regular Chrome or Safari window.
Do Not Track
Browsers sending Do Not Track or Global Privacy Control are skipped by default. If your own test visit does not appear, this is often why. You can switch it off in Settings.
VPN
VPN and iCloud Private Relay visitors who interact are counted. A VPN visitor who never touches the page can look like data centre traffic and be refused. If many of your readers use a VPN, switch off the data centre filter in Settings.
Wrong domain
Visits from a domain the site is not registered under are refused. If your site also answers on another domain, add it under Settings, Advanced, Extra allowed domains.
Content Security Policy
If your site sends a Content Security Policy, it must allow the tag to load and to
send visits. Add the analytics address to script-src and
connect-src:
script-src 'self' https://analytics.convertnow.tools;
connect-src 'self' https://analytics.convertnow.tools;
My numbers are lower than another tool
Expected. See What counts as a visit, then open Filtered Traffic: the difference is listed there by name.
Self hosting
Not available yet. ConvertDash runs on our servers, at
analytics.convertnow.tools. A build you can install on your own server is
being worked on and is not something you can buy or download today. There is no date to
give you.
When it is ready it will be announced on the product page and to everyone on a plan. Nothing you set up now is wasted if you are waiting for it: the tag is the same, the reports are the same, and your history moves with you.
If self hosting is the only way ConvertDash works for you, say so at the support address. Knowing who is waiting, and why, is what decides how soon it gets built.
Plans and billing
Every new account starts with a seven day free trial. It includes everything a paid single site gets, plus All sites. No card, nothing to cancel. After seven days the account moves to the free plan and keeps collecting.
| Trial | Free | Pro Single | Pro Power | Agency | |
|---|---|---|---|---|---|
| Seats (installs on one key) | 1 | 1 | 1 | 2 | 5 |
| Sites | 1 | 1 | 1 | 5 | Unlimited |
| History | Full | 30 days | Full | Full | Full |
| Reports | All 63 | Core | All 63 | All 63 | All 63 |
| Events | Yes | No | Yes | Yes | Yes |
| Revenue | Yes | No | Yes | Yes | Yes |
| Exports | Yes | No | Yes | Yes | Yes |
| Shared dashboards | Yes | No | Yes | Yes | Yes |
| Weekly email | Yes | No | Yes | Yes | Yes |
| All sites | Yes | No | No | Yes | Yes |
| Team | No | No | No | No | Yes |
| White label | No | No | No | No | Yes |
| Read API | No | No | No | No | Yes |
The core reports on the free plan are pages, referrers, campaigns, geographic, devices and filtered traffic. Collection never stops and nothing is deleted.
Nothing is deleted when a trial or plan ends. History older than 30 days is hidden rather than removed, and each locked report names the plan that opens it. Buy a plan later and all of it is visible again at once.
Seats
A seat is one install. An agency running forty client sites through one install uses one seat. When every seat is taken, a new install is refused until one is released: run php bin/convertdash license deactivate on the old server before moving.
Refunds
Fourteen days, no questions: email us. A full refund retires the licence and the install moves to the free plan at its next check in. A partial refund is reviewed by a person before anything changes. Nothing you collected is deleted either way.
Upgrading
Open Subscription in your dashboard and pick a plan. The plan applies to your account the moment the payment clears. Confirm your email address first: the plan cards show before that, but the payment step does not.
Licence keys
Plans bought on the product page come as a licence key by email. Paste it under Subscription, Licence key, and the plan applies straight away. Removing the key there takes the account back to free and frees the key for another account. It does not cancel a yearly renewal: do that from the Razorpay receipt in your email, or reply to it.
Already have a key and need more sites? The upgrade form on the product page charges the difference between the two plans, once. Your key and renewal date stay the same.
Lost your key? We store a hash rather than the key, so nobody can look it up. Enter your email in the recovery form on the product page. We email a link that works for one hour. Your old key keeps working until you open that link and confirm; only then is a fresh key issued and the old one retired.
The licence, in full
Written out because a licence you have to email somebody about is a licence nobody reads. Everything below is how the software behaves. The plan table it refers to is on the pricing section of the product page.
1. The first seven days
Every new hosted account gets the Pro Single column plus All sites for seven days. Team, White label and the Read API stay on Agency. No card is asked for and there is nothing to cancel. On the eighth day the account moves to the Free column and keeps collecting.
Nothing is deleted at that point. History older than 30 days is hidden rather than removed, and each locked report names the plan that opens it. Pay at any point and the older data is visible again at once, including the weeks you spent on the free plan.
2. What a key attaches to, and seats
On the hosted service a plan belongs to your account. Buy it inside the dashboard and it applies the moment the payment clears. Buy it here and you paste the key under Subscription once. Remove the key there and its seat is free for another account.
On a self hosted install the key attaches to the install, identified by a random id it creates on first run. A seat is one install, not a site: an agency running forty client sites through one ConvertDash uses one seat. Moving to a new server? Run php bin/convertdash license deactivate on the old one first and the seat frees at once. Old server already gone? Email us and we will release it.
3. Where the visitor data lives
Your readers’ requests reach our servers, and what the collector keeps is written there: a visitor identifier that rotates daily by default, the page, the referrer, the country, the device and similar facts. IP addresses are never stored. We show you your own reports and do nothing else with it: no selling, no ad networks, no data brokers, no profiles of your readers or of you. You can export it and you can ask us to delete it, and deletion means deletion.
When self hosting exists, the same clause will cover it, and the data will sit on your own machine instead. That is not the case today.
4. The check in, and exactly what it sends (self hosting only, once it exists)
This one is about self hosted installs. Two check ins exist. A licence check in happens when you activate a key and then roughly monthly. A product check in happens once a month whether you have a licence or not, so we know how many installs exist and which versions to keep supporting.
What they send: the random instance id, the address you configured, the domains you track, how many sites there are, the ConvertDash, PHP and database versions, the platform, and the number of pageviews recorded in the last thirty days. One number. The licence check in also sends your key, because that is what it is for.
What they never send: any row of traffic, any visitor, any page path, any referrer, any figure from any dashboard, any email address, any account.
The product check in is switchable. The installer asks before the first one is sent. php bin/convertdash checkin off stops it and deletes the record of your install on our side. See the exact message with php bin/convertdash checkin preview, and read src/License/Registry.php in the source.
5. If our server is unreachable, nothing happens (self hosting only, once it exists)
For a fortnight. Installs sit behind firewalls, on air gapped networks, in places where an outbound call fails for reasons nobody can fix from here. The entitlement is cached, verified against a public key that ships with the install, and honoured through a 14 day offline grace window measured from the last successful check in.
If that window closes, the install steps down to the free tier. Collection continues at full speed, every historical row stays where it is, and the dashboard keeps showing the last 30 days. The moment a check in succeeds, everything comes back.
6. Your data is never held hostage
If a plan expires, is refunded, or you stop paying, collection carries on and the dashboard keeps working. You lose the paid features in the table above and nothing else. There is no kill switch in this product.
Self hosted, the rows are in your database and stay there. Hosted, the free plan shows the last 30 days and older rows are hidden rather than deleted. Pay again and they are back the same minute.
7. How your key is stored, and how you get it back
Not in plain text. We keep a keyed hash of it plus the first eight and last four characters, so a database breach here does not hand anybody a working key for every customer. The honest trade: we cannot look your key up.
Recovery is two steps. Type the address you bought with, and that mailbox gets a list of its licences by hint, each with a link that lasts an hour and works once. The link opens a page with one button. Press it and a new key is issued, shown once and emailed. Only then does the old key stop. Nobody who merely knows your email address can take your key away.
8. What we are honest about
ConvertDash ships readable PHP. Anybody determined enough can delete the licence check in twenty minutes, and no amount of cleverness would change that. So the check is not a lock. It is an honest meter: it tells your install what it is entitled to, warns you before a licence lapses, and lets us count seats.
What carries the commercial weight lives on the server: the crawler signature feed a licensed install pulls daily, and hosted delivery. That is why there is no obfuscation in this product, and why the product check in is a count rather than a lock.
9. Renewals, cancelling and refunds
Yearly subscription: renews itself through Razorpay. A renewal moves the expiry to the end of the period it paid for, plus seven days of grace, so a card that declines and is retried does not drop you to free in between. Cancel any time by emailing us, or from the link in your renewal receipt. A licence paid until December runs until December.
One payment: twelve months, no auto renew, no surprise charge. We email before it lapses.
Refunds: fourteen days, no questions asked, email and it is done. A full refund revokes the licence, and the install moves to free at its next check in with your collected data untouched. A partial refund changes nothing by itself: it is written on the licence and reviewed by a person, because a partial refund is usually a price adjustment, not a cancellation.
10. What you may and may not do
You may: run it on client sites, modify the source for your own use, and keep running the last version you had if you stop paying.
You may not: redistribute or resell ConvertDash itself, share a key across more installs than the licence covers, or offer it as a hosted analytics service to third parties without talking to us first. That last one is a conversation, not a no.