Guide
Everything a beta tester needs, in order. Short on time? Hand this page's companion file, llms.txt, to your AI assistant and let it do the integration for you.
1. Sign in
Use the Log in button on the Tinkerer Analytics home page. Enter the email address your invitation was sent to and follow the one-time code that arrives by email. You land on a home page with every link in one place:
- Panel: create sites, declare properties, manage tokens, copy snippets.
- Stats dashboard: your daily counts, funnels and breakdowns.
- Guide and llms.txt: this page, and the machine-readable version.
2. Create your site
In the panel, choose New site and fill in:
- Site id: a short name for the site, such as
my-blog. - Allowed domains: the domains your events will come from. Events from anywhere else are rejected, which is what keeps your numbers yours.
- Mode: strict counts daily totals only. Standard also counts unique visitors per day, using a one-way hash that rotates daily and is deleted once the day is finalised.
- Properties (optional): if your events will carry extra values, such as a link name or a board size, declare each one's shape here first. Events carrying undeclared properties are rejected whole.
3. Add the tracking
Open your site's Install tab in the panel and copy the snippet. It is generated for your site, with your token and your declared properties filled in. Paste it into your pages before the closing </body> tag. The snippet fires one pageview per load; fire further events from your own code, for example tinkerer.track('link_click', { link: 'docs' }).
The Install tab waits for your first event and tells you when it arrives. Once it does, your site is live and the tab links straight to your dashboard.
Link clicks with no code at all: if your site declares a link property, add data-tinkerer-link="docs" to any element and the tracker counts its clicks for you, including clicks on things inside it. Values outside your declared list are ignored.
For apps and games, send the lifecycle in order: game_started, then game_first_move, then game_completed. The tracker keeps one game id per game; call tinkerer.resetGame() before the next one.
4. Not using JavaScript?
No problem. The tracker is a convenience, not a requirement. Any language or runtime that can send an HTTPS POST with a JSON body can integrate directly: Python, Go, Rust, C#, PHP, Unity and game engines included. Two rules matter:
- Send the site token and the event name as JSON to the endpoint shown in your snippet.
- Set an
Originheader naming one of your allowed domains. Browsers send it automatically; other clients must set it themselves.
The full contract, with a copy-paste curl example, is in llms.txt.
5. Read your numbers
The stats dashboard shows today, the last 7 days and the last 30 days, with a day-by-day table. Games get a funnel (visited, started, first move, completed); declared breakdowns appear as per-value daily totals. Counts are daily: there is no raw event log to dig through, by design.
To take the numbers elsewhere, use Download CSV on your site's dashboard page: it exports exactly the view on screen (the picked day, or the selected range) as one file: a day-by-day table with a totals row, then your breakdowns and the filtered and quarantined summaries as headed sections. Standard-mode sites include a unique visitors column; strict-mode sites have none, because strict mode records no uniques. The same export answers at GET /api/export.csv?site_id=...&from=...&to=... for scripts, defaulting to the last 30 days.
6. The command-line client (optional)
Everything in the panel can also be driven from a terminal with the tinkerer CLI, which suits scripts and AI agents. Download it from the tinkerer-cli releases page, then open CLI access in the panel to issue yourself a credential, set it as TINKERER_API_TOKEN, and run tinkerer sites list. A credential carries the same access as your panel account, so treat it like a password; you can revoke it on the same page at any time.
7. When an event is rejected
missing_origin: no Origin or Referer header arrived. Browsers always send one; non-browser clients need to set it.disallowed_origin: the sending domain is not in your site's allowed domains. Add it in the panel.invalid_properties: a property was undeclared, or its value fell outside the declared shape. Declare it, or fix the value.- Filtered is not a rejection: recognised bots are counted in a separate bucket, so your main totals stay human.
8. The beta, briefly
The beta is free, places are limited, and your data belongs to you. The full notes are on the beta page. Help: [email protected]. Privacy questions: [email protected].