Skip to main content

Node.js (server SDK)

@simplr-ai/node is Simplr's server-side SDK. Use it from your backend to run fraud/identity checks, score orders, ingest edge logs, and verify webhook signatures — all with your secret key.

For client-side device signals, RUM, and feature-flag evaluation, use the browser SDK @simplr-ai/js or the Flutter SDK. Secret keys must never ship to a client.

Install

npm install @simplr-ai/node

Requires Node 18+ (uses built-in fetch and crypto).

Initialize

import { Simplr } from "@simplr-ai/node";

const simplr = new Simplr({ apiKey: process.env.SIMPLR_API_KEY! }); // sk_live_… / sk_test_…

baseUrl defaults to https://api.simplr-ai.com; override for local/dev:

new Simplr({ apiKey: "sk_test_…", baseUrl: "http://localhost:7002", timeoutMs: 15000 });

Checks

const result = await simplr.check({ email: "user@example.com", event_type: "signup" });
// result.risk_score, result.risk_level, result.signals
await simplr.check({ phone: "+14155550100", event_type: "login" });
await simplr.checkBulk([{ email: "a@x.com" }, { phone: "+1..." }]); // up to 100

Orders

await simplr.orders.submit({ order_id: "o_1", external_id: "cust_1", amount: 249, currency: "USD" });
await simplr.orders.submitBulk([/* up to 100 */]);

Phone intelligence

await simplr.phone.report({ phone: "+14155550100", outcome: "sim_swap_fraud", confidence: 0.9 });
await simplr.phone.intelligence("+14155550100");

Edge devices & logs

await simplr.edge.registerDevice({ device_id: "POS-0042", name: "Front till" });
await simplr.edge.heartbeat("POS-0042", { cpu: 0.34, battery: 0.78 });
await simplr.edge.ingestLogs("POS-0042", [{ category: "transaction", level: "info", message: "sale ok" }]);

Verifying webhooks

Verify the X-Simplr-Signature header against the raw request body (don't re-serialize parsed JSON):

import express from "express";
import { Simplr } from "@simplr-ai/node";

const simplr = new Simplr({ apiKey: process.env.SIMPLR_API_KEY! });
const app = express();

app.post("/hooks/simplr", express.raw({ type: "application/json" }), (req, res) => {
const sig = req.header("X-Simplr-Signature")!;
try {
const event = simplr.webhooks.constructEvent(req.body, sig, process.env.SIMPLR_WEBHOOK_SECRET!);
// handle event.event / event.data
res.sendStatus(200);
} catch {
res.sendStatus(400); // invalid signature
}
});
  • webhooks.verify(payload, header, secret, { toleranceSec })boolean
  • webhooks.constructEvent(payload, header, secret) → parsed event, or throws WebhookVerificationError

The signature is HMAC-SHA256 over `${timestamp}.${rawBody}` (header format t=…,v1=…), with a default 5-minute timestamp tolerance.

Server-side feature flags

Evaluate flags on your backend. Flag config is read with a public key (pk_…), so pass one alongside the secret key; evaluation is local and deterministic (same bucketing as the browser SDK, so a user buckets identically on client and server).

const simplr = new Simplr({
apiKey: process.env.SIMPLR_API_KEY!, // sk_… for checks/orders
publicKey: process.env.SIMPLR_PUBLIC_KEY!, // pk_… for flags
});

await simplr.flags.initialize();
simplr.flags.setUser("user_123");

if (simplr.flags.isEnabled("new-checkout")) {
// gate a backend code path
}
simplr.flags.isEnabled("beta", { userId: "u1", attributes: { plan: "growth" } });

SimplrFlags is also exported for standalone use.

Admin & measurement (SimplrAdmin)

Dashboard operations — usage/measurement, feature-flag CRUD, and RUM analytics — require a portal token (JWT), not an API key. They live on a separate client:

import { SimplrAdmin } from "@simplr-ai/node";

const admin = new SimplrAdmin({ token: process.env.SIMPLR_PORTAL_TOKEN! });

await admin.usage.stats(orgId); // usage counters
await admin.usage.billing(orgId); // per-service totals + estimated cost
await admin.flags.create(orgId, { key: "new-checkout", environment: "test", rollout_percentage: 10 });
await admin.flags.update(orgId, flagId, { rollout_percentage: 50 });
await admin.flags.history(orgId, flagId, { limit: 20 });
await admin.rum.overview(orgId, { application_id: "my-app" });
await admin.rum.sessions(orgId, { page: 1, limit: 50 });

Errors

Non-2xx responses throw SimplrError with .status and .body.

import { SimplrError } from "@simplr-ai/node";

try {
await simplr.check({ email: "user@example.com" });
} catch (err) {
if (err instanceof SimplrError) console.error(err.status, err.body);
}