Introduction
GetFluxly is a customer data platform built around behavior-triggered email. You capture events from your product through a JavaScript SDK or an HTTP API, those events flow onto a unified customer profile, and automations send lifecycle messages through the email provider you already operate.
This page is the 10-minute version. By the end of it, you'll have the SDK installed, an event flowing into your workspace, a profile identified, and an automation triggered on a real event.
Quickstart
Three steps. Each one is independently useful: if you stop after step 1, you still have analytics; after step 2, you have profiles; after step 3, you have lifecycle email.
1. Install the SDK
Drop a script tag or npm install. About 7KB minified.
2. Identify users
Call identify when a user signs in. Anonymous activity stitches automatically.
3. Track key events
Auto-capture handles pageviews. Track 5–10 custom events that matter.
Install
The browser SDK ships as @getfluxly/browser on npm. Use either npm (or pnpm / yarn) for bundled apps, or a CDN script tag for static sites.
$ npm install @getfluxly/browserBundled apps should call initGFlux directly. Script tag installs read window.__GFLUX__ and boot on DOMContentLoaded. Auto-capture for pageviews, clicks, form submits, and page-leave starts on its own.
Configuration
Pass config to initGFlux before the SDK attaches listeners. The fields below are the common set; the only required one is apiKey.
import { initGFlux } from "@getfluxly/browser";
const gflux = initGFlux({
apiKey: "gflux_pub_live_your_key",
apiHost: "https://api.getfluxly.com",
autocapture: {
pageviews: true,
clicks: true,
forms: true,
pageLeave: true
},
flushIntervalMs: 3000,
flushQueueSize: 10,
maxRetries: 3
});
gflux?.page();| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | required | Your project's browser API key. Format: gflux_pub_live_…. |
apiHost | string | api.getfluxly.com | Override for self-hosted or proxied ingest. |
autocapture | object | all on | Toggle individual auto-capture features. |
flushIntervalMs | number | 3000 | How often the queue is flushed to the API, in ms. |
flushQueueSize | number | 10 | Flush early when this many events are queued. |
maxRetries | number | 3 | How many times a failed batch is retried. |
identify()
Tie the current browser session to a known user. Call this the moment you have a stable user ID, typically right after sign-in or sign-up.
window.gflux?.identify("usr_847", {
email: "neo@zion.dev",
plan: "free",
name: "Jane Doe"
});What happens behind the scenes: Any events captured under the anonymous ID are stitched onto the identified profile. Subsequent events on this device will go to usr_847 directly. Call reset() on logout or account switch before identifying another user.
track()
Send a custom event. Auto-capture handles pageviews, clicks, and form submits; track is for the events that matter to your lifecycle: sign-ups, activations, upgrades, feature uses.
window.gflux?.track("pricing_viewed", {
plan: "team",
source: "nav"
});
window.gflux?.track("subscription_started", {
plan: "team",
amount_cents: 4900,
trial: false
});past_tense_snake_case: pricing_viewed, not view_pricing. This makes segment language read naturally: users who did pricing_viewed ≥ 3 times.reset()
Clear the user identity. Call this on logout so the next visitor on the same browser starts a fresh anonymous session.
window.gflux?.reset();destroy()
Tear down the SDK, flush any queued events, and remove all browser listeners. Useful in single-page apps that swap analytics tools at runtime.
window.gflux?.destroy();Node SDK
Backend apps should use @getfluxly/node for lifecycle events like billing webhooks, sign-ups, job completions, and server-side profile stitching.
import { initGFluxNode } from "@getfluxly/node";
const gflux = initGFluxNode({
token: process.env.GFLUX_SERVER_TOKEN,
apiHost: "https://api.getfluxly.com"
});
await gflux.track("subscription_started", {
userId: "usr_847",
properties: {
plan: "team",
amount_cents: 4900
}
});
await gflux.identify({
anonymousId: "anon_abc",
userId: "usr_847",
traits: {
plan: "team"
}
});Use a gflux_secret_live_… key here. Never ship that key to browser code. identify stitches earlier anonymous activity to the known user, and alias can link anonymous-like IDs from trusted backend workflows.
HTTP Events API · Authentication
Server-side events use the HTTP Events API with a secret server token. Tokens have the format gflux_secret_live_…. Never put a server token in browser code.
curl -X POST https://api.getfluxly.com/v1/events \
-H "Authorization: Bearer gflux_secret_live_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{
"event": "subscription_started",
"external_id": "usr_847",
"properties": {
"plan": "team",
"amount_cents": 4900
},
"occurred_at": "2026-05-06T14:32:11Z"
}'POST /v1/events
Send a single event. Use this for low-volume server-side workflows (webhooks, billing events). For higher volume, use /v1/events/batch.
| Field | Type | Required | Notes |
|---|---|---|---|
event | string | yes | Event name. past_tense_snake_case. |
external_id | string | one of | Identified user. Either this or anonymous_id. |
anonymous_id | string | one of | Anonymous session ID, if pre-identify. |
properties | object | no | Up to 64 keys. Strings, numbers, and booleans only. |
occurred_at | ISO 8601 | no | Defaults to server-receive time. |
POST /v1/events/batch
Send up to 50 events in a single request. Recommended for backfills, server-side workers, and any environment where round-trip latency matters. The browser SDK uses this endpoint internally for its periodic flushes.
curl -X POST https://api.getfluxly.com/v1/events/batch \
-H "Authorization: Bearer gflux_secret_live_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"event": "checkout_started",
"external_id": "usr_847",
"properties": { "cart_total_cents": 4900 }
},
{
"event": "order_placed",
"external_id": "usr_847",
"properties": { "order_id": "ord_456" }
}
]
}'Errors and retries
The API uses standard HTTP status codes. 2xx means accepted; 4xx means stop and fix the request; 5xx means retry with exponential backoff. Ingest is at-least-once, so your backend should tolerate duplicate retries after an unknown network outcome.
| Status | Meaning | Recommended action |
|---|---|---|
202 | Accepted, queued | No action needed. |
400 | Bad request | Inspect the response body. Do not retry. |
401 | Unauthorized | Check your server token. |
429 | Rate limited | Honour the Retry-After header. |
5xx | Server error | Retry with backoff. Use idempotency keys. |
Unified profiles
Every event lands on a profile, which is a single record holding a user's identifiers, traits, and the full event timeline. Profiles update in place. There's no nightly rebuild and no "yesterday's view" of who someone is.
Identity stitching
When you call identify(user_id), the SDK posts an identity link. The platform walks any anonymous IDs seen on that device and merges their event history into the identified profile. The merge is deterministic and reversible. Every link is logged and can be inspected (or undone) on the Identity links page in the Console.