Docs · Reference

JavaScript SDK

@ageassure/js opens a session’s hosted url in a centered popup and reports the result — no iframe, no polling on your end. Zero dependencies, built as both an ES module and a ~1.5 kB minified script-tag build.

Install

Via npm

shell
npm install @ageassure/js
javascript
import { AgeAssure } from "@ageassure/js";

AgeAssure.open({
  url: session.url, // from POST /v1/verification-sessions
  onComplete: ({ sessionId, status }) => {
    if (status === "passed") {
      // unlock whatever was age-gated
    } else {
      // show the "not verified" state — offer another method or exit
    }
  },
});

Via a script tag

No build step: download ageassure.min.js from the @ageassure/js npm package’s dist/ folder and self-host it (a hosted CDN URL is coming — this page will be updated with it). It defines a single window.AgeAssure global with the same open() API.

html
<script src="/vendor/ageassure.min.js"></script>
<script>
  AgeAssure.open({
    url: session.url,
    onComplete: function (result) {
      console.log(result.sessionId, result.status);
    },
  });
</script>

AgeAssure.open(options)

FieldTypeDescription
urlrequiredstringThe session url from POST /v1/verification-sessions.
onCompleterequired(result) => voidCalled once with { sessionId, status } where status is "passed" or "failed", when the session reaches that outcome.
onClose() => voidPopup mode only. Called if the user dismisses the popup before a result arrives — a distinct outcome from failed, since nothing was actually checked.
mode"popup" | "redirect""popup" (default): open a ~480×760 centered popup. "redirect": navigate the current page to url instead — onComplete/onClose are never called in this mode, since the page navigates away; rely on the return_url redirect and/or a webhook instead.

Returns a handle with a close() method for tearing things down early (e.g. on your own component unmount) — most callers can ignore the return value.

The postMessage contract

Under the hood, the hosted flow’s result screen posts one message to window.opener before it redirects/closes:

json
{ "type": "ageassure:result", "sessionId": "vs_...", "status": "passed" }

It’s sent with target origin "*" — the payload carries no secret, only a session id and a pass/fail status. The SDK checks the message’s type and shape before acting on it, and as defense in depth also drops any message whose event.origin doesn’t match the origin of the url you opened. If you’re handling the postMessage yourself instead of using the SDK, confirm result.sessionId matches a session you actually created before trusting status — see the full example below.

Full example

javascript
import { AgeAssure } from "@ageassure/js";

async function startVerification() {
  const res = await fetch("/api/verify/start", { method: "POST" }); // your own server route,
  const session = await res.json();                                 // which calls AgeAssure's API

  AgeAssure.open({
    url: session.url,
    mode: "popup", // default — "redirect" navigates the current page instead
    onComplete: ({ sessionId, status }) => {
      if (sessionId !== session.id) return; // defense in depth — see below
      renderResult(status);
    },
    onClose: () => {
      // user closed the popup before finishing — no result yet
      renderDismissed();
    },
  });
}