Skip to main content
You control two parts of every Bily browser event: a stable name and an optional payload. The JavaScript SDK prepares both for delivery and adds a small amount of browser context.

Give every event a clear shape

track("checkout_completed", {
  event_id: "checkout_01J2M8YQ7B",
  ts: "2026-07-13T08:30:00.000Z",
  checkout_id: "checkout_123",
  plan: "growth",
});
PartPurpose
Event nameStable description of the outcome
Typed fieldsclient, products, order, page, and search context
Custom propertiesApplication-specific IDs, categories, and safe state
event_idIdentifier for one logical outcome
tsISO timestamp for the event
When event_id or ts is missing, the SDK creates it. A generated event ID helps with correlation. track() does not acknowledge ingestion or promise exactly-once delivery.

Name outcomes consistently

Use Bily’s current title-case names for ecommerce events. Use stable snake_case names for application events. Good application event names:
  • workspace_created
  • integration_connected
  • billing_checkout_completed
  • product_error_encountered
Keep customer IDs, timestamps, translated labels, and UI positions out of event names. Put changing context in properties. Event names are case-sensitive. The SDK accepts documented compatibility aliases. New code should use the current names in the event reference.

Track an outcome only when it is true

Send an event only after the state it names is true.
const workspace = await createWorkspace(input);

track("workspace_created", {
  workspace_id: workspace.id,
  plan: workspace.plan,
});
A button click does not prove completion when the operation can still fail. If you need to analyze failures, send a separate event with a small, safe error vocabulary.

Keep commerce data typed

Use products for product, cart, and checkout activity. Each product requires id, name, price, and currency.
track("Product Added", {
  products: [
    {
      id: "product_123",
      name: "Everyday Tee",
      price: 39,
      currency: "USD",
      quantity: 2,
    },
  ],
});
Use order when an event represents one order. Put its products in order.products.
track("Order Completed", {
  order: {
    id: "order_789",
    currency: "USD",
    total: 78,
    products: [
      {
        id: "product_123",
        name: "Everyday Tee",
        price: 39,
        currency: "USD",
        quantity: 2,
      },
    ],
  },
});
When order.total is missing, the SDK calculates it from product price and quantity. Total, tax, discount, and shipping values can all be zero.

Add only the customer context you need

The optional client object applies only to the event you send.
track("user_signed_in", {
  client: {
    userId: "user_123",
    userGroup: "growth",
  },
});
Prefer a stable internal userId to extra contact fields. Add email, phone, address, date of birth, or gender only when you have a documented need and permission.

Preserve page and acquisition context

Use typed page fields when an explicit event needs that context:
track("PageView", {
  sourceUrl: window.location.href,
  pageTitle: document.title,
  referrer: document.referrer,
});
sourceUrl and referrer are inputs. They do not define a public first-touch or last-touch attribution rule. Use Bily’s returned analytics fields as the reporting contract. Do not infer undocumented identity merging or attribution behavior.

Give each property one meaning and type

Keep the meaning and type of every property stable.
PropertyRecommended value
IDsStable string or documented numeric ID
CurrencyConsistent currency code string
MoneyFinite number in the unit your event plan defines
FlagsBoolean, not "true" or "false"
TimeISO timestamp string in ts
CategorySmall controlled vocabulary
Do not change a released property from a number to a formatted string. If its meaning changes, add a new, clearly named property.

Prepare the contract for review

For each event, record:
  • the exact name and owner;
  • the successful trigger;
  • required and optional fields;
  • field types and allowed values;
  • customer-data classification;
  • an example payload;
  • a test and expected result.

Payload reference

See every typed SDK field.

Validate the model

Prove the names, payloads, and firing behavior before you release.