Skip to content
Private betaTreebars is letting teams in from the waitlist.Join the waitlist

Quickstart

Three steps. The samples below fill in your own ids when you are signed in.

1. Install

bash
npm install @treebars/web-sdk

2. 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.

ts
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

ts
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:

ts
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:

bash
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.

bash
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.