Identity
Web SDK

Web SDK

The Web SDK collects device and behavioral telemetry in the browser and requests the identity risk snapshot for you. It is headless — there is no widget, iframe or UI to mount. You script it: create a client, init() a signed session, then analyze() and track(). Under the hood it calls the /identity/sdk/* endpoints with a session token; your secret key never touches the page.

Load it from https://cdn.lunixi.com:

<script src="https://cdn.lunixi.com/lunixi-identity.min.js"></script>

The global is Lunixi. Authentication is via a signed SDK session token minted by your backend — see Authentication.

The global API

CallReturnsWhat it does
Lunixi.configure(config)—Sets defaults applied to every client created afterwards. Optional.
Lunixi.identity.createClient(config)clientBuilds a client without initialising it. You call init() yourself.
Lunixi.identity.init(config)Promise<client>Convenience: builds a client and awaits init() — an initialised client.
const client = await Lunixi.identity.init({
  sessionBootstrapUrl: '/lunixi/identity/session',
  subjectId: 'cus_8f2a9c',
  productContext: 'checkout',
});
const snapshot = await client.analyze();

Client methods

MethodReturnsPurpose
init()Promise<void>Runs the bootstrap and obtains the signed SDK session token. Required before analyze/track.
analyze()Promise<snapshot>Requests a synchronous identity risk snapshot for the current session and context.
track(eventType, payload)Promise<void>Streams one interaction event to enrich the behavioral signal.
trackBatch(events)Promise<void>Streams an array of events in one call.
compatibility()Promise<result>Reports SDK/environment capability and policy — no auth required.
getSession()sessionThe current SDK session (token, endpoints) held in memory.

analyze()

analyze() is the core call: it gathers the collected telemetry, sends it with the session token, and resolves to the flat snapshot — identityRiskLevel, riskScore, per-domain signals, reasonCodes, findings. Read the fields you need and apply your own policy.

const snapshot = await client.analyze();
if (snapshot.identityRiskLevel === 'high' || snapshot.identityRiskLevel === 'critical') {
  // your decision — the SDK does not block for you
}

track() and trackBatch()

Events feed the behavioral signal over the life of a session (a wallet transfer click, a step reached, a field focused). The event type is a free string — there is no fixed enum; the default type is sdk_event.

await client.track('wallet_transfer_click', { amount: 25000, currency: 'TRY' });
 
await client.trackBatch([
  { type: 'step_reached', payload: { step: 'review' } },
  { type: 'field_focus',  payload: { field: 'iban' } },
]);

Configuration

Config is passed to configure, createClient or init. All fields are optional except a bootstrap source.

Connection

FieldDescription
apiBaseUrlOverride the API host. Defaults to the hosted gateway (https://api-gateway.lunixi.com).
platformBaseUrlOverride the platform host, if you split gateway and platform traffic.
allowedOriginThe origin the session is bound to. Defaults to window.location.origin.

Session bootstrap (one required)

The SDK never holds a key — it obtains a signed session from your backend via one of these:

FieldDescription
sessionBootstrap(fn)An async function the SDK calls to fetch the session from your backend.
sessionBootstrapUrlA backend URL the SDK fetches the session from (a proxy of POST /identity/sdk/init).
sessionDataA session object you already fetched server-side and inject directly.

See Authentication › Bootstrap patterns.

Identity & context

FieldDescription
subjectIdWho you are scoring (your customer/user id).
paymentId / checkoutSessionIdTie the analysis to a payment or checkout session for later querying.
integrationModeHow the SDK is embedded in your flow.
productContextThe business context, e.g. checkout, login, signup.
payment, walletOperation, customer, accountStructured business context relevant to the event being scored.

Telemetry

FieldDescription
device, telemetry, network, session, sourceTelemetry the SDK collects and/or you supplement.
metadataFree-form key/value data echoed onto the analysis.

Internal fields are stripped from the response and are not part of the public payload. Provide only the context above; do not depend on internal metadata keys.

Token rotation

The session token is short-lived. When a call returns a refreshed token, the SDK rotates to it automatically — you do not manage token lifetime yourself. Sessions are origin-bound: a token minted for one origin is refused elsewhere.

Error handling — not fail-open

⚠️

The SDK is not fail-open. If init(), analyze() or track() fails, it throws or rejects — it does not silently return a "pass". You own the fallback: wrap calls in try/catch and decide how your flow behaves when a snapshot is unavailable (proceed, add friction, or hold).

try {
  const client = await Lunixi.identity.init({ sessionBootstrapUrl: '/lunixi/identity/session' });
  const snapshot = await client.analyze();
  // apply your policy on snapshot.identityRiskLevel
} catch (err) {
  // your decision when identity signal is unavailable
}

The one graceful degradation is size: a payload over 48 KB is truncated rather than rejected, and the response is flagged with __sdkTruncated: true so you know the telemetry was trimmed.

The equivalent HTTP calls

The SDK is a thin client over the /identity/sdk/* endpoints. Each method maps to a request carrying the session token as Authorization: Bearer <token> — the token is only in the header, never in the body.

SDK methodHTTP call
init()POST /identity/sdk/init (via your backend, publishable key) → session token
analyze()POST /identity/sdk/live-sessions/analyze-sync
track(...)POST /identity/sdk/live-sessions/event
trackBatch(...)POST /identity/sdk/live-sessions/events/batch
compatibility()POST /identity/sdk/compatibility (public)
# What analyze() sends, by hand:
curl -X POST "https://api-gateway.lunixi.com/api/v1/identity/sdk/live-sessions/analyze-sync" \
  -H "Authorization: Bearer <sdk-session-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "subjectId": "cus_8f2a9c",
    "productContext": "checkout"
  }'

Scoring a backend event instead of a browser session? Skip the SDK and call the server-side endpoints with your secret key — see Server-side API & Queries.

Next steps