Skip to main content
Tripwire’s browser surface is intentionally small. Import t.js, call start(), and call getSession() when the user performs a sensitive action.
const Tripwire = await import("https://cdn.tripwirejs.com/t.js");
const tripwire = await Tripwire.start({ publishableKey: "pk_live_..." });

// At action time (signup, login, checkout)
const { sessionId, sealedToken } = await tripwire.getSession();

Load and initialize

Start Tripwire as early as possible on your page. The SDK begins collecting signals immediately.
<script type="module">
  const tripwirePromise = import("https://cdn.tripwirejs.com/t.js")
    .then((Tripwire) =>
      Tripwire.start({ publishableKey: "pk_live_your_publishable_key" })
    );

  const tripwire = await tripwirePromise;

  // Optional: subscribe to errors
  tripwire.onError((error) => {
    console.error(error.code, error.message);
  });

  // Optional: pre-warm fingerprinting
  void tripwire.waitForFingerprint().catch(console.error);
</script>

API reference

Module exports

ExportDescription
start({ publishableKey })Bootstrap the runtime and start collection. Returns a TripwireClient.
versionSDK bundle version string.

TripwireClient

MethodReturnsDescription
getSession()Promise<{ sessionId, sealedToken }>Flush pending observations and return a sealed handoff for your backend.
waitForFingerprint()Promise<void>Resolve when fingerprinting is complete. No identity data is returned.
onError(handler)() => void (unsubscribe)Subscribe to TripwireError events.
destroy()voidStop timers and tear down the runtime.

Getting a session handoff

Call getSession() right before the protected action — not on page load.
async function submitSignup(formData) {
  const { sessionId, sealedToken } = await tripwire.getSession();

  await fetch("/api/signup", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      ...formData,
      tripwire: { sessionId, sealedToken },
    }),
  });
}
The handoff contains:
{
  "sessionId": "sid_7m2k9x4v8q1n5t3w6r0p2c4y8h",
  "sealedToken": "AQAA..."
}
Every call produces a fresh handoff. The browser never receives verdicts, scores, or visitor IDs.

Error handling

All async methods reject with a structured TripwireError:
{
  "code": "config.validation_failed",
  "message": "Tripwire start options are invalid.",
  "retryable": false,
  "fatal": true,
  "operation": "start",
  "details": {
    "fieldErrors": [{ "field": "publishableKey", "issue": "required" }]
  }
}
FieldDescription
codeStable identifier like config.validation_failed or transport.upgrade_required
retryableWhether retrying may succeed
fatalWhether the runtime is in a terminal state
operationThe failing operation (start, wait_for_fingerprint, get_session)

Best practices

  • Start early — initialize on page load, not at action time
  • Call getSession() late — right before the sensitive action for the freshest signal data
  • Handle errors gracefully — if the SDK fails, your app should still work (degrade to a fallback policy)
  • Don’t expose verdicts client-side — the browser API intentionally doesn’t return them

What’s next