MaiGuard

SDK Reference

JavaScript SDK

The MaiGuard SDK (Sentinel) runs in the browser, collects behavioral biometrics, and enriches your transaction scoring requests with device-session context.

Note

The MaiGuard JavaScript SDK (Sentinel) is distributed via CDN. Add the script tag below — no NPM install required for browser integration.

Quick start

Get fraud protection running in under five minutes.

  1. 1

    Get your API key

    Sign in to the MaiGuard dashboard and copy your public key from Settings → API Keys. Use pk_test_ during development and pk_live_ in production.

  2. 2

    Add the script tag

    Include the SDK in your HTML <head> before any scoring calls.

    index.html
    <script src="https://cdn.maiguard.com/sdk/v1/maiguard.min.js"></script>
    <script>
      const sentinel = MaiGuard.init('pk_live_xyz123');
      sentinel.watch();
      sentinel.onReady((deviceSessionId) => {
        console.log('SDK ready:', deviceSessionId);
      });
    </script>
  3. 3

    Initialize and start watching

    Call MaiGuard.init() with your public key, then sentinel.watch() to begin collecting behavioral signals.

    init.js
    1const sentinel = MaiGuard.init('pk_live_xyz123');
    2
    3// Start collecting behavioral signals
    4sentinel.watch();
    5
    6// Fires when the device session is ready
    7sentinel.onReady((deviceSessionId) => {
    8  console.log('Device Session ID:', deviceSessionId);
    9  // Store for use in transaction scoring requests
    10});
  4. 4

    Score your first transaction

    Call scoreTransaction() at the point of payment submission. Handle the ALLOW, REVIEW, and BLOCK decisions in your payment flow.

Authentication

The JavaScript SDK uses your public API key — it is safe to include in client-side code and is scoped to behavioral signal collection and transaction scoring only.

Public API Key

Passed directly to MaiGuard.init(). Begins with pk_live_ (production) or pk_test_ (development).

init.js
const sentinel = MaiGuard.init('pk_live_your_key_here');

Server-side secret keys

Secret keys (sk_live_) are used for server-to-server API calls (batch scoring, webhooks, admin endpoints). Never expose them in browser code.

Warning

Never use your secret key (sk_live_) in the browser. The public key is intentionally limited — it cannot access tenant configuration or read scoring history.

Installation

Add the script tag to your HTML — the SDK exposes window.MaiGuard globally.

index.html
<script src="https://cdn.maiguard.com/sdk/v1/maiguard.min.js"></script>
<script>
  const sentinel = MaiGuard.init('pk_live_xyz123');
  sentinel.watch();
  sentinel.onReady((deviceSessionId) => {
    console.log('SDK ready:', deviceSessionId);
  });
</script>

Note

Add this tag once, ideally in <head>, before any code that calls MaiGuard.init().

Initialization

Call MaiGuard.init() once after the script loads, then call sentinel.watch() to begin collecting signals.

init.js
1const sentinel = MaiGuard.init('pk_live_xyz123');
2
3// Start collecting behavioral signals
4sentinel.watch();
5
6// Fires when the device session is ready
7sentinel.onReady((deviceSessionId) => {
8  console.log('Device Session ID:', deviceSessionId);
9  // Store for use in transaction scoring requests
10});

Tip

Use pk_test_ during development and pk_live_ in production. Test-mode events are excluded from your live risk model.

Scoring transactions

Call scoreTransaction() at the point of transaction submission. The SDK automatically attaches the collected device session ID.

See API Reference — Payload shapes for field-level documentation on Minimal, Recommended, and Full / enterprise payloads.

ALLOW

Transaction approved. Proceed with payment.

REVIEW

Elevated risk. Flag for manual review.

BLOCK

High risk. Decline the transaction.

Warning

Always implement a fail-open fallback: if the scoring call throws a network error, allow the transaction and log the failure — never block on SDK unavailability.

Configuration options

config.js
1const sentinel = MaiGuard.init('pk_live_xyz123', {
2  endpoint: 'https://api.maiguard.com',
3  batchSize: 50,
4  batchInterval: 5000,
5  enabled: true,
6  debug: false,
7  sessionId: 'custom_session_id'
8});
OptionTypeDefaultDescription
endpointstringhttps://api.maiguard.comOverride the API base URL.
batchSizenumber50Max events per flush.
batchIntervalnumber5000Flush interval in ms.
enabledbooleantrueSet false to disable all collection.
debugbooleanfalseLog SDK activity to the console.
sessionIdstringautoOverride the auto-generated session ID.

SDK methods

MaiGuard.init(apiKey, options?)

Creates and returns a Sentinel instance. Call this once per page load.

Parameters

apiKeystringrequiredYour public API key (pk_live_ or pk_test_).
optionsobjectoptionalConfiguration overrides. See Configuration options.
ReturnsSentinel instance
sentinel.watch()

Starts collecting behavioral signals (keystrokes, mouse, scroll, device context). Call immediately after init().

Returnsvoid
sentinel.onReady(callback)

Fires once the device session ID is available. The ID is passed to the callback. watch() is asynchronous — always wait for onReady before reading the device session ID.

Parameters

callback(deviceSessionId: string) => voidrequiredReceives the device session ID string.
Returnsvoid
sentinel.onError(callback)

Fires if the SDK encounters an initialization or network error. Use this for logging — do not block the payment flow on SDK errors.

Parameters

callback(error: Error) => voidrequiredReceives the thrown error.
Returnsvoid
sentinel.getDeviceSessionId()

Returns the current device session ID synchronously, or null if the SDK is not ready yet. Prefer onReady() for guaranteed availability.

Returnsstring | null
get-device-session-id.js
const sessionId = sentinel.getDeviceSessionId();
if (sessionId) {
  // SDK ready — include in scoring request
}
sentinel.scoreTransaction(data)

Scores a transaction via the MaiGuard API. Automatically attaches the device session ID. Returns a Promise resolving to the full scoring response — see Response shape below. Send Minimal, Recommended, or Full / enterprise payloads — see Scoring transactions.

Parameters

userIdstringrequiredYour stable user identifier.
amountnumberrequiredTransaction amount.
currencystringrequiredISO 4217 code (e.g. NGN, USD).
occurredAtstringoptionalISO 8601 timestamp when the transaction occurred.
ipAddressstringoptionalClient IP address.
userAgentstringoptionalBrowser user-agent. Use navigator.userAgent.
deviceIdstringoptionalDevice fingerprint.
deviceSessionIdstringoptionalAuto-attached from watch() if omitted.
locationobjectoptionalGeographic coordinates: { latitude, longitude }.
metadataobjectoptionalBusiness context: countryCode, product, paymentMethod, orderId, channel, etc.
eventobjectoptionalFull / enterprise — schema 1.1 event envelope.
transactionobjectoptionalFull / enterprise — kind, direction, channel, paymentMethod, product.
actorobjectoptionalFull / enterprise — initiating party.
accountobjectoptionalFull / enterprise — source account.
counterpartyobjectoptionalFull / enterprise — beneficiary for screening.
merchantobjectoptionalFull / enterprise — merchant context.
sessionobjectoptionalFull / enterprise — auth session context.
deviceobjectoptionalFull / enterprise — device profile.
networkobjectoptionalFull / enterprise — ipAddress, userAgent.
geoobjectoptionalFull / enterprise — latitude, longitude, countryCode.
behavioralobjectoptionalFull / enterprise — behavioral biometrics.
loginContextobjectoptionalLogin context for ATO signals.
ReturnsPromise<ScoringResponse>
sdk-method.js
// scoreTransaction() resolves to the inner data object (SDK unwraps the API envelope)
{
  "transactionId": "550e8400-e29b-41d4-a716-446655440000",
  "riskScore": 42,
  "decision": "REVIEW",
  "matchedRules": [
    {
      "ruleId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "ruleName": "High velocity — 1 hour",
      "action": "REVIEW",
      "priority": 10
    }
  ],
  "velocity": 6,
  "shadowEvaluation": {
    "hasShadowRules": true,
    "shadowDecision": "BLOCK",
    "shadowRiskScore": 78
  },
  "patternAnalysis": {
    "hasAnomalies": true,
    "totalAnomalyScore": 35,
    "amountAnomaly": { "deviation": 2.4, "isAnomaly": true },
    "botDetection": { "isBot": false, "score": 12 }
  },
  "mlEvaluation": {
    "available": true,
    "score": 0.72,
    "confidence": 0.85,
    "modelVersion": "global_txn_autogluon_live_v1"
  }
}
sentinel.stop()

Pauses event collection without destroying the instance. Call watch() again to resume.

Returnsvoid
sentinel.destroy()

Permanently tears down the instance, removes all listeners, and clears the session. Call in component cleanup (useEffect return, ngOnDestroy, etc.).

Returnsvoid
sentinel.onSent(callback)

Fires after a successful batch send to the API.

Parameters

callback(batchSize: number) => voidrequiredReceives the number of events sent.
Returnsvoid
sentinel.onFailed(callback)

Fires when a batch send fails.

Parameters

callback(error: Error) => voidrequiredReceives the send failure reason.
Returnsvoid

Framework examples

Full payment-form integration examples for common frontend frameworks.

PaymentForm.jsx
1import { useEffect, useRef, useState } from 'react';
2
3function PaymentForm() {
4  const [sdkReady, setSdkReady] = useState(false);
5  const sentinelRef = useRef(null);
6
7  useEffect(() => {
8    const script = document.createElement('script');
9    script.src = 'https://cdn.maiguard.com/sdk/v1/maiguard.min.js';
10    script.async = true;
11
12    script.onload = () => {
13      const sentinel = window.MaiGuard.init('pk_live_xyz123', {
14        debug: process.env.NODE_ENV === 'development'
15      });
16      sentinelRef.current = sentinel;
17      sentinel.watch();
18      sentinel.onReady(() => setSdkReady(true));
19      sentinel.onError((err) => console.error('MaiGuard SDK error:', err));
20    };
21
22    document.head.appendChild(script);
23
24    return () => {
25      sentinelRef.current?.destroy();
26    };
27  }, []);
28
29  const handleSubmit = async (e) => {
30    e.preventDefault();
31    if (!sentinelRef.current) return;
32
33    try {
34      const result = await sentinelRef.current.scoreTransaction({
35        userId: getCurrentUserId(),
36        amount: parseFloat(e.target.amount.value),
37        currency: 'NGN',
38        occurredAt: new Date().toISOString(),
39        userAgent: navigator.userAgent,
40        location: { latitude: 6.4474, longitude: 3.3903 },
41        metadata: {
42          countryCode: 'NG',
43          product: 'Collections',
44          paymentMethod: 'card',
45          environment: 'LIVE',
46          type: 'purchase',
47          orderId: crypto.randomUUID(),
48          channel: 'web',
49        },
50      });
51
52      if (result.decision === 'BLOCK') return;
53      processPayment(e.target);
54    } catch {
55      processPayment(e.target); // fail open
56    }
57  };
58
59  return (
60    <form onSubmit={handleSubmit}>
61      <input type="number" name="amount" placeholder="Amount" required />
62      <button type="submit" disabled={!sdkReady}>Pay</button>
63    </form>
64  );
65}

Privacy & data collection

The SDK collects only behavioral and device signals needed for fraud detection. It never reads form field values.

Collected

  • Keystroke timing patterns
  • Mouse movement trajectories
  • Scroll velocity & behavior
  • Device fingerprint signals
  • Session interaction events

Never collected

  • Passwords or PINs
  • Card numbers or CVVs
  • Personally identifiable information
  • Form field contents

Note

All behavioral data is transmitted over TLS and processed server-side. No raw events are stored permanently — only the derived device session ID.

Was this page helpful?