Reward Hand-off — RheumaView Interactive Modules
RheumaView · Reward Hand-off

One signal at completion.
Your platform grants the reward.

Every RheumaView interactive module ends the same way: when a player finishes, the module hands a compact completion signal — score, points, achievements, tier — to the page hosting it. Your platform or the sponsor’s redemption page reads that signal and decides what to grant. The mechanism is identical across the entire portfolio.

The flow

How the reward hand-off works

Three steps, fully client-to-client. The module never touches your fulfilment system — it emits a signal; your side does the crediting.

Completion → Signal → Reward

Continuous loop shown for illustration · one real hand-off fires per attempt

1 · Player completes
module finished
Interactive module
Crucible · Cascade · Simulators — hosted in an iframe
score 71% · pts 587
tier C · 🏅 4
2 · Signal received
Your platform / sponsor page
Reads the signal, identifies the player, applies reward logic
grant decision
3 · Reward granted
🎁
Player rewarded
CME creditGift cardPlatform points Gated contentFree trial

Watch the full walkthrough

Part A · points accumulate  →  Part B · hand-off to the sponsor

One mechanism, every product

The same hand-off powers the whole portfolio

You integrate once. The completion signal is structurally identical whether the player just finished a Crucible diagnostic case, a Cascade therapeutic-education module, a RheumaView Simulator, or any future interactive module we ship. Tap any product to view it live.

Everything is customized. Each build is tailored per buyer, sponsor, and platform — branding tier, palette, signal channel, reward label, score threshold, pre-quiz gate, redemption URL, passed parameters, allowed origins, and the on-page copy are all configured to your agreement before delivery. Nothing here is one-size-fits-all.
Integration & reference

The technical detail, when you need it

Expand any section below. Everything here is configured per build — the snippets show the shape of the contract, not fixed values.

BoundariesWhat the hand-off is — and is not

In short: the module is the source of a signal, not a fulfilment engine. Identity, rate-limiting, anti-abuse, tax/compliance reporting, and ledger integrity all live on your side.

The module does

  • Emit a one-time completion signal with the score and effort metrics
  • Signal reward-eligibility when a configured threshold is met
  • Pass through an opaque reward label or score parameters you defined at build time
  • Include calibration / timing / achievement summaries when those features are enabled

The module does not

  • Identify the player (no user ID, no email, no session)
  • Call your API, webhook, or fulfilment endpoint
  • Issue, track, deduplicate, or report rewards
  • Validate the score server-side or prevent client-side tampering
The signalTwo ways the signal reaches you

Depending on the module and your setup, the completion signal arrives by one or both of these channels. Both carry the same result data.

A · postMessage event (iframe → your page)

The module sends a window.parent.postMessage(...) when the player finishes. Fires once per attempt; a fresh attempt fires again with new values.

// completion — fires on success and on the fail screen
{
  type:         "module:case-complete",
  caseId:       "CSC-001",
  product:      "crucible" | "cascade" | "simulator",
  tier:         "A" | "B" | "C",
  success:      true,        // false on fail screen
  score:        52,
  maxScore:     60,
  percent:      71,
  points:       587,
  streakMax:    5,
  achievements: 4,
  timestamp:    1730000000000
}

A second module:reward-eligible event fires immediately after, in the same tick, only when reward trigger is enabled, the attempt succeeded, and the threshold was met. It carries an opaque rewardLabel you map back to your reward catalog.

B · URL parameters (module → sponsor redemption page)

Used by Cascade-style reward redemption: the player clicks “Claim my reward” and the module opens the sponsor’s page with the result appended as query parameters. The sponsor’s page reads them and decides what to grant.

https://sponsor.example.com/reward/?caseId=CSC-001&drugName=TYK2i-DEMO
   &points=587&percent=71&streakMax=5
   &achievements=4&tier=C&totalAttempts=12
Consolation path. Even players who do not pass can be allowed to redeem at a reduced tier — the receiving page decides the minimum reward. Every completer produces a commercial signal, not just passers.
IntegrationListener template

Paste this on the page where you embed the module. One listener handles every product.

<iframe id="rv-module"
  src="https://www.rheumaview.com/m/CSC-001/"
  width="900" height="940"
  style="border:0;max-width:100%;" loading="lazy"></iframe>

<script>
window.addEventListener("message", (e) => {
  // 1 · origin check — required
  if (e.origin !== "https://www.rheumaview.com") return;
  if (!e.data || typeof e.data !== "object") return;

  // 2 · reward-eligible — credit the player using YOUR session
  if (e.data.type === "module:reward-eligible") {
    fetch("/api/rv/credit", {
      method: "POST", credentials: "include",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        caseId: e.data.caseId, score: e.data.score,
        rewardLabel: e.data.rewardLabel
      })
    });
    return;
  }

  // 3 · case-complete — analytics, completion tracking, leaderboards
  if (e.data.type === "module:case-complete") {
    yourAnalytics.track("rv_complete", e.data);
  }
});
</script>
Always check e.origin. Without it, any other page could spoof an event. The origin is always https://www.rheumaview.com.
Who is the playerIdentifying the player on your side

The module has no idea who the player is. You do.

Pattern A — your own session (recommended)

Your page already requires login, so when your listener runs, the browser carries your authenticated session. Your credit endpoint reads it, looks up the user, and credits them. The module never participates in identity.

Pattern B — echo a token through the module

If your session cookie is not available in the module’s context, generate a short-lived opaque token, pass it via the URL (?uid=opaque_token), and the module echoes it back as echoToken in the payload. Your endpoint maps the token to the user.

Trust modelAnti-tampering and reward classes
Read before enabling rewards above the small-coupon tier. Scoring runs client-side. A determined player using DevTools can manipulate state before the signal fires. The module cannot prevent this — acceptable for low-value rewards, not for high-value ones.
Reward typeSignal alone OK?Server-side validation
Internal platform points / XPYesNo
Badges, progress, leaderboardsYesNo
Coupons / discount codes < $5Yes (rate-limit)Recommended
Gift cards ≥ $5NoRequired
CME creditNoRequired + audit log
Cash honorariaNoRequired + KYC

For high-value rewards your fulfilment endpoint must: require an authenticated session; be idempotent on (userId, caseId); rate-limit per user per window; and log every attempt, accepted or rejected, for audit.

ResponsibilitiesCompliance is the buyer’s surface

The module emits a technical signal and collects no PII. The completion and reward-eligible payloads contain no user-identifying fields. Linking a real person to an attempt happens entirely on your platform, under your privacy notice and legal basis.

RegimeBuyer responsibility
PhRMA Code (US)Determine HCP status; apply gift / educational-item rules.
Sunshine Act (US)Report transfers of value above threshold to the registry.
1099 reporting (US)Aggregate per-recipient annual payments > $600/year.
ACCME independenceSeparate reward issuance from the accreditation pathway.
GDPR / UK GDPRLawful basis & privacy notice for storing “X completed Y”.
Local tax on gift cardsApply local rules (EU, US state-level, etc.).
Before go-liveHow to test
  1. Embed the module on a staging page and open the DevTools console.
  2. Add the listener with extra console.log() calls.
  3. Pass the module to a clearing score — confirm case-complete (success:true) then reward-eligible with the expected label.
  4. Re-run below threshold — case-complete fires, reward-eligible does not.
  5. Trigger the fail screen — case-complete fires with success:false; no eligibility.
  6. Curl your credit endpoint with no session — confirm it rejects the request.
  7. Hit it twice with the same (userId, caseId) — confirm the duplicate is rejected.
Authored by Olga Goodman, MD · www.rheumaview.com
RheumaView Reward Hand-off · works across Crucible, Cascade, RheumaView Simulators, and all other interactive modules.
For onboarding, allowed-origin updates, sandbox embeds, or echo-token enablement — contact us.

All product, drug, sponsor, and trial names shown in code samples are fictional placeholders for demonstration. The module is the source of a reward-eligibility signal; anti-abuse, identity verification, fulfilment, tax, and compliance reporting are the buyer’s responsibility.