EPErgoport
Pure play transmitter
Ergoport never receives or stores identity data from your users. The user holds their own verified credential. You receive a signal. The safest place for identity is somewhere it isn't stored.

Quickstart

Add one script tag to your age gate. That is the entire integration.

HTML
<!-- Add to your age gate page -->
<script
  src="https://cdn.ergoport.com/widget.js"
  data-key="pk_live_YOUR_PLATFORM_KEY"
  data-email-hash="OPTIONAL_SHA256_EMAIL_HASH"
  data-session-id="OPTIONAL_SESSION_ID"
></script>

Listen for the verified postMessage event to receive the signal:

JavaScript
window.addEventListener("message", function(e) {
  // Always verify origin
  if (e.origin !== "https://cdn.ergoport.com") return;

  const { event, verified, human_verified, app_confirmed, method } = e.data;

  if (event === "verified" && verified === true) {
    // Age verified — lift your age gate
    grantAccess();
  }
});

Platform Types

Your platform type is set at onboarding and tied to your API key. The widget reads it on load — you cannot change it at runtime.

HEAA Highly Effective
Required for platforms hosting primary priority content under the UK Online Safety Act. App-only verification. Highest compliance bar.
Standard Non-HEAA
For platforms with duty of care obligations. App, mweb, or email OTP verification paths. Suitable for AI companion, social, gaming platforms.

Widget Parameters

Parameter Required Description
data-key required Your platform API key. Begins with pk_live_. Never use your secret key in the widget.
data-email-hash optional SHA-256 of the normalised email: SHA256(lowercase(trim(email))). Enables identity-linked flows. Omit for anon flow.
data-consent-ts optional Unix timestamp of prior consent. Include for returning user re-verification flows. Omit on first-time verification.
data-session-id optional Your own session identifier. Anon flows only. Ergoport echoes it back in the postMessage. Never stored against a user.
Email hash format
Ergoport requires a specific hash format: SHA256(lowercase(trim(email))). Do not send the raw email. Do not use a different hashing algorithm or your users will not be matched.

PostMessage Events

The widget communicates exclusively via window.postMessage. Always validate the origin before processing.

event: "verified"

Fired when a user successfully completes verification. This is the primary event you handle.

event "verified"
verified true or false
human_verified true or false
app_confirmed true or false
method "totp_app" | "session_code_app" | "session_code_mweb" | "email_otp"
expires_at unix_timestamp (returning/anon flows only)
session_id "your_session_id" (anon flows only, echoed)

HEAA Flow

HEAA App only. User enters a TOTP code from the Ergoport app. Highest assurance level. Required for UK Online Safety Act primary priority content.

1
Widget loads, reads API key
Detects HEAA:true from your API key configuration. Renders app-only mode. No mweb path is offered.
2
Widget displays TOTP entry box
User opens their Ergoport app and reads their rotating 6-digit TOTP code. Enters it in the widget.
3
Ergoport validates TOTP against email hash
Confirms the user is age-verified. Consent timestamp established on first verification.
4
postMessage fired to your platform
verified: true, app_confirmed: true, human_verified: true, method: "totp_app"

Non-HEAA Flow

Standard Three verification paths. User chooses based on what they have available. Platform decides which signals it accepts.

Path How app_confirmed method
Ergoport app Enter session code in app true session_code_app
ergoport.com/verify Log in on mweb, enter code false session_code_mweb
Email OTP OTP sent to email on file false email_otp
Email OTP requires data-email-hash
The email OTP path is only shown when you pass data-email-hash. Without it, the widget shows session code paths only. No email OTP option is shown for anon flows.

Anon Flow

Triggered when no data-email-hash is passed. No identity claimed. Returns human_verified: true only. Both HEAA and Non-HEAA platforms can use this for bot detection / CAPTCHA replacement.

HTML — Anon / CAPTCHA replacement
<!-- No email hash — triggers anon flow -->
<script
  src="https://cdn.ergoport.com/widget.js"
  data-key="pk_live_YOUR_PLATFORM_KEY"
  data-session-id="your_internal_session_123"
></script>

// Response will include:
// { verified: false, human_verified: true,
//   session_id: "your_internal_session_123",
//   expires_at: 1234567890 }

Signal Reference

Flow verified human_verified app_confirmed method
HEAA — new user true true true totp_app
HEAA — returning true true true totp_app
HEAA — anon false true true session_code_app
Standard — app true true true session_code_app
Standard — mweb true true false session_code_mweb
Standard — email OTP true true false email_otp
Standard — anon (app) false true true session_code_app
Standard — anon (mweb) false true false session_code_mweb

Email Hash Standard

Ergoport uses a standardised lookup hash format. Your backend must produce this exactly or users will not be matched.

JavaScript
// Step 1: normalise
const normalized = email.toLowerCase().trim();

// Step 2: SHA-256 hash
const encoder = new TextEncoder();
const data = encoder.encode(normalized);
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const emailHash = hashArray
  .map(b => b.toString(16).padStart(2, "0"))
  .join("");

// Pass as data-email-hash

Security Notes

Requirement Detail
Validate postMessage origin Always check e.origin === "https://cdn.ergoport.com" before processing any message.
Never expose secret key Your sk_live_ key is for server-to-server calls only. Never include it in frontend code or the widget.
Session codes are single-use Each session code is invalidated immediately after successful verification. The same code cannot be reused.
Enforce expires_at server-side Ergoport issues tokens with expires_at. Your platform is responsible for enforcing expiry and re-surfacing the widget when needed.
No raw emails Never send raw email addresses to Ergoport. Pass SHA256(lowercase(trim(email))) only. Ergoport never stores raw emails.

Compliance Coverage

Jurisdiction Regulation Status
🇬🇧 United Kingdom Online Safety Act — HEAA Live — Lewis Silkin opinion
🇮🇹 Italy AGCOM Caivano Decree — Double Anonymity AGCOM certification in progress
🇺🇸 Texas + 23 states HB 1181 and mirror state laws US counsel opinion in progress
🇪🇺 European Union DSA Article 28 + eIDAS 2.0 EU relying party — 2027
One integration, growing coverage
As Ergoport adds jurisdictions, your compliance coverage grows automatically. No additional integration work required on your side.