Quickstart
Three steps. The samples below fill in your own ids when you are signed in.
1. Install
npm install @treebars/web-sdk2. Initialise
The write key names your project AND the environment events land in, and it is safe to ship in page source — it grants write-only access to ingest and nothing else. Signed in, the samples below carry your own; the switcher in the rail decides which environment's. Every key is also under Settings → Write keys.
You do not need to supply a URL: every SDK defaults to https://ingest.treebars.com. Set ingestUrl only to point somewhere else.
import treebars from '@treebars/web-sdk';
treebars.init({ writeKey: '<your-write-key>' });The highlighted ids above are blanks until you sign in.
3. Send an event
treebars.identify('user_123', { plan: 'pro' });
treebars.track('signup_completed', { plan: 'pro' });That is enough in a test environment. In a live one, identify also needs a signature from your server, or the sign-in is not recorded and the person's messages are withheld — one line of HMAC.
Not sending your own user id? Pass null in its place — identify(null, { plan: 'pro' }) — and the attributes go on the person Treebars already knows this device as, carried into their account if they sign in later. An email or a phone number is kept only with a user id, and it never signs anybody out — that is reset(). The same call, in the same order, on every SDK.
When they sign out, call treebars.reset(). From then on that browser or phone is a new anonymous visitor, kept apart from the account. Whoever signs in on it next takes that visitor's activity with them — the same account, or a new one.
What a property can hold
Text, a number, true or false, a date, a list, or an object. Each is something you can filter, break down and target by:
treebars.track('purchase', {
value: 129, // a number
gift: true, // true / false
delivers_at: '2026-03-04T10:00:00Z', // a date: "delivers_at is before 5 March"
tags: ['new', 'sale'], // a list: "tags contains any of sale"
delivery: { method: 'express' }, // an object, read by its path: delivery.method
line_items: [ // a list of objects: one list per field,
{ category: 'shoes', qty: 1 }, // line_items.category = shoes, bags
{ category: 'bags', qty: 2 },
],
});A list is asked which items it holds — contains any of, all of, or none of — and its items are compared as text, exactly and by case. With a list of objects, each field is its own list, so line_items.category holds every category in the order; the fields of one item are not kept together, so “an item that is shoes and has a quantity of 2” cannot be asked. A list keeps its first hundred different items, and an object is read five levels deep.
A date is sent as an ISO 8601 string — 2026-03-04, or with a time and a zone, as toISOString() writes it — or as a Unix timestamp in seconds or milliseconds. Pick “date” as the condition's type and it is asked whether it is on, before, after or between days, each a whole day in UTC; a time with no zone is read as UTC. Anything else, such as 03/04/2026, is kept as text and matches no date condition.
Confirm it arrived
Live shows events as they land. Or ask the API directly — this one is about your project:
curl 'https://api.treebars.com/analytics/event-names?project_id=<your-project-id>' \
-H 'Authorization: Bearer sk_…'The highlighted ids above are blanks until you sign in.
Server-side
A server sends with a secret key, never the write key: make one under Settings → API keys → Send server events, choosing the environment its events land in. The body is Segment's, so Segment's and RudderStack's server libraries work pointed at https://api.treebars.com as they are.
curl -X POST https://api.treebars.com/v1/track \
-H 'Authorization: Bearer sk_…' \
-H 'Content-Type: application/json' \
-d '{
"userId": "user_123",
"event": "signup_completed",
"properties": { "plan": "pro" }
}'For a purchase your backend or a store confirms, send the app's context token with it so it lands on the same person, device and session.