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
| Call | Returns | What it does |
|---|---|---|
Lunixi.configure(config) | — | Sets defaults applied to every client created afterwards. Optional. |
Lunixi.identity.createClient(config) | client | Builds 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
| Method | Returns | Purpose |
|---|---|---|
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() | session | The 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
| Field | Description |
|---|---|
apiBaseUrl | Override the API host. Defaults to the hosted gateway (https://api-gateway.lunixi.com). |
platformBaseUrl | Override the platform host, if you split gateway and platform traffic. |
allowedOrigin | The 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:
| Field | Description |
|---|---|
sessionBootstrap(fn) | An async function the SDK calls to fetch the session from your backend. |
sessionBootstrapUrl | A backend URL the SDK fetches the session from (a proxy of POST /identity/sdk/init). |
sessionData | A session object you already fetched server-side and inject directly. |
See Authentication › Bootstrap patterns.
Identity & context
| Field | Description |
|---|---|
subjectId | Who you are scoring (your customer/user id). |
paymentId / checkoutSessionId | Tie the analysis to a payment or checkout session for later querying. |
integrationMode | How the SDK is embedded in your flow. |
productContext | The business context, e.g. checkout, login, signup. |
payment, walletOperation, customer, account | Structured business context relevant to the event being scored. |
Telemetry
| Field | Description |
|---|---|
device, telemetry, network, session, source | Telemetry the SDK collects and/or you supplement. |
metadata | Free-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 method | HTTP 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
- The Risk Snapshot — every field
analyze()returns. - Authentication — publishable key, session token and bootstrap in detail.
- Device & Continuity · Bot & Automation — the signals the SDK feeds.