Track an event
Events →// anywhere after the script tag
signals('newsletter_signup');
signals('purchase', 9900, { order: 'X-1042' });
// or declare it in the markup
<button data-signal="cta_click">Buy</button> Cookieless by design
One script collects the visits. Forms, conversions, contacts and money hang off the same session. Everything the dashboard shows, you can read back from the API, an SDK, or an AI assistant.
<!-- one tag, every page -->
<script src="https://cdn.snipform.io/api/analytics/signals.js?site=YOUR_KEY" defer></script>
// console, one second later
Initialized
View loaded: <view id>, Session: <session id> The map
A visit becomes a session. Everything else either writes to that session or reads from it, which is how a form submit, an ad click and a paid Shopify order end up on the same row.
In the browser, or from your own server.
Signals tracker One script tag. Page views, events, revenue and identity. Forms HTML, React or dashboard-built. All validated server-side. Session handoff Pass the session id to your backend and keep writing to it. Shopify The session id rides the cart through to the paid order. Ad platforms Google and Meta spend, normalised to USD cents.What SnipForm builds out of it.
Sessions One visit, one document. Every field is filterable. Channels Classified once on arrival, in a fixed order you can override. Conversions Funnels that trip on views, events, links and form submits. Contacts The person behind the session, once they tell you who they are. Short links Campaign links with UTM presets and per-click geography. Money Revenue and ad cost, on the session, in integer cents.Get it back out, on your terms.
Dashboards Widget canvases, shareable on a public token. Weekly reports A stored snapshot per completed week, with checks. Automations When a signal fires, do something. Once per session, exactly. REST API Token-scoped and property-scoped, with a predictable envelope. MCP Twelve read-only tools, so an assistant can answer from real data. SDKs PHP and React packages, plus the tracker itself.First five minutes
Every snippet below works against a live property as soon as you have a key. Money is always integer cents.
// anywhere after the script tag
signals('newsletter_signup');
signals('purchase', 9900, { order: 'X-1042' });
// or declare it in the markup
<button data-signal="cta_click">Buy</button> <snip-form key="YOUR_FORM_KEY">
<form>
<input name="email"
sf-validate:required
sf-validate:email />
<button>Subscribe</button>
</form>
</snip-form> const form = useSnipForm({
key: 'YOUR_FORM_KEY',
fields: {
email: { type: 'email', rules: { required: null } },
},
});
<SnipForm form={form}>
<input {...form.register('email')} />
</SnipForm> // the browser knows the visitor,
// your backend confirms the money
Snipform::revenue(9900, 'USD');
Snipform::event('order_shipped');
// from a job, pass the id you stored
Snipform::eventFor($id, 'refunded'); Straight there
Build on it
Read analytics, sessions, contacts, conversions and short links. Write events and revenue. Tokens are scoped to one property and the scopes you pick.
Point Claude, Cursor or any MCP client at a property and ask in English. Read-only is enforced in code and covered by a test, not by instructions.
A PHP package with a fluent query builder and a Laravel facade, a React package for forms, and the browser tracker they all feed.
Before you ship it